遇到shell重定向的一個奇怪問題:'消失'的標準輸入!

需求:
把找到的文件逐行輸出,而後用rm在許可的狀況下刪除
 
前置準備: 
$ls
rm.sh test1 test2 test3 test4 test5 test6
$cat rm.sh
#! /bin/bash
while read fileinfo
do 
    rm -iv $fileinfo
done< <( find . -name 'test*' -print )

第一次執行結果:shell

$bash rm.sh

rm:是否刪除普通文件「./test2」?

出現的問題:bash

雖然rm顯示了詢問信息,卻並不關心我輸入的是什麼(就沒給我機會),也沒有刪除文件spa

第一次結果分析:
rm -iv須要從標準輸入中獲取容許,但標準輸入已經被重定向爲’done< <( find $path -type f -print )‘,因此rm只能從這獲取輸入了,也形成了這一次執行的令就無效了,而後read和rm就不斷地逐次消耗掉輸入的行,也就什麼都沒作了;
 
 第二次前置準備
$ls
rm2.sh test1 test2
$cat test1
test1
test2
test3
test4
test5
test6
 程序解釋:
當每次read到的內容不爲空就輸出到屏幕,count統計的是嘗試的刪除次數
$cat rm2.sh
#! /bin/bash
count=0
while read info
do
    if [ ! -z info ]
        then echo $info:not null
    fi
    rm -iv test2
    let count++
    echo $count
done< test1

第二次執行結果:code

 

$bash rm2.sh
test1:not_null
rm:是否刪除普通文件 「test2」?1
test3:not_null
rm:是否刪除普通文件 「test2」?2
test5:not_null
rm:是否刪除普通文件 「test2」?3
驗證分析:
符合第一次結果分析的猜想;
解決方案:
將原標準輸入(鍵盤輸入)存放在新的文件描述符中,並在rm中將新的文件描述符做爲它的輸入
修正後的程序:
$cat rm3.sh
#! /bin/bash
exec 3<&0
while read fileinfo
do 
    rm -iv $fileinfo <&3
done< <( find . -type f -print )
 
 
順帶一提:
'done< <( find . -type f -print )'有兩個‘<’的緣由:
第一步:‘<( find . -type f -print )’至關於將子shell中的結果輸出到一個臨時文件
第二步:‘done< temp_file’從臨時文件中獲取輸入
相關文章
相關標籤/搜索