Чи є спосіб переписати командну структуру, A && B || C | Dщоб або B, або C було переведено в D?
За допомогою поточної команди виконується лише B або обидва C і D.
Наприклад:
Чи є спосіб переписати командну структуру, A && B || C | Dщоб або B, або C було переведено в D?
За допомогою поточної команди виконується лише B або обидва C і D.
Наприклад:
Відповіді:
Так, в bash ви можете використовувати дужки:
(A && B || C) | D
Таким чином, вхід A && B || Cбуде зафіксований D.
sh:)
Aзнаходиться всередині A
Ви можете написати це як
if A; then B; else C; fi | D
Ви кажете, що хочете бігти Bабо C, але A && B || Cцього не досягаєте. Якщо це Aвдасться, але Bпробігає і не вдається, воно виконаєC .
Примітка 1: якщо ви можете якось гарантувати, що Bзавжди успішно і хочете дотримуватися короткої версії, я б все-таки вибрав це
{ A && B || C; } | D
над ( ... ) , оскільки останній необгрунтовано змушує створити нову підзарядку, яка може або не може бути оптимізованою.
Примітка 2: обидві форми припускають, що Aне дає результатів, що є правдою у вашому прикладі, але не обов'язково в цілому. Цього можна уникнути
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }не змушує створити підзаглушку через трубу? Я спостерігаю наступне поведінка: pgrep bashі pgrep bash | catта if true; then pgrep bash; fiі { pgrep bash; }мають один рядок; ( pgrep bash; )і ( pgrep bash; ) | catі { pgrep bash; } | catі if true; then pgrep bash; fi | catмають два рядки виведення.
... | ...спричиняє створення додаткової оболонки , що неминуче. ( ... ), принаймні теоретично, спричиняє створення додаткової оболонки, яка { ...; }уникає, але саме це я мав на увазі "може або не може бути оптимізований": можливо, що в цьому конкретному випадку оболонка розуміє, що це не має значення, ефект був би таким же.
Відповідь приймача є правильною, але вона не охоплює потенційний випадок використання, щоб не мати вихід Aяк вхід D. Для цього вам потрібно перенаправлення потоку Aзалежно від ваших потреб.
Якщо ви хочете все-таки відкинути вихід A:
{ A >/dev/null && B || C; } | DЯкщо ви хочете побачити вихід Aтерміналу:
{ A >/dev/tty && B || C; } | DЯкщо вам потрібен вихід Aяк вхід наступної команди, Eвам знадобиться додаткова командна група та перенаправлення потоку:
{ { A >&3 && B || C; } | D; } 3>&1 | EЯкщо все це здається вам занадто прихованим (як і мені), я рекомендую вам використовувати спеціальну змінну оболонки для стану виходу Aта працювати з цим:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Якщо ви хочете бути більш стислими, але не надто несерйозними, пропоную це:
A; { [ $? -eq 0 ] && B || C; } | D
(Дивіться також останню частину відповіді hvd, яку я не помітив, коли писав оригінальну відповідь.)
Aвийшов з конвеєра.
A && (B || C) | Dякщо ви не хочете, щоб B, C або D запускалися, коли A не