Соответствующий раздел руководства удара перечисляет 5 различных конструкций, которые могут использоваться для условной оценки. Из них, if
, case
, и [[ .. ]]
конструкции, вероятно, обычно используются в реальном коде, хотя (( .. ))
конструкция будет часто привыкать в сценариях, которые делают сложный подсчет или другие числовые операции.
Но они не упоминают другую очень стандартную форму, используемую для ветвления в ударе, который должен просто выполнить команду в сочетании с оценкой короткого замыкания, например
grep -q needle haystack.txt && echo "Needle located!" || echo "No dice or needles.";
&&
и ||
логические операторы: "и" и "или" соответственно.
Это - эффективно то же как
if grep -q needle haystack.txt; then echo "yea"; else echo "nay"; fi;
но работы по-другому: в первой форме условная логика действительно появляется как побочный эффект фактической явной цели кода, который должен, по крайней мере якобы, оценить логические операторы. Этот вид конструкции также обычно замечается в C и коде JavaScript.
Это работает путем поиска легких путей: части выражения, например. x && y || z
, оценены слева направо. Если левая сторона логического и, например, x
в x && y
, оценивает ко лжи, bash
не потрудился оценивать y
часть, потому что в той точке это уже знает это x && y
ложь.
Обратное верно для логического ors: true || z
всегда оценивает к истинному, независимо от того, чем оказывается z.
Таким образом, если grep
выходит ложь, bash
может пропустить это сначала echo
, потому что та часть выражения не может возможно быть верной. Таким образом, это идет дальше к второму echo
. С другой стороны, если grep является верным, первым echo
выполняется (приводящий к тем, ну, в общем, отражаемым словам..). В этой точке bash
сделан, потому что безотносительно значения правой стороны ||
, результат выражения все еще будет верен.
Для получения ощущения пути работы удара с условными выражениями, лучше делать некоторое экспериментирование на командной строке. Команда
echo $?;
повторит код возврата предыдущего оператора. Это - код ошибки, таким образом, 0
верное средство, и ненулевое значение означает ложь. Это немного сбивает с толку сначала, но Вы привыкаете к нему.
Таким образом, можно сделать, например
$ (( 1 + 2 == 3 )); echo $?
0
$ (( 1 + 2 == 4 )); echo $?
1
и выполните подобные тесты с [[ .. ]]
создайте для получения ощущения этих основных стандартных блоков. После того как Вам сделали это, движение к if
и затем case
операторы.
Что касается ответа на Ваш вопрос, ну, в общем, я думаю, что это очень зависит от контекста, в котором его спросили. Но получение хорошего понимания различных вариантов должно помочь Вам выяснить то, что они ищут там.
Вам даже не нужен расширенный globbing, позволенный сделать то, что Вы хотите. Это будет работать в ударе:
ls {day*,night*}
Нет никакой опции в ls
для фильтрации на имени файла, но в большинстве оболочек существует globbing расширение man bash
/Pattern Matching
ksh
ls -lrtd -- *@(day|night)*
zsh
setopt extendedglob
ls -lrtd -- *(day|night)*
или:
setopt kshglob
ls -lrtd -- *@(day|night)*
удар
shopt -s extglob
ls -lrtd -- *@(day|night)*
В любой из этих трех оболочек можно сделать это, но отметить что, если один из случаев не соответствует никакому файлу, что шаблон оставят нерасширенным (например. *day* night1.txt othernight.txt
если нет никакого имени файла, содержащего day
; посмотрите man bash
/EXPANSION
или /Brace Expansion
конкретно):
ls -lrtd -- *{day,night}*
В любых оболочках можно сделать:
ls -lrtd -- *day* *night*
В zsh, если существует любой нет day
или night
файл, последние две команды перестанут работать; установите nonomatch
или csh_null_glob
опция, или добавляют (N)
после каждого шаблона для предотвращения этого.
*{day,night}*
. Я отредактировал бы его, но я не знаю, какие оболочки поддерживают его?
– Random832
08.10.2012, 18:12
bash
, ksh
, и zsh
(ни одному не нужен расширенный globbing), но нет sh
- однако, Nahuel, последний "все оболочки" пример, действительно работает в sh
.
– Izkata
08.10.2012, 21:04
Оболочки не делают регулярных выражений использования для расширения аргумента.
Можно включить расширенное сопоставление с образцом
$ shopt -s extglob
и затем
$ ls @(day|night).txt
day.txt night.txt
См., например, Справочник Bash (Сопоставление с образцом)
touch day.txt; touch night.txt; ls {*day,night*}
результаты вls: *day: No such file or directory
– Matteo 08.10.2012, 19:46*{day,night}*
ближе к тому, что хочет OP. – derobert 08.10.2012, 20:24