Как я могу использовать значение из трубы в тестовой программе?

wc -l | test -eq 1

Это не работает. Я хочу сравнить результат wc со значением 1. Как я могу это сделать?

10
задан 15 August 2013 в 18:38

4 ответа

Он не отвечает на ваш вопрос о каналах, но вы можете переставить:

test $(ls -l | wc -l) -eq 1 && echo "worked"

И есть несколько решений по SO , это самое хорошее:

[ 111]
0
ответ дан 15 August 2013 в 18:38

При использовании Bash Вы, вероятно, хотите исследовать переменную PIPESTATUS. Как отмечено в справочнике Bash, PIPESTATUS

Переменная типа массив (см. Массивы), содержащий список значений статуса выхода от процессов в последний раз выполняемом приоритетном конвейере (который может содержать только единственную команду).

Мы можем узнать то, чем коды выхода были для этого конвейера с PIPESTATUS:

dmesg | grep -iw 'nnse' | wc -l

Если Вы теперь запрашиваете переменную типа массив, Вы получаете статусы выхода, относящиеся к командам, используемым в конвейере:

echo ${PIPESTATUS[@]}
0 1 0

(В индексном массиве те коды выхода выше представлены 0 1 и 2 в массиве, поскольку массивы всегда запускаются в 0 в Bash.)

Здесь мы видим, что вторая команда возвратилась 1, и остальные 0; однако, wc -l возвраты 0, если существуют нулевые соответствия, который не является ошибкой. Отказ представлен с ненулевым значением, и существуют другие ошибочные значения такой как 127, который является командой, не найденной, и все же больше кодов, которые могут быть характерны для затронутой программы.

Если Вы хотите видеть, каков код выхода конкретной команды в конвейере был, можно просто получить доступ к тому значению. Команда grep была второй командой в конвейере выше, но поскольку массивы запускаются от 0, нам нужна запись один.

Таким образом для обнаружения кода выхода grep команды выполните вышеупомянутый конвейер снова (поскольку содержание PIPESTATUS будет исчерпано, если Вы работали echo ${PIPESTATUS[@]}) и затем выполните команду ниже, которая возвратится 1 (код выхода):

echo ${PIPESTATUS[1]}
1

В сценарии удостоверьтесь, что конвейер закончил выполняться перед поиском содержания переменной типа массив PIPESTATUS.

Для примера интересного использования переменной типа массив PIPESTATUS см., что этот ответ расценивает объединяющуюся группировку команды Bash, и передайте состояние по каналу. Вы могли протестировать переменную типа массив в пути, предложенном Gilles в комментариях, хотя необходимо будет сначала выполнить конвейер снова:

dmesg | grep -iw 'nnse' | wc -l
[ ${PIPESTATUS[1]} -eq 1 ] && do_something_here

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

4
ответ дан 15 August 2013 в 18:38

Это не охватывает каждый test случай, но если вы можете использовать регулярное выражение и grep конвейерную строку, это довольно просто, потому что grep подобен test в том смысле, что имеет ненулевой выход, если совпадения не найдено

cat file | wc -l | grep -qE '^\s*1\s* 

Расширенные регулярные выражения позволяют вам охватить многие случаи с помощью этой техники. Для хихиканья, контрольный пример:

for i in 1 11 '' foo; do 
  if echo $i | grep -qE '^\s*1\s* 

выводит:

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.
; then echo "'$i' matched" else echo "'$i' didn't match." fi done

выводит:

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.

Расширенные регулярные выражения позволяют вам охватить многие случаи с помощью этой техники. Для хихиканья, контрольный пример:

for i in 1 11 '' foo; do 
  if echo $i | grep -qE '^\s*1\s* 

выводит:

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.
; then echo "'$i' matched" else echo "'$i' didn't match." fi done

выводит:

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.
0
ответ дан 15 August 2013 в 18:38

Самый простой путь состоит в том, чтобы, вероятно, использовать xargs:

wc -l | xargs -I % test % -eq 1
1
ответ дан 10 October 2019 в 14:06

Другие вопросы по тегам:

Похожие вопросы: