2016-09-30 5 views
0

У меня есть этот пример сценария:Shell POSIX два вложенным во время чтения и чтения из стандартного ввода не работает

#!/bin/sh 
while read ll </dev/fd/4; do 
    echo "1 "$ll 

    while read line; do 
      echo $line 
      read input </dev/fd/3 
      echo "$input" 
    done 3<&0 <notify-finished 

done 4<output_file 

В настоящее время Первый цикл не итерацию просто остается на линии 1. Как это исправить без bashisms потому, что он должен быть очень переносимым. Благодарю.

+1

'/ dev/fd' является либо лимузием, либо бахизмом (bash эмулирует его на не-Linux-операционных системах, но не все оболочки), поэтому вы уже неперекрываетесь. Используйте '<& 4', а не'

+0

Пожалуйста, расширьте свой код, чтобы быть MCVE, создавая 'output_file' и' notify-finished', поэтому он будет работать таким образом, чтобы он успешно демонстрировал вашу ошибку без человека, который хочет увидеть вашу проблему, которая должна что-то сделать. –

+0

@CharlesDuffy Оказалось, что это была нотация '

ответ

3

Ваш код уже имеет багизмы. Вот, я беру их (и упрощая обработку FD для лучшей читаемости):

#!/bin/sh 
while read ll <&4; do   # read from output_file 
    printf '%s\n' "1 $ll" 

    while read line <&3; do  # read from notify-finished 
      printf '%s\n' "$line" 
      read input    # read from stdin 
      printf '%s\n' "$input" 
    done 3<notify-finished 

done 4<output_file 

Выполнить скрипт следующим образом:

echo "output_file" >output_file 
echo "notify-finished" >notify-finished 
echo "stdout" | ./yourscript 

... и это правильно выходит со следующим выходом :

1 output_file 
notify-finished 
stdout 

Примечания:

  • echo Поведение на рынке POSIX небезопасно. См. Раздел ПРИМЕНЕНИЕ ИСПОЛЬЗОВАНИЯ the POSIX spec for echo, который рекомендует вместо этого использовать printf.
  • /dev/fd/## не указан POSIX; это расширение, доступное как дистрибутивами Linux (создание символической ссылки на /proc/self/fd - /proc, являющееся самим неопределенным расширением), так и самим bash. Используйте <&4 вместо </dev/fd/4.
  • You вероятно хотите использовать -r аргумент read - который является POSIX-указания, и предотвращает поведение по умолчанию обработки обратной косой черты, как управляющие последовательности для переноса строк и символов в МФС. Без него foo\bar читается как foobar, таким образом, не считывая ваши данные, поскольку он действительно существует в его источниках ввода.
Смежные вопросы