Jak mogę użyć wartości z potoku w programie testowym?

10
wc -l | test -eq 1

To nie działa Chcę porównać wynik wc z wartością 1. Jak to zrobić?

tr3quart1sta
źródło

Odpowiedzi:

9

Nie odpowiada na twoje pytanie dotyczące rur, ale możesz zmienić kolejność:

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

Istnieje kilka rozwiązań w zakresie SO , jest to najładniejsze:

ls -l | wc -l | { read wc; test $wc -eq 7 && echo "woohoo"; }
Oli
źródło
4

Jeśli używasz Bash, prawdopodobnie chcesz zbadać zmienną PIPESTATUS. Jak zauważono w podręczniku Bash , PIPESTATUS to

Zmienna tablicowa (patrz Tablice) zawierająca listę wartości statusu wyjścia z procesów w ostatnio wykonywanym potoku pierwszoplanowym (która może zawierać tylko jedno polecenie).

Możemy dowiedzieć się, jakie były kody wyjścia dla tego potoku za pomocą PIPESTATUS:

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

Jeśli teraz zapytasz o zmienną tablicową, otrzymasz statusy wyjścia odnoszące się do poleceń używanych w potoku:

echo ${PIPESTATUS[@]}
0 1 0

(W tablicy indeksowanej powyższe kody wyjścia są reprezentowane przez 0 1 i 2 w tablicy, ponieważ tablice zawsze zaczynają się od 0 w Bash.)

Widzimy, że drugie polecenie zwróciło 1, a pozostałe 0; jednak wc -lzwraca 0 jeśli są zerowe mecze, które nie jest błędem. Niepowodzenie jest reprezentowane przez wartość niezerową, a istnieją inne wartości błędów, takie jak 127, których nie znaleziono polecenia, i jeszcze więcej kodów, które mogą być specyficzne dla danego programu.

Jeśli chcesz zobaczyć, jaki był kod zakończenia określonego polecenia w potoku, możesz po prostu uzyskać dostęp do tej wartości. Polecenie grep było drugim poleceniem w powyższym potoku, ale ponieważ tablice zaczynają się od 0, potrzebujemy pierwszego.

Aby znaleźć kod wyjścia polecenia grep, ponownie uruchom powyższy potok (ponieważ zawartość PIPESTATUS zostanie wyczerpana, jeśli uruchomiłeś echo ${PIPESTATUS[@]}), a następnie wykonaj poniższe polecenie, które zwróci 1 (kod wyjścia):

echo ${PIPESTATUS[1]}
1

W skrypcie upewnij się, że potok zakończył wykonywanie, zanim zaczniesz szukać zawartości zmiennej tablicowej PIPESTATUS.

Przykład interesującego zastosowania zmiennej tablicowej PIPESTATUS znajduje się w tej odpowiedzi dotyczącej łączenia grupowania poleceń Bash i statusu potoku . Możesz przetestować zmienną tablicową w sposób sugerowany przez Gillesa w komentarzach, chociaż najpierw będziesz musiał ponownie uruchomić potok:

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

To tylko fragment, ponieważ nie wiem, jaki rodzaj skryptu zamierzasz, ale mam nadzieję, że wiedza na temat PIPESTATUSA może ci się przydać. Istnieje wiele zmiennych tablic Bash, takich jak PIPESTATUS, które mogą być niezwykle przydatne; zapoznaj się z instrukcją obsługi Bash dla całej listy i innymi stronami Stackexchange, aby zobaczyć przykłady ich użycia.

Społeczność
źródło
2

Najprostszym sposobem jest prawdopodobnie użycie xargs :

wc -l | xargs -I % test % -eq 1
nieznany z nazwiska
źródło
1

Nie obejmuje to wszystkich testprzypadków, ale jeśli możesz użyć wyrażenia regularnego i grepciągu potokowego, jest to dość proste, ponieważ grepjest testpodobne do tego, że ma niezerowe wyjście, gdy nie znaleziono dopasowania

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

Rozszerzone wyrażenia regularne pozwalają objąć wiele przypadków tą techniką. W przypadku chichotów przypadek testowy:

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

wyjścia:

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.
zanerock
źródło