将不会分配伪终端错误,因为stdin不是终端 - sudo

时间:2014-02-12 00:34:35

标签: linux bash ssh scripting sudo

还有其他主题同一主题,但我的问题是独一无二的。我正在运行一个bash脚本,该脚本具有与远程服务器相关的功能,并在远程服务器上运行sudo命令。我正在使用ssh -t选项来避免requiretty问题。只要不在while循环中调用代码,违规行代码就可以正常工作。 while循环基本上从本地服务器上的csv文件读取并调用checkAuthType函数:

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循环以及如何修复它?提前一千谢谢你。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我猜你正在测试linux。您应该尝试将-n标志添加到您的(linux)ssh命令中以避免从stdin读取ssh - 因为它通常从stdin读取while循环正在向它提供您的csv。

<强>更新

在使用SSH编写脚本时,您应该(通常)使用-n标志,并且在读取 -loop时使用时,“预期行为”通常需要该标志。不过,这似乎不是主要问题。 可能还有其他解决方案,但是当stdin不是终端时,你可以尝试添加另一个-t标志来强制伪tty分配:

ssh -n -t -t

答案 2 :(得分:0)

BroSlow使用不同文件描述符的方法似乎有效!由于read命令从fd 3读取而不是stdin, ssh因此sudo仍然拥有或获得tty / pty作为stdin。

# 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)