Ждите ключа в сценарии оболочки, который может быть отправлен в / bin / bash

Рассмотрим следующий сценарий оболочки

echo foo; read; echo bar 

Запуск bash my_script выводит «foo», ждет ключа возврата и выводит «бар».

В то время как это работает отлично работает так, это не работает больше, если отправлено в / bin / bash:

 $ echo 'echo foo;read;echo bar'|bash 

напрямую выводит «foo» и «bar», не дожидаясь нажатия клавиши.

Почему больше не читать работу при ее использовании таким образом?

Есть ли способ переписать сценарий таким образом, что он работает как файл сценария файла, а также строка сценария, передаваемая в / bin / bash?

3 Solutions collect form web for “Ждите ключа в сценарии оболочки, который может быть отправлен в / bin / bash”

На самом деле это действительно просто. Во-первых, вам нужно отложить свой stdin в каком-то запоминаемом дескрипторе:

 exec 9<&0 

Там. Вы сделали копию. Теперь давайте перетаскиваем наши команды в нашу оболочку.

 echo 'echo foo; read <&9; echo bar' | bash 

… ну, это было легко. Конечно, мы еще не сделали. Мы должны очистить.

 exec 9<&- 

Хорошо, теперь все готово.

Но мы можем избежать очистки, если мы просто немного сгруппируем наши команды …

 { echo 'echo foo; read <&9; echo bar' | bash; } 9<&0 

Дескриптор сохраняется только до тех пор, пока его назначенная составная команда делает в этом случае.

Встроенное read bash читается из stdin (fd0), но не может открыть stdin, поскольку команда bash уже потребляет stdin.

Вы можете eval что вы

 eval 'echo foo;read;echo bar' 

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

Я никогда не получал его, как дублировать дескриптор файла stdin. См. Ответы на майки.

Кстати. Вы можете видеть, что происходит с чтением с помощью

 echo 'echo foo;read;echo bar'|strace bash 

Ответ ikrabbe правильно определяет, почему ваша командная строка работает не так, как вы ожидаете. Обычный способ вызова новой оболочки для одной командной строки:

 $ sh -c 'echo foo; read; echo bar' 

Конечно, вы можете использовать bash если вам нужно, но 98% того, что вы можете сделать в однострочном сценарии оболочки, можно сделать в простой старой оболочке. (Не обращайте внимания на то, что «простая старая оболочка» образует аббревиатуру «POS».)

Если ваша цель – заставить ваш однострочный сценарий оболочки приостановиться, ожидая ввода пользователя (возможно, просто подтверждения / подтверждения), то это, вероятно, то, что вы должны делать. Если ваша цель – лучше понять работу оболочки, попробуйте следующее:

  $ (echo 'echo foo; read; echo "$ REPLY bar"', echo candy) |  ш
 Foo
 конфеты (без ожидания)
 $ 
  • Unix без / dev / stdin, / dev / stdout и / dev / stderr?
  • Выведенный процесс не читается с stdin
  • Как я могу обойти программу с ошибкой, если есть * любой * stdin?
  • Сценарий Ed работает только в том случае, если набирается медленно
  • Каковы некоторые практические применения перенаправления STDIN?
  • Как заставить программы python вести себя как соответствующие инструменты unix?
  • Необходимо перенаправить ввод из файла, а также из tty
  • nohup: игнорирование ввода и перенаправление stderr в stdout
  • Является ли Bluetooth-клавиатура связанной с `stdin`?
  • Может ли оболочка предупредить меня, если программа ждет стандартного ввода?
  • vimdiff для сравнения вывода вместо файлов
  • Linux и Unix - лучшая ОС в мире.