Як я можу використовувати значення з труби в програмі тестування?


10
wc -l | test -eq 1

Це не працює. Я хочу порівняти результат wc зі значенням 1. Як це зробити?

Відповіді:


9

Це не відповідає на ваше запитання щодо труб, але ви можете переставити:

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

І є кілька рішень щодо SO , це найкраще:

ls -l | wc -l | { read wc; test $wc -eq 7 && echo "woohoo"; }

4

Якщо ви використовуєте 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 для прикладів їх використання.



1

Це охоплює не кожен 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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.