2011-07-05 169 views
2

我有一個腳本逐行讀取文件,並根據它讀取的內容做一些事情。它所做的一件事是ssh到遠程服務器並獲取一些信息。由於某種原因,這完全超出了我的視野,這會停止從文件中讀取行。在Bash腳本中調用SSH的文件讀取

劇本基本上是(我剪了很多它簡化問題,所以如果它看起來像它並沒有真正做任何事情,不用擔心):

cat $csv | while read line; do 
    shopt -s nocasematch 
    for j in "${file_list[@]}"; do 
     found=0; 
     for i in $(ssh some_server "ls /some_path/${line:0:1}/${line:1:1}/$line*"); do 
     if [[ $i =~ .*$j$ ]]; then 
      echo "do something"; 
      found=1; 
      break; 
     fi; 
     done; 
     if [[ $found -ne 1 ]]; then 
     echo "don't have $j"; 
     fi; 
     if [[ $found -ne 1 && $j == '\.pdf' ]]; then 
     getPDF $line ${dest}; 
     fi; 
    done; 
    shopt -u nocasematch 
done 

這個腳本只能在csv的第一行上運行。如果我用其他任何東西替換腳本的「ssh」部分,它會一直在文件的所有行上運行。是什麼賦予了?

+2

是SSH吃你的標準輸入(在這裏,你的[無用的使用貓] (http://en.wikipedia.org/wiki/Cat_%28Unix%29#Useless_use_of_cat)是stdin)?嘗試ssh -n,看看會發生什麼...... – Useless

+1

我強烈建議你在逐行閱讀文件時總是使用'read -r',並且你可能希望'while IFS = $'\ n'read -r'如果空白對你很重要。 – Sorpigal

回答

9

ssh正在使用stdin。通過-n

+0

這樣做。謝謝!對於那些希望在將來想要更多解釋的人,請通過運行「man ssh」來查找-n選項。腳本的最終工作版本與上述相同,只是ssh部分讀取「ssh -n some_server ...」 – Eli

0

如果你運行它從標準輸入(例如,ssh)在循環中讀取命令,你需要確保之一:

  • 你的循環不會遍歷標準輸入
  • 你的命令有其標準輸入重定向:

前者:

while read -u 5 -r; do 
    ssh "$REPLY" ... 
done 5<file 

... WHI CH,使用bash 4.1或更高版本,可以自動文件描述符分配改寫成這樣:

while read -u "$file_fd" -r; do 
    ssh "$REPLY" ... 
done {file_fd}<file 

後者:

while read -r; do 
    ssh "$REPLY" ... </dev/null 
done <file