При выполнении конвейера каждый разделенный от канала элемент выполняется в его собственном процессе. Переменные присвоения только вступают в силу в их собственном процессе. Под ksh и zsh, последний элемент конвейера выполняется в исходной оболочке; под другими оболочками, такими как удар, каждый конвейерный элемент выполняется в его собственной подоболочке, и исходная оболочка просто ожидает их всех для окончания.
$ bash -c 'GROUPSTATUS=foo; echo GROUPSTATUS is $GROUPSTATUS'
GROUPSTATUS is foo
$ bash -c 'GROUPSTATUS=foo | :; echo GROUPSTATUS is $GROUPSTATUS'
GROUPSTATUS is
В Вашем случае, так как Вы только заботитесь обо всем следовании команд, можно составить поток кода состояния.
{ tar -cf - my_folder 2>&1 1>&3 | grep -v "Removing leading" 1>&2;
! ((PIPESTATUS[0])); } 3>&1 |
gzip --rsyncable > my_file.tar.gz;
if ((PIPESTATUS[0] || PIPESTATUS[1])); then rm my_file.tar.gz; fi
Если Вы хотите вытащить больше чем 8 битов информации из левой стороны канала, можно записать в еще один дескриптор файла. Вот пример доказательства принципа:
{ { tar …; echo $? >&4; } | …; } | { gzip …; echo $? >&4; } \
4>&1 | ! grep -vxc '0'
После того как Вы получаете данные по стандартному выводу, можно подать его в переменную оболочки, использующую замену команды, т.е. $(…)
. Замена команды читает из стандартного вывода команды, поэтому если бы Вы также означали печатать вещи к стандартному выводу сценария, то они должны временно пройти другой дескриптор файла. Следующий отрывок использует fd 3 для вещей, которые в конечном счете переходят к stdout сценария и fd 4 для вещей, которые получены в $statuses
.
statuses=$({ { tar -v … >&3; echo tar $? >&4; } | …; } |
{ gzip …; echo gzip $? >&4; } 4>&1) 3>&1
Если необходимо получить вывод от различных команд в различные переменные, я думаю, что нет никакого прямого пути даже в “усовершенствованных” оболочках, таких как удар, ksh или zsh. Вот некоторые обходные решения:
Вы уже делаете его.
Ожидание команды для окончания является нормальным поведением оболочки. (Попытайтесь ввести sleep 5
при приглашении оболочки.) Единственное время, которого не происходит, - когда Вы добавляете &
к команде, или когда сама команда делает что-то к эффективно фону самому (последний является определенным упрощением).
Можно удалить wait %%
управляйте из своего сценария; это, вероятно, просто производит сообщение об ошибке как wait: %%: no such job
. (Вопрос: это на самом деле печатает такое сообщение?)
У Вас есть какое-либо доказательство что tar
команда не завершается перед /home/ftp.sh
команда запускается?
Кстати, это немного нечетно, чтобы иметь вещи кроме корневых каталогов пользователей непосредственно под /home
.
(Я знаю, что большая часть из этого была уже охвачена в комментариях, но я думал, что должен быть фактический ответ.)
Можно использовать:
wait $!
Удалите wait %%
из Вашего сценария.