Чи є спосіб переписати командну структуру, 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 не