Использование файла ввода в качестве стандартного ввода для сценария оболочки не работает
У меня есть следующий код скрипта:
test.sh
echo "BEGIN"
while read CMD <&1; do
[ -z "$CMD" ] && continue
case "$CMD" in
start)
echo "get_start"
;;
stop)
echo "get_stop"
;;
*)
echo "get_uknown_command"
;;
esac
echo "END";
done
Когда я запускаю его с:
$./test.sh <input.txt
Я заблокировал свой сценарий
input.txt
start
stop
sthh
Почему мой скрипт заблокирован? Как я могу это исправить?
Кстати: если я введу данные вручную, сценарий не будет заблокирован.
2 ответа
Вы используете неправильный файловый дескриптор. 1
это стандартный вывод, 0
это стандартный
Изменить:
while read CMD <&1; do
чтобы:
while read CMD <&0; do
И это будет из файла правильно. Тем не менее, вам не нужно делать это все, так как read
по умолчанию используется stdin:
while read CMD; do
Так же -u
опция может быть использована для чтения из определенного файлового дескриптора (по крайней мере, в bash). Таким образом, вы могли бы сделать это также:
while read -u 0 CMD; do
Файловый дескриптор 1
является stdout
или стандартный вывод. Это означает, что вы перенаправляете read
вход для стандартного вывода. Это явно не будет работать очень хорошо; почти наверняка никогда не будет никакого ввода, ожидающего на стандартном выходе для read
,
Стандартный ввод - дескриптор файла 0
так что если вы измените <&1
в <&0
on line 2 of your script, it works. Or simply drop that part entirely; read
reads from standard input by default (that's pretty much its purpose), so there's no need to explicitly tell it to read from standard input.
If you want to read some particular input interactively and allow the remainder to be redirected from a file (or come through a pipe), you can do read </dev/tty
,
And you don't need the semicolon statement separator after the END echo; the newline does just fine.