Как сохранить скрипт от проглатывания всего стандартного ввода?

У меня есть сценарий, который читает из канала в цикле и запускает сценарий ожидания и обычный сценарий оболочки в цикле. Оба сценария запускают ssh на другом сервере, чтобы получить часть данных. Например:

cat /tmp/file |
while read a b c d
do
   s=`expect-script server1 $b`
   c=`ssh $b normal-script`
   echo $s $c
done

Несмотря на то, что в файле / tmp / file много строк, скрипт завершает работу после обработки первой строки. Я подозреваю, что ожидаемый сценарий поглощает весь стандартный ввод данных, поэтому, когда он возвращается, больше нечего читать. Как я могу избежать этого? Я не хочу, чтобы какие-либо скрипты, которые я вызываю, читали со стандартного сценария основного скрипта.

3 ответа

Это на самом деле ssh это хлюпает STDIN. Просто добавьте -n опция:

    c=$( ssh -n $b normal-script )

Если вы не хотите этого делать, вы можете иметь свою оболочку while чтение цикла из другого файлового дескриптора, оставляя stdin нетронутым:

while read -u3 a b c d
do
    s=$( expect-script server1 $b )
    c=$( ssh $b normal-script )
    echo $s $c
done 3< /tmp/file

(предполагается, что bash/ksh/zsh для read -u опция)

cat /tmp/file |
while read a b c d
do
    {
        s=`expect-script server1 $b`
        c=`ssh $b normal-script`
        echo $s $c
    } < /dev/null
done

{ command... } Синтаксис позволяет применять перенаправление или конвейерную обработку к последовательности команд.

Я также отмечу, что вам не нужно cat в вашем примере. Вы могли бы сделать это:

while read a b c d
do
    ...
done < /tmp/file

Кроме того, вообще говоря, если вы не хотите, чтобы какая-либо команда использовала текущий STDIN, вы предоставляете ей другой, используя<.

Например

         s=`expect-script server1 $b < /dev/null`

заставит "expect-script" прочитать STDIN из/dev/null(который просто возвращаетEOF) вместо того, чтобы потреблять текущий (из/tmp/file)

Вы также можете использовать|чтобы предоставить отдельный STDIN только для этой команды, например

         s=`cat /tmp/stdin_for_expect | expect-script server1 $b`
   c=`cat /tmp/stdin_for_ssh | ssh $b normal-script`
Другие вопросы по тегам