Bash c-style, если оператор и методы моделирования - PullRequest
6 голосов
/ 21 февраля 2011

Насколько я понимаю, вы можете делать циклы в стиле C для циклов и 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 или альтернативы / плагины bash?Я хотел бы следовать стандарту, но исходить из C, Java и PHP фоновый bash выглядит действительно странно.Ремонтопригодность и стандарты важны.

Ответы [ 4 ]

12 голосов
/ 21 февраля 2011

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

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

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

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

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

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

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

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

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

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

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

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

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

1 голос
/ 21 февраля 2011

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

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

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

Возможно, вы захотите взглянуть на Tiny C Compiler , который можно использовать для запуска источника C в качестве сценария оболочки.

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

int main()
{
    printf("Hello World\n");
    return 0;
}
1 голос
/ 21 февраля 2011

В 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.ИМО, иметь квадратные скобки или нет - это просто соображения языкового дизайна, и я лично не хотел бы скобки, если бы у меня был выбор.

0 голосов
/ 21 февраля 2011

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

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

Так, например, вы бы написали скрипт на Ruby и добавили к нему #!/usr/bin/ruby, например, так:

#!/usr/bin/ruby
for a in 1..10
  puts ( a >= 5 ) ? "a >= 5" : "a < 5"
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...