Bash-блок і повернення кодів - потрібно пояснення


0

Я давно використовую Bash, але, здається, все одно щось сумую. Будь ласка, врахуйте цей код:

function surprise {
    true && {
        echo 'Expected';
        false;
    } || {
        echo 'Unexpected';
    }
}

surprise;

що є скороченою демонстрацією моєї реальної проблеми та результатів:

Expected
Unexpected

До цього часу я думав, що те, що повертається "Очікуваний" блок, не впливає ||перед блоком "Неочікуваний", але, схоже, ||перевіряється не на вихід trueкоманди, а насправді на falseкоманду всередині дужок.

Може хтось, будь ласка, пояснить, що насправді щойно сталося? Спасибі заздалегідь.

Відповіді:


2

здається, як || не перевіряється на результат виведення вірної команди, а насправді помилкової команди всередині дужок.

Можна сказати, що так.

x && y || z не є структурою if / then / else і не повинна використовуватися як одна. Це комбінація булевих операторів - еквівалент "x AND y АБО z" - і оцінить стільки команд, скільки потрібно для визначення результату. (Оцінка ліворуч праворуч, якщо їх не згрупувати в дужках чи дужках, як у більшості мов програмування, тому порядок є (x && y) || z.)

Отже, для того, щоб визначити результат x && y, коли x є істинним, y також слід оцінити. З іншого боку, коли x помилково, результат буде хибним незалежно від того, тому він просто коротке замикання і пропустить оцінку y .

Чи значення між ними є окремими командами чи {cmd; cmd; cmd}блоками, насправді зовсім не має значення; в цій ситуації він просто допомагає побачити фактичні наслідки.


Коротке замикання ... Мені дуже до думки &&і ||більше подобалось if-then-else, але тепер я це отримую - дякую!
Cromax

2

По-перше: ви можете розглядати кожен з "блоків" як просто складні команди, а не щось суттєво відрізняється. Таким чином, те, що ви насправді маєте, це просто:

cmd1 && cmd2 || cmd3

... і той факт , що cmd2і cmd3блоки , а не прості команди не має значення. Тепер важливим є те, що з огляду на послідовність команд, логічний пріоритет операторів &&і ||"операторів" робить це приблизно таким:

( cmd1 && cmd2 ) || cmd3

(Зауважте: насправді ці дужки змушуватимуть підзаголовок. Я це ігнорую.) Якщо ви подивитеся на логічну структуру цього, це ( something ) || cmd3так, то явно воно запуститься, cmd3якщо somethingне вдасться. Але somethingнасправді cmd1 && cmd2, що якщо вдасться * як cmd1і cmd2успіх - це означає , що не виконується , якщо або cmd1 або cmd2зазнає невдачі.

Таким чином, логічно, що буде заводитися працює , cmd3якщо або cmd1 або cmd2виходить з ладу. У вашому фактичному коді cmd2завжди виходить з ладу, тому cmd3завжди працює.


0

Подвійний і ( &&) і подвійний канал ( ||) мають значення в управлінні процесом в Linux.

Розглядайте їх як логічних операторів.

command1 && command2

або

command1 || command2

Або

command1 && command2 || command3

В основному, у всіх 3 випадках command1працює. Якщо він має статус виходу NON-ZERO (помилка певного типу), вважається, що він не запустився успішно.

З &&- мислення логічного І в програмуванні - не потрібно запускати другу команду, оскільки перша якимось чином не вдалася.

При ||логічному АБО - якщо перший успішний (вихід 0), не потрібно перевіряти другу умову - лише одна чи друга повинні бути успішними.

З 3-м прикладом, якщо command1він буде успішним, він запуститься command2. Якщо це не вдалося, він замість цього запуститьсяcommand3

У вашому прикладі, ||це визначає статус виходу вашої falseкоманди.

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