Предположим, у меня есть:
** EDIT TO HAVE CLOSER CORRESPONDENCE TO ACTUAL USAGE **
find ... -regex ... | head -n 1 | xargs -I {} zcat {} | head -n 1
# next, I do some other things
Теперь все работает правильно. Однако xargs -I {} zcat {}
команда выдает следующую ошибку:
xargs: zcat: terminated by signal 13
Что я могу проигнорировать для целей того, что я пытаюсь сделать. Однако, если я запущу код и передам его в less
, xargs: zcat: terminated by signal 13
оператор будет первой строкой. Это нежелательно. Есть ли способ подавить или перехватить это предупреждение/ошибку, которая не является ошибкой?
решение1
Ошибка возникает из-за zcat
получения PIPE
сигнала, отправленного ему. Это происходит, потому что во второй раз zcat
выполняется (и все остальные разы после этого, по одному разу для каждого файла, кроме первого), он пытается записать через канал в head
после head
выхода (из-за того, что он выполнил свою задачу вывода первой строки).
Вы можете избежать генерации этой конкретной ошибки, прочитав все данные, которые zcat
она производит. Вы можете сделать это либо
ls files/* | xargs -I {} zcat {} | { head -n 1; cat >/dev/null; }
или
ls files/* | xargs -I {} zcat {} | sed -n 1p
или
ls files/* | xargs -I {} zcat {} | awk 'NR == 1'
Или см.Ответ Эдуардо Трапанидля того, как простоигнорироватьОшибка.
Другой способ сделать это — распаковать только первый файл:
set -- files/*
zcat "$1" | head -n 1
Это не вызывает сигнал PIPE
, zcat
поскольку выполняется только один раз, а не для каждого файла в каталоге. Это имело бы дополнительное преимущество, поскольку справлялось бы с любым допустимым именем файла (например, именами со встроенными переносами строк).
решение2
Несмотря на то, что вы видите сообщение в первой строке, оно записывается не в стандартный вывод, а в стандартный поток ошибок.
Итак, это должно сработать:
ls files/* | xargs -I {} zcat {} 2>/dev/null | head -n 1
Он отбрасывает стандартный вывод ошибок (отправляет его в /dev/null)