Bash c-style if оператор и методы стиля

насколько я понимаю вы можете сделать в стиле C for и while в bash.

LIMIT=10

for ((a=1; a <= LIMIT ; a++))  # Double parentheses, and "LIMIT" with no "$".
do
  echo -n "$a "
done                           # A construct borrowed from 'ksh93'.

и даже тернарные операторы.

(( var0 = var1<98?9:21 ))

как бы вы сделали это с if заявление?

также почему они не реализуют фигурные скобки, как в C? Какова логика использования всех этих ключевых слов, таких как done, do, if и fi? Я буду писать некоторые сценарии, но bash выглядит совсем по-другому.

есть ли Баш стайлинг методы или альтернативы/Плагины bash? Я хотел бы следовать стандарту, но исходящий из C, Java и PHP background bash выглядит очень странно. Ремонтопригодность и стандарты важны.

4 ответов


есть некоторые синтаксические особенности bash (и, возможно, другие оболочки sh family), связанные с if:

  • основной if-оператор имеет синтаксис if condition-command ; then list ; fi (с возможностью добавить elif и else для других веток).

    • The condition-command может быть любая команда, которую поддерживает bash (даже другая, если, я думаю), выполняется, и возвращаемое значение затем оценивается. (На самом деле, это также может быть список команд, но это может запутать читателей. Возвращаемое значение последней команды имеет значение для условия.)
    • Bash (и оболочки Unix в целом) интерпретируют коды результатов программ немного необычным образом (для программистов C): результат 0 интерпретируется как true (или "нет ошибки"), а любой другой результат интерпретируется как false (или "произошла ошибка"). (В C и некоторых других языках это наоборот: 0 -false и все остальное true.)
    • если результат условие-команда 0 (true),list выполняется (и возвращаемое значение if в результате в списке). Если это не-0 (false), список не выполняется (но elif или else ветви, если они есть). (Если ни один из списков не выполняется, возвращаемое значение if равно 0.)
  • некоторые полезные команды в качестве условий (они также работают как условия в while loops):

    • [ ... ] на самом деле другой способ пиши test ... - это просто команда, которая может возвращать 0 (true) или 1 (false) в зависимости от того, какие параметры вы даете. (Это здание из раковины.)
    • [[ ... ]] - команда условного выражения. Он поддерживает некоторые из тех же аргументов, что [ поддерживает, и некоторые другие, как скобки,<, > и ( ... ) для вложенности условий и обрабатывает расширения внутри немного отличается, так как это специальная синтаксическая конструкция вместо команду строить. Все это команда, которая возвращает 0 (true) или 1 (false).
    • (( ... )) является оболочкой для арифметического выражения (или нескольких из них) в качестве команды. Результат равен 0 (true), когда результат (последнего) выражения не равен 0, и 1 (false), когда результат (последнего) выражения равен 0. (Вместо этого вы можете написать let ....)

      в арифметических выражениях переменные оболочки могут использоваться без $ и все это интерпретируется как целые числа (фиксированной ширины, но я не узнал, какие). Вы можете использовать следующие операторы:

      • унарные: ++, --, +, -, !, ~ (как в C)
      • двоичный арифметика: ** (возведения), *, /, %, +, -
      • bit-shift:<<, >>
      • для сравнения: <=, >=, <, >, ==, != (я думаю, что они возвращают либо 1 (true) или 0 (false))
      • побитовые: &, ^, |
      • логические: &&, ||, и, конечно же, троичный оператор:... ? ... : ...
      • назначение: =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
      • запятая: , (просто соединяет два выражения, возвращая значение последнего)

      я думаю, что в целом это работает много как с целочисленными выражениями. (Это примерно в порядке приоритета, но иногда внутри каждой группы есть подразделения. Посмотрите в info '(bash)Shell Arithmetic' для сведения.)

    • true - это сборка, которая ничего не делает и всегда возвращает 0.
    • false - это сборка, которая ничего не делает и всегда возвращает 1.
    • вы также можете вызвать свои внешние программы C (или что-нибудь еще) в качестве команд, их возвращаемые значения интерпретируются одинаково путь.
  • список:

    • ( ... ) список команд, который выполняется в подоболочку. Назначения переменных в этой подрешетке не распространяются обратно.
    • { ...; } - это список команд, которые не создают подсетку.
    • ; - это простой разделитель команд в списке, но также может быть заменен новой строкой.
    • && является разделителем команд, выполняющих вторую один только при первом возврате 0.
    • || является разделителем команд, выполняющих вторую только тогда, когда первая возвращается не-0.
    • & является разделителем команд, выполняющих обе команды параллельно (первая в фоновом режиме).

Итак, вы can написать свой if-команда с некоторыми скобками и скобками, но вам все равно нужен ваш then и fi:

if (( i > 0 ))
then {
   echo "i > 0"
}
else {
   echo "i <= 0"
}
fi

фигурные скобки здесь просто лишние, так как команды между then, else и fi есть (каждый) один список в любом случае. (Также обратите внимание на необходимость новых строк или ; после и до закрытия скобок здесь.)

но, как говорили другие,лучше использовать другой язык, если вы хотите использовать C-подобный синтаксис.


в bash оператор if не имеет скобок, таких как () например, некоторого синтаксиса в bash

if [[ ... ]];then
  ..
fi 

if [ ... ];then
 ...
fi

if $(grep .. file) ;then  #note the () is part of $().
  ...
fi

Я ничего не имею против Bash, но IMO, вам лучше использовать язык программирования, который может предоставить вам все, что вам нужно в ваших сценариях/программировании, таких как Python, Ruby или Perl. Bash имеет некоторые ограничения, такие как выполнение математики с плавающими точками и т. д.Кроме того, если ваша задача достаточно сложна, чрезмерное использование инструментов *nix может привести к" раздутости " вашего сценарий, следовательно, мешает производительности. Если вы хотите "чистый" синтаксис и ремонтопригодность, либо Ruby/Python может вам подойти. ИМО, имея скобки или нет, - это просто соображения языкового дизайна, и я лично не хотел бы скобок, если у меня есть выбор.


причина текущего синтаксиса в значительной степени историческая. Большая часть того, о чем вы спрашиваете, основана на оригинальной Bourne shell (sh). Борн решил основывать синтаксис на Алголе, а не на C.

иметь более C-подобный синтаксис (и не быть csh), кто-то должен был бы начать с нуля.

Как уже сказали, для многих целей вы можете писать скрипты на других языках.

вы можете посмотреть на Крошечный Компилятор C который можно использовать для запуска источника C в качестве сценария оболочки.

#!/usr/bin/tcc -run
#include <stdio.h>

int main()
{
    printf("Hello World\n");
    return 0;
}

Если вы по какой-то причине не привязаны к bash, я бы рекомендовал вам использовать более современный структурированный язык сценариев, такой как Ruby, Python или PHP, и просто использовать соответствующий заголовок сценария, чтобы сделать их исполняемыми, как сценарий bash. Я лично большой поклонник bash one-liners на консоли, но считаю его полностью тупым при использовании в качестве скриптового языка.

большинство современных языков сценариев даст вам легкий доступ к массиву, как ARGV для аргументы командной строки и поддержка знакомых циклов и структур управления.

Итак, например, вы напишете сценарий Ruby и предварите его #!/usr/bin/ruby, например:

#!/usr/bin/ruby
for a in 1..10
  puts ( a >= 5 ) ? "a >= 5" : "a < 5"
end