ошибка псевдотерминала не будет выделена, потому что стандартный ввод не является терминалом - sudo

Есть и другие темы с такой же темой, но моя проблема уникальна. Я запускаю сценарий bash, в котором есть функция, которая подключается к удаленному серверу по sshes и запускает команду sudo на удаленном сервере. Я использую опцию ssh -t, чтобы избежать проблемы с требованием. Ошибочная строка кода работает нормально, пока она НЕ вызывается из цикла 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 is not a terminal». Я также пробовал "ssh -t -t", но безрезультатно. Но если я вызываю функцию checkAuthType вне цикла while, она работает нормально. Что такого в цикле while, который изменяет терминал и как его исправить? Заранее спасибо тысячу раз.


person Isaac    schedule 12.02.2014    source источник


Ответы (3)


Другим вариантом решения проблемы может быть перенаправление файла на другой файловый дескриптор и принудительное 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
person Reinstate Monica Please    schedule 12.02.2014
comment
Это решение! Я собирался попытаться прочитать CSV-файл в переменную вместо того, чтобы читать его построчно, а затем использовать цикл for для перебора значений массива. Не уверен, что это сработает, но это решение намного проще. Большое спасибо! - person Isaac; 18.02.2014

Я предполагаю, что вы тестируете Linux. Вам следует попробовать добавить флаг -n к вашей (linux) команде ssh, чтобы избежать чтения ssh из stdin - поскольку он обычно читается из stdin, цикл while передает ему ваш csv.

ОБНОВЛЕНИЕ

Вы должны (обычно) использовать флаг -n при написании сценариев с помощью SSH, и этот флаг обычно требуется для «ожидаемого поведения» при использовании цикла while read. Хотя, похоже, это не главная проблема. Вероятно, есть и другие решения для этого, но вы можете попробовать добавить еще один флаг -t, чтобы принудительно выделить псевдотерминал, когда стандартный ввод не является терминалом:

ssh -n -t -t
person bryn    schedule 12.02.2014
comment
Спасибо за ответ. Я пробовал ssh -n -t, а также ssh -t -n для команды Linux ssh, но получаю ту же ошибку. - person Isaac; 12.02.2014
comment
@ Исаак Я подозревал это, но подумал, что ты можешь попробовать. Смотрите мой обновленный ответ! :) - person bryn; 12.02.2014
comment
Пробовал. Это не сработало для моей ситуации. Однако решение BroSlow сработало. - person Isaac; 18.02.2014
comment
@Исаак Отлично! Я попробовал это с помощью простой команды «sudo ls» (которая сработала), но это не очень хорошее решение — решение Брослоу требует немного больше сантехники, но оно более подходящее и, по-видимому, также более безопасное :) - person bryn; 18.02.2014

Подход BroSlow с другим файловым дескриптором работает! Поскольку команда read читает из fd 3, а не из стандартного ввода, 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)
person trofx    schedule 12.02.2014