Все команды в конвейере запускаются практически одновременно. Их синхронизирует только ввод-вывод по каналу. Кроме того, канал может содержать столько информации, сколько позволяет буфер канала.
Таким образом, вы не можете избежать запуска одного этапа конвейера, потому что
Вместо этого запишите вывод в файл, дав конвейеру завершить работу. Затем используйте этот файл.
Пример (как функция с одним аргументом):
myman () {
tmpfile=$( mktemp )
if man -k "$1" | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf >"$tmpfile" && [ -s "$tmpfile" ]
then
zathura "$tmpfile"
fi
rm -f "$tmpfile"
}
Кроме того, программа zathura
не будет запускаться, если конвейер выйдет из строя, (часть xargs
вернет не -ноль )или сгенерированный файл будет пустым.
В оболочке bash
вы также можете установить параметр оболочки pipefail
с set -o pipefail
, чтобы конвейер возвращал статус выхода первой неудачной команды в конвейере. И вы хотели бы сделать переменную tmpfile
local
:
myman () {
local tmpfile=$( mktemp )
if [ -o pipefail ]; then
set -o pipefail
trap 'set +o pipefail' RETURN
fi
if man -k "$1" | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf >"$tmpfile"
then
zathura "$tmpfile"
fi
rm -f "$tmpfile"
}
Это устанавливает параметр pipefail
на время действия функции, если он еще не был установлен, а затем при необходимости снимает его. Он избавляется от теста -s
в выходном файле.