2014-02-12 75 views
0

還有其他線程使用同一主題,但我的問題是唯一的。我正在運行一個bash腳本,該腳本具有一個連接到遠程服務器並在遠程服務器上運行sudo命令的功能。我正在使用ssh -t選項來避免requiretty問題。只要沒有在while循環中調用代碼,違規代碼行就可以正常工作。 while循環基本上都是從本地服務器上的CSV文件中讀取並調用checkAuthType功能:僞終端錯誤將不會分配,因爲stdin不是終端 - sudo

while read inputline 
do 
    ARRAY=(`echo $inputline | tr ',' ' '`) 
    HOSTNAME=${ARRAY[0]} 
    OS_TYPE=${ARRAY[1]} 
    checkAuthType $HOSTNAME $OS_TYPE 
    <more irrelevant code> 
done < configfile.csv 

這是在腳本的頂部位於(以外的任何while循環)功能:

function checkAuthType() 
{ 
    if [ $2 == linux ]; then 
     LINE=`ssh -t $1 'sudo grep "PasswordAuthentication" /etc/ssh/sshd_config | grep -v "yes\|Yes\|#"'` 
    fi 

    if [ $2 == unix ]; then 
     LINE=`ssh -n $1 'grep "PasswordAuthentication" /usr/local/etc/sshd_config | grep -v "yes\|Yes\|#"'` 
    fi 
    <more irrelevant code> 
} 

因此,有問題的行是在函數中具有sudo命令的行。我可以將命令更改爲「sudo ls -l」之類的簡單命令,而且我仍然會看到「stdin不是終端」錯誤。我也嘗試過「ssh -t -t」,但無濟於事。但是如果我從while循環之外調用checkAuthType函數,它可以正常工作。什麼是while循環改變終端,我該如何解決它?提前一千多次感謝你。

回答

1

另一種選擇,試圖得到解決該問題將重定向將文件轉換爲不同的文件描述符,並強制從中讀取。

while read inputline <&3 
do 
    ARRAY=(`echo $inputline | tr ',' ' '`) 
    HOSTNAME=${ARRAY[0]} 
    OS_TYPE=${ARRAY[1]} 
    checkAuthType $HOSTNAME $OS_TYPE 
    <more irrelevant code> 
done 3< configfile.csv 
+0

這是解決方案!我將嘗試將csv文件讀入一個變量,而不是逐行讀取它,然後使用for循環遍歷數組值。不知道這是否會奏效,但這個解決方案要簡單得多。非常感謝! – Isaac

0

我猜你正在用linux進行測試。您應該嘗試將-n標誌添加到您的(linux)ssh命令中,以避免從標準輸入讀取ssh - 因爲它通常從標準輸入中讀取while循環爲您提供的csv。

UPDATE

你應該(通常)使用而當使用-n標誌時,通常需要對「預期的行爲」腳本與SSH和標記讀取 -loop。不過,這似乎並不是主要問題。 有可能是這個其他的解決方案,但你可以嘗試添加另一個-t標誌標準輸入時強制僞終端分配不是終端:

ssh -n -t -t 
+0

感謝您的回覆。我爲Linux ssh命令嘗試了「ssh -n -t」以及「ssh -t -n」,但是我得到了同樣的錯誤。 – Isaac

+0

@Isaac我懷疑這個,但你覺得你可以放棄它。看到我更新的答案! :) – bryn

+0

試過了。它不適合我的情況。 BroSlow的解決方案雖然工作。 – Isaac

0

BroSlow用不同的文件描述符的方法似乎工作!由於read命令從fd 3讀取而不是stdin,因此 和ssh,因此sudo仍然具有或獲得tty/pty作爲標準輸入。

# simple test case 
while read line <&3; do 
    sudo -k 
    echo "$line" 
    ssh -t localhost 'sudo ls -ld /' 
done 3<&- 3< <(echo 1; sleep 3; echo 2; sleep 3)