Czy istnieje sposób, aby ponownie napisać strukturę poleceń, A && B || C | Daby B lub C zostały podłączone do D?
Przy bieżącym poleceniu uruchamiane są tylko B lub oba C i D.
Na przykład:
Czy istnieje sposób, aby ponownie napisać strukturę poleceń, A && B || C | Daby B lub C zostały podłączone do D?
Przy bieżącym poleceniu uruchamiane są tylko B lub oba C i D.
Na przykład:
Odpowiedzi:
Tak, w bash możesz użyć nawiasów:
(A && B || C) | D
W ten sposób wyjście A && B || Czostanie przekazane do D.
sh:)
Aznajduje się w podpowłoce, obejmuje to również A.)
Możesz to napisać jako
if A; then B; else C; fi | D
Mówisz, że chcesz uruchomić albo Balbo C, ale A && B || Cnie osiągnąć. Jeśli się Apowiedzie, ale Buruchomi się i nie powiedzie, wykona się C.
Uwaga 1: jeśli możesz w jakiś sposób zagwarantować, że Bzawsze się powiedzie i chcesz pozostać przy krótkiej wersji, nadal bym wybrał
{ A && B || C; } | D
koniec ( ... ), ponieważ ten ostatni niepotrzebnie wymusza utworzenie nowej podpowłoki, która może, ale nie musi zostać zoptymalizowana.
Uwaga 2: zakładamy, że obie formy Anie generują danych wyjściowych, co jest prawdą w twoim przykładzie, ale niekoniecznie w ogóle. Można tego uniknąć
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }nie wymusza to utworzenia podpowłoki z powodu potoku? I zaobserwować następujące zachowanie: pgrep bashi pgrep bash | cati if true; then pgrep bash; fii { pgrep bash; }mają jedną linię wyjścia; ( pgrep bash; )i ( pgrep bash; ) | cati { pgrep bash; } | cati if true; then pgrep bash; fi | catmają dwa wiersze wyników.
... | ...powoduje utworzenie podpowłoki, co jest nieuniknione. ( ... ), przynajmniej teoretycznie, powoduje utworzenie dodatkowej podpowłoki, która { ...; }pozwala jej uniknąć, ale właśnie to miałem na myśli mówiąc „może zostać zoptymalizowany lub nie”: możliwe jest, że w tym konkretnym przypadku powłoka zdaje sobie sprawę, że to nie ma znaczenia, efekt byłby taki sam.
Odpowiedź akceptora jest poprawna, ale nie obejmuje potencjalnego przypadku użycia, którego nie należy podawać Ajako wyniku D. Aby to osiągnąć, konieczne będzie przekierowanie strumienia w Azależności od potrzeb.
Jeśli Amimo wszystko chcesz odrzucić dane wyjściowe :
{ A >/dev/null && B || C; } | DJeśli chcesz zobaczyć dane wyjściowe Ana terminalu:
{ A >/dev/tty && B || C; } | DJeśli potrzebujesz danych wyjściowych Ajako danych wejściowych kolejnego polecenia E, potrzebujesz dodatkowej grupy poleceń i przekierowania strumienia:
{ { A >&3 && B || C; } | D; } 3>&1 | EJeśli to wszystko wydaje się zbyt tajemnicze (tak jak dla mnie), zalecamy użycie specjalnej zmiennej powłoki dla statusu wyjścia Ai pracę z tym:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Jeśli chcesz być bardziej zwięzły, ale nie zbyt tajemniczy, sugeruję to:
A; { [ $? -eq 0 ] && B || C; } | D
(Zobacz także ostatnią część odpowiedzi hvd, której nie zauważyłem, kiedy napisałem swoją pierwotną odpowiedź).
Awyszedłem z rurociągu.
A && (B || C) | D, jeśli nie chcesz, aby B, C lub D działały, gdy A zawiedzie