Во-первых, ваш пример false | echo ok
не имеет смысла, поскольку false
ничего не выводит на свой стандартный вывод, а echo
не читает со своего стандартного ввода. «Решение» этого false && echo ok
.
cmd1 && cmd2
Это запустит cmd1
и не запустит cmd2
, пока cmd1
не завершит успешное выполнение.
В конвейере, таком как
cmd1 | cmd2
две команды всегда запускаются одновременно (это то, что вы заметили в своем «Неудачное решение 1» ). Их синхронизирует чтение cmd2
из вывода cmd1
. Конвейер — это способ передачи вывода одной программы во ввод другой, параллельно работающей программы.
Чтобы имитировать, что cmd1
выводит что-то, что читает cmd2
, но чтобы избавиться от параллелизма, вам нужно сохранить вывод из cmd1
во временный файл, который cmd2
читает:
cmd1 >outfile && cmd2
Временный файл может обрабатываться следующим образом:
trap 'rm -f "$tmpfile"' EXIT
tmpfile=$(mktemp)
cmd1 >"$tmpfile" && cmd2 <"$tmpfile"
Это устанавливает ловушку, которая срабатывает при выходе из оболочки. Ловушка удалит временный файл.
Если у вас есть $TMPDIR
в файловой системе памяти, вы не понесете никаких штрафов за ввод-вывод за запись на диск.
Если вас беспокоит размер файла, то вы будете вынуждены хранить его на диске во что бы то ни стало (канал также не сможет удерживать содержимое, это то, что вы заметили в своем " Неудачное решение 3" ).
Глядя на решение xhienne для Bash:
result=$(cmd1) && cmd2 <<< "$result"
unset result
Это работает, если результатом является текст, который не заканчивается пустыми строками, но не работает, если он содержит нулевые байты (они будут отброшеныbash
).
Чтобы смягчить это, мы могли бы base64 -закодировать результат:
set -o pipefail # ksh/zsh/bash
result=$( cmd1 | base64 ) && base64 -d <<<"$result" | cmd2
unset result
Это ужасная идея с точки зрения использования памяти и процессора.особенно если результат большой (, кодировка base64 $result
будет на треть больше, чем двоичная ). Гораздо лучше записать двоичный результат на диск и прочитать его оттуда.
Также обратите внимание, что bash
реализует <<<
с использованием временного файла в любом случае.