Как проверить коды возврата для процессов, передаваемых друг другу в оболочке пепла?

Вот команда, которая меня интересует:

dd if=/my/block/device | ssh myuser@otherserver "gzip > file.gz" 

Кроме того, я знаю, что это было решено для оболочки bash (то есть, с использованием массива PIPESTATUS), но я в своей среде использую оболочку пепла.

1 ответ1

1

Я вообще не знаю ash . Этот общий обходной путь должен работать даже в sh:

psf=/tmp/pipestatus
: > "$psf"   # to make the file empty
( dd if=/my/block/device; echo "1 $?" >> "$psf" ) \
| ( ssh myuser@otherserver "gzip > file.gz"; echo "2 $?" >> "$psf" )

Затем вы проверяете содержимое /tmp/pipestatus . Есть недостаток: условие гонки, два ( ) блока работают параллельно, они могут выводить в файл не в правильном порядке. Я использовал >> поэтому ни одно сообщение не перезапишет другое; "сообщения" короткие, поэтому они не должны чередоваться; я пронумеровал "сообщения", поэтому, даже если они не в порядке, вы можете получить правильный порядок позже ( sort , cut ).

Приведенный выше код является просто примером в любом случае. Более надежное решение использует mktemp для создания временных файлов, printf вместо echo . Чтобы полностью избавиться от состояния гонки, вам нужно записать в отдельные файлы:

psd="$(mktemp -d)"
# you may want to check if the above command succeeded

( dd if=/my/block/device; printf '%s\n' "$?" > "$psd/f1" ) \
| ( ssh myuser@otherserver "gzip > file.gz"; printf '%s\n' "$?" > "$psd/f2" )

# retrieve the results here, they are in "$psd/f1" and "$psd/f2"

rm -rf "$psd"
unset psd

Это не так хорошо, как PIPESTATUS Bash, потому что он опирается на некоторую файловую систему и возможность писать туда, мало что может пойти не так и не быть пойманным. Все еще лучше чем ничего.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .