سؤال

There are other threads with this same topic but my issue is unique. I am running a bash script that has a function that sshes to a remote server and runs a sudo command on the remote server. I'm using the ssh -t option to avoid the requiretty issue. The offending line of code works fine as long as it's NOT being called from within the while loop. The while loop basically reads from a csv file on the local server and calls the checkAuthType function:

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

This is the function that sits at the top of the script (outside of any while loops):

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>
}

So, the offending line is the line that has the sudo command within the function. I can change the command to something simple like "sudo ls -l" and I will still get the "stdin is not a terminal" error. I've also tried "ssh -t -t" but to no avail. But if I call the checkAuthType function from outside of the while loop, it works fine. What is it about the while loop that changes the terminal and how do I fix it? Thank you one thousand times in advance.

هل كانت مفيدة؟

المحلول

Another option to try to get around the problem would be to redirect the file to a different file descriptor and force to read from it instead.

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

نصائح أخرى

I am guessing you are testing with linux. You should try add the -n flag to your (linux) ssh command to avoid having ssh read from stdin - as it normally reads from stdin the while loop is feeding it your csv.

UPDATE

You should (usually) use the -n flag when scripting with SSH, and the flag is typically needed for 'expected behavior' when using a while read-loop. It does not seem to be the main issue here, though. There are probably other solutions to this, but you could try adding another -t flag to force pseudo-tty allocation when stdin is not a terminal:

ssh -n -t -t

BroSlow's approach with a different file descriptor seems to work! Since the read command reads from fd 3 and not stdin, ssh and hence sudo still have or get a tty/pty as 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)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top