У меня есть следующий сценарий оболочки. Цель состоит в том, чтобы пройти через каждую строку целевого файла (путь которого является входным параметром скрипта) и выполнить работу с каждой строкой. Теперь, похоже, работает только с самой первой строкой в целевом файле и останавливается после обработки этой строки. Что-то не так с моим сценарием?
#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets
FILENAME=$1
count=0
echo "proceed with $FILENAME"
while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done < $FILENAME
echo "\ntotal $count targets"
В do_work.sh
, я запускаю пару ssh
команд.
bash
shell
ssh
while-loop
епископ
источник
источник
source
и просто выйти илиexec
. Но этот код не выглядит подлинным, OP заметит, что эхо требует-e
правильного отображения перевода строки ...do_work.sh
запуститьssh
любой шанс?do_work.sh
источник , а также работатьdo.sh
сset -x
отлаживать.Ответы:
Проблема в том, что
do_work.sh
запускаетssh
команды и по умолчаниюssh
читает из stdin, который является вашим входным файлом. В результате вы видите только обработанную первую строку, потому чтоssh
потребляет остальную часть файла, и ваш цикл while завершается.Чтобы предотвратить это, передайте
-n
своейssh
команде параметр, чтобы она читалась из/dev/null
стандартного ввода.источник
cat
. Можно подумать, что этого особенно опасаются грызуны.while read host ; do $host do_something ; done < /etc/hosts
избежал бы этого. Это спасает жизнь, спасибо!httpie
- это еще одна команда, которая по умолчанию читает STDIN и будет иметь такое же поведение при вызове внутри цикла bash или fish. Используйтеhttp --ignore-stdin
или установите стандартный ввод,/dev/null
как указано выше.В более общем плане обходной путь, который не является специфическим,
ssh
заключается в перенаправлении стандартного ввода для любой команды, которая в противном случае могла бы использоватьwhile
ввод цикла.</dev/null
Важнейшим моментом здесь является добавление (хотя исправленное цитирование также в некоторой степени важно; см. Также Когда заключать кавычки в переменную оболочки? ). Вы захотите использовать,read -r
если вам специально не требуется устаревшее немного странное поведение, без которого вы получаете-r
.Другой способ обхода, который несколько специфичен,
ssh
- убедиться, что у любойssh
команды есть привязанный стандартный ввод, например, путем изменениявместо этого читать команды из документа здесь, который удобно (для этого конкретного сценария) связывает стандартный ввод
ssh
для команд:источник
Параметр ssh -n предотвращает проверку статуса выхода ssh при использовании HEREdoc при передаче вывода в другую программу. Поэтому предпочтительнее использовать / dev / null в качестве stdin.
источник
<<EOF
Отменяет</dev/null
переназначение.<<
Перенаправление после того , какdone
это не так.Это происходит со мной , потому что я
set -e
иgrep
в петле возвращается без выхода (который дает ненулевой код ошибки).источник