wc -l | test -eq 1
Это не работает Я хочу сравнить результат wc со значением 1. Как я могу это сделать?
wc -l | test -eq 1
Это не работает Я хочу сравнить результат wc со значением 1. Как я могу это сделать?
Ответы:
Он не отвечает на ваш вопрос о каналах, но вы можете переставить:
test $(ls -l | wc -l) -eq 1 && echo "worked"
И есть несколько решений на SO , это самое хорошее:
ls -l | wc -l | { read wc; test $wc -eq 7 && echo "woohoo"; }
Если вы используете 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 и состояния канала . Вы можете проверить переменную массива способом, предложенным Жилем в комментариях, хотя сначала вам нужно будет снова запустить конвейер:
dmesg | grep -iw 'nnse' | wc -l
[ ${PIPESTATUS[1]} -eq 1 ] && do_something_here
Это всего лишь фрагмент, так как я не знаю, какой сценарий вы намереваетесь, но я надеюсь, что знание о PIPESTATUS может вам пригодиться. Существует много переменных массива Bash, таких как PIPESTATUS, которые могут быть чрезвычайно полезны; см. справочное руководство по Bash для всего списка и другие сайты Stackexchange для примеров их использования.
Это не покрывает каждый 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*$'; 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.