Bash -a против bash &&

У меня есть это заявление bash:

if ls > /dev/null 2>&1 -a ls > /dev/null 2>&1; then
    echo "true"; 
else 
    echo "false"; 
fi

Что дает мне «ложь». Но я знаю, что ls всегда будет возвращать 0 (т.е. true). Я думал, что -a было оператором AND.

Когда я меняю это на:

if ls > /dev/null 2>&1 && ls > /dev/null 2>&1; then
    echo "true"; 
else 
    echo "false"; 
fi

Оно работает. Что здесь происходит по-другому? Разве -a не является оператором AND?


person Connor    schedule 21.06.2018    source источник
comment
Кстати, эффективнее использовать grep -q "state UP" и не заморачиваться с >/dev/null. Когда grep знает, что вывод вам не нужен, он (1) не удосуживается записать его, даже в /dev/null, где он выбрасывается; и (2) может выйти немедленно, как только будет обнаружено совпадение, без необходимости чтения остальной части входного потока.   -  person Charles Duffy    schedule 21.06.2018
comment
@CharlesDuffy Спасибо за заметку о grep -q "state UP", я воспользуюсь ей в будущем. Для тех, кто найдет это в будущем, в этом вопросе использовалась эта команда: ip link show eth1 | grep "state UP" > /dev/null 2>&1, которую я отредактировал для простоты.   -  person Connor    schedule 23.06.2018


Ответы (1)


&& — это правильный способ выполнения короткого логического И в bash.

-a — это операнд test (test — это команда, также именуемая [). Это не означает И в любом другом контексте (встроено в bash; например, является также предикатом в find). Более того, спецификация POSIX для test помечена как "устаревшая"; найдите OB на связанной странице.

Вышеизложенное также означает, что [ -n "$foo" ] && [ -n "$bar" ] или [[ $foo && $bar ]] лучше, чем [ -n "$foo" -a -n "$bar" ].

person Community    schedule 21.06.2018
comment
Синтаксис оболочки, как правило, чрезвычайно зависит от контекста. То есть значение различных символов во многом зависит от того, где они встречаются. && означает логический и когда он находится между командами (как в [ -n "$foo" ] && [ -n "$bar" ]), или внутри [[ ]] или (( )), но не внутри [ ]. -a означает логический и только когда встречается внутри [ ] (и то только в некоторых позициях). Это лишь один из многих примеров такой зависимости от контекста. - person Gordon Davisson; 21.06.2018
comment
Я вообще не решаюсь назвать синтаксис оболочки -a -- это часть спецификации test, а не часть командный язык оболочки, тогда как && является частью этого языка. - person Charles Duffy; 21.06.2018
comment
Я не возражаю, но я считаю это различие частью контекстной зависимости, о которой я говорил. - person Gordon Davisson; 22.06.2018
comment
Вот такие вещи заставляют меня ненавидеть bash: или внутри [[ ]] или (( )), но не внутри [ ]. Есть ли доступный способ изучить этот материал, который заставит его казаться мотивированным и убедительным, а не одиозным, плохо продуманным, заклеенным изолентой, недоступным беспорядком, каким он кажется мне прямо сейчас? - person Connor; 23.06.2018
comment
@Connor, [ ], также известная как команда test, относится к 1970-м годам - ​​она ​​намного старше [[ ]] и (( )) (которые не являются внешней командой, а синтаксисом, распознаваемым синтаксическим анализатором), и она вообще не является частью bash< /i> (за исключением того, что bash имеет встроенную реализацию того, что в противном случае было бы внешней командой для повышения производительности). Было бы полезно начать с простого изучения командного языка оболочки и игнорировать все остальное - если вы не думаете (ошибочно), что [ является частью bash, вы не можете спутать синтаксис [ с синтаксисом оболочки. - person Charles Duffy; 24.06.2018
comment
@Connor, ... итак, то, что вы приписываете кому-то, принявшему действительно ужасное дизайнерское решение, было скорее тем, что кто-то пытался исправить чей-то оплошность в дизайне, существовавший десятилетия назад, таким образом, чтобы избежать обратной несовместимости. Bash полон этого, да, но, учитывая контекст и историю, причина становится гораздо менее загадочной. - person Charles Duffy; 24.06.2018
comment
@CharlesDuffy Я могу принять это как таковое, это не делает его более приятным. Какие-нибудь ресурсы для углубленного изучения командного языка оболочки, которые вы рекомендуете? Я тоже могу пойти на охоту, просто подумал, что спрошу - person Connor; 24.06.2018
comment
Спецификация POSIX (ссылка выше) является каноническим ресурсом; вики bash-hackers немного менее канонична, но гораздо более доступна, оставаясь при этом быть точным и ориентироваться на передовой опыт. Для более медленного документа в стиле учебника я предлагаю BashGuide или BashFAQ и BashPitfalls документы для людей, пытающихся быстро определить места, где есть место для дополнения их существующего понимания. - person Charles Duffy; 24.06.2018