Назад | Перейти на главную страницу

Как сделать так, чтобы скрипт не проглотил весь стандартный ввод?

У меня есть сценарий, который читает из канала в цикле и запускает сценарий ожидания и обычный сценарий оболочки в цикле. Оба сценария запускают 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 много строк, сценарий завершает работу после обработки первой строки. Я подозреваю, что ожидаемый скрипт проглатывает весь стандартный ввод, так что, когда он возвращается, читать нечего. Как мне этого избежать? Я не хочу, чтобы скрипты, которые я вызываю, читались со стандартного ввода основного скрипта.

Это на самом деле 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