Дивіться наступні приклади та їх результати в оболонках POSIX:
false;echo $?
абоfalse || echo 1
:1
false;foo="bar";echo $?
абоfoo="bar" && echo 0
:0
foo=$(false);echo $?
абоfoo=$(false) || echo 1
:1
foo=$(true);echo $?
абоfoo=$(true) && echo 0
:0
Як згадується у відповіді з найбільшою оцінкою на /programming/6834487/what-is-the-variable-in-shell-scripting :
$?
використовується для пошуку значення повернення останньої виконаної команди.
Це, мабуть, трохи вводить в оману в цьому випадку, тому давайте отримаємо визначення POSIX, яке також цитується у публікації з цієї теми:
? Розширюється до десяткового статусу виходу останнього трубопроводу (див. Трубопроводи).
Таким чином, здається, що сам присвоєння вважається командою (а точніше частиною конвеєра) з нульовим значенням виходу, але яке застосовується перед правою стороною призначення (наприклад, тут в моїх прикладах викликає підміна команди).
Я бачу, як така поведінка має сенс з практичної точки зору, але мені здається дещо незвичним, що саме завдання буде зараховано в такому порядку. Можливо, щоб зрозуміти, чому мені це дивно, припустимо, що призначення було функцією:
ASSIGNMENT( VARIABLE, VALUE )
тоді foo="bar"
було б
ASSIGNMENT( "foo", "bar" )
і foo=$(false)
було б щось подібне
ASSIGNMENT( "foo", EXECUTE( "false" ) )
що означатиме, що EXECUTE
запускається перший і лише після цього ASSIGNMENT
, але це все ще EXECUTE
має значення статус.
Я правильний у своїй оцінці чи щось нерозумію / пропускаю? Чи є ці правильні причини, коли я сприймаю цю поведінку як "дивну"?
false;foo="bar";echo $?
завжди повертається 0, коли була остання реальна команда, що виконувалась false
?" По суті, присвоєння поводяться особливо, коли мова йде про вихідні коди. Їх код виходу завжди 0, за винятком випадків, коли це не через те, що було частиною правої частини завдання.