还有其他主题同一主题,但我的问题是独一无二的。我正在运行一个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循环以及如何修复它?提前一千谢谢你。
答案 0 :(得分:1)
尝试解决问题的另一个选择是将文件重定向到不同的文件描述符,并强制read从中读取。
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)