Bash
Контрольные структуры
Поиск…
Синтаксис
- ["$ 1" = "$ 2"] #A "[" Скобка - это фактически команда. Из-за этого требуется пространство для него и после него.
- test "$ 1" = "$ 2" #Test является синонимом команды "["
параметры
Параметр [или тест | подробности |
---|---|
Операторы файлов | подробности |
-e "$file" | Возвращает true, если файл существует. |
-d "$file" | Возвращает true, если файл существует и является каталогом |
-f "$file" | Возвращает true, если файл существует и является обычным файлом |
-h "$file" | Возвращает true, если файл существует и является символической ссылкой |
Компоненты строк | подробности |
-z "$str" | Истинно, если длина строки равна нулю |
-n "$str | Истинно, если длина строки отлична от нуля |
"$str" = "$str2" | Истинно, если строка $ str равна строке $ str2. Не лучше для целых чисел. Он может работать, но будет несовместимым |
"$str" != "$str2" | Истинно, если строки не равны |
Целочисленные компараторы | подробности |
"$int1" -eq "$int2" | Истинно, если целые числа равны |
"$int1" -ne "$int2" | Истинно, если целые числа не равны |
"$int1" -gt "$int2" | Истинно, если int1 больше, чем int 2 |
"$int1" -ge "$int2" | Истинно, если int1 больше или равно int2 |
"$int1" -lt "$int2" | Истинно, если int1 меньше, чем int 2 |
"$int1" -le "$int2" | Истинно, если int1 меньше или равно int2 |
замечания
В bash имеется множество параметров компаратора. Не все еще перечислены здесь.
Если утверждение
if [[ $1 -eq 1 ]]; then
echo "1 was passed in the first parameter"
elif [[ $1 -gt 2 ]]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
Замыкание fi
необходимо, но предложения elif
и / или else
могут быть опущены.
Точки с запятой до then
являются стандартным синтаксисом для объединения двух команд в одну строку; они могут быть опущены , если только then
перемещается на следующую строку.
Важно понимать, что скобки [[
не являются частью синтаксиса, но рассматриваются как команда; это код выхода из этой команды, которая тестируется. Поэтому вы всегда должны включать пробелы вокруг скобок.
Это также означает, что результат любой команды может быть протестирован. Если код выхода из команды равен нулю, утверждение считается истинным.
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
Математические выражения, размещенные внутри двойных скобок, также возвращают 0 или 1 таким же образом, а также могут быть протестированы:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
Вы также можете столкнуться , if
заявления с одиночными скобками. Они определены в стандарте POSIX и гарантированно работают во всех POSIX-совместимых оболочках, включая Bash. Синтаксис очень похож на синтаксис в Bash:
if [ "$1" -eq 1 ]; then
echo "1 was passed in the first parameter"
elif [ "$1" -gt 2 ]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
Пока цикл
#! /bin/bash
i=0
while [ $i -lt 5 ] #While i is less than 5
do
echo "i is currently $i"
i=$[$i+1] #Not the lack of spaces around the brackets. This makes it a not a test expression
done #ends the loop
Посмотрите, что во время теста есть пробелы вокруг скобок (после утверждения while). Эти пространства необходимы.
Эта петля выводит:
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
Для цикла
#! /bin/bash
for i in 1 "test" 3; do #Each space separated statement is assigned to i
echo $i
done
Другие команды могут генерировать операторы для перебора. См. Пример «Использование для цикла для ввода чисел».
Эти результаты:
1
test
3
Использование цикла для перебора Iterate Over Numbers
#! /bin/bash
for i in {1..10}; do # {1..10} expands to "1 2 3 4 5 6 7 8 9 10"
echo $i
done
Это обеспечивает следующее:
1
2
3
4
5
6
7
8
8
10
Для цикла с синтаксисом C-стиля
Основной формат C-стиль for
петли:
for (( variable assignment; condition; iteration process ))
Заметки:
- Назначение переменной внутри цикла C-стиля
for
цикла может содержать пробелы, в отличие от обычного назначения - Переменным внутри цикла C
for
цикла не предшествует$
.
Пример:
for (( i = 0; i < 10; i++ ))
do
echo "The iteration number is $i"
done
Также мы можем обрабатывать несколько переменных внутри цикла C for
цикла:
for (( i = 0, j = 0; i < 10; i++, j = i * i ))
do
echo "The square of $i is equal to $j"
done
До цикла
Пока цикл не будет выполняться до тех пор, пока условие не будет истинным
i=5
until [[ i -eq 10 ]]; do #Checks if i=10
echo "i=$i" #Print the value of i
i=$((i+1)) #Increment i by 1
done
Выход:
i=5
i=6
i=7
i=8
i=9
Когда i
достигает 10, условие до тех пор, пока цикл не станет истинным, и цикл закончится.
продолжить и разбить
Пример продолжения
for i in [series]
do
command 1
command 2
if (condition) # Condition to jump over command 3
continue # skip to the next value in "series"
fi
command 3
done
Пример разрыва
for i in [series]
do
command 4
if (condition) # Condition to break the loop
then
command 5 # Command if the loop needs to be broken
break
fi
command 6 # Command to run if the "condition" is never true
done
Зацикливание по массиву
for
цикла:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
done
Или же
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
while
loop:
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
Или же
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
Перерыв петли
Разрыв нескольких циклов:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break 2
done
done
Выход:
a
a
Разрыв одного цикла:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
Выход:
a
a
b
a
c
a
d
a
e
a
f
a
Оператор switch с футляром
С помощью оператора case
вы можете сопоставлять значения с одной переменной.
Аргумент, переданный case
, расширяется и пытается сопоставляться с каждым шаблоном.
Если совпадение найдено, команды upto ;;
выполняются.
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
Шаблон - это не регулярные выражения, а совпадение шаблонов (aka globs).
Для Loop без параметра списка слов
for arg; do
echo arg=$arg
done
В цикле for
без параметра списка слов вместо этого будут выполняться итерация по позиционным параметрам. Другими словами, приведенный выше пример эквивалентен этому коду:
for arg in "$@"; do
echo arg=$arg
done
Другими словами, если вы поймете, что пишете for i in "$@"; do ...; done
, просто перенесите in
части, а просто писать for i; do ...; done
.
Условное выполнение списков команд
Как использовать условное выполнение списков команд
Любая встроенная команда, выражение или функция, а также любая внешняя команда или скрипт могут выполняться условно с использованием &&
(и) и ||
(или) операторов.
Например, это приведет только к печати текущего каталога, если команда cd
была успешной.
cd my_directory && pwd
Аналогично, это приведет к выходу из строя команды cd
, предотвращая катастрофу:
cd my_directory || exit
rm -rf *
При объединении нескольких операторов таким образом важно помнить, что (в отличие от многих языков C-стиля) эти операторы не имеют приоритета и являются лево-ассоциативными .
Таким образом, это заявление будет работать как ожидалось ...
cd my_directory && pwd || echo "No such directory"
- Если
cd
завершается успешно, выполняется&& pwd
и печатается текущее имя рабочего каталога. Еслиpwd
не сработает (редкость)|| echo ...
не будет выполняться. - Если
cd
не удастся,&& pwd
будет пропущен, а значение|| echo ...
будет работать.
Но это не будет (если вы думаете, if...then...else
) ...
cd my_directory && ls || echo "No such directory"
- Если
cd
терпит неудачу,&& ls
пропущен и|| echo ...
выполняется. - Если
cd
завершается успешно, выполняется&& ls
.- Если
ls
преуспеет,|| echo ...
игнорируется. (Все идет нормально) - НО ... если
ls
терпит неудачу, то|| echo ...
также будет выполнено.Это команда
ls
, а неcd
, это предыдущая команда .
- Если
Зачем использовать условное выполнение списков команд
Условное исполнение - это волосы быстрее, чем if...then
но его главное преимущество - позволить функциям и сценариям выходить рано или «короткое замыкание».
В отличие от многих языков, таких как C
где ядро явно выделяется для структур и переменных и таких (и, следовательно, должно быть освобождено), bash
обрабатывает это под обложками. В большинстве случаев нам не нужно ничего убирать, прежде чем покидать эту функцию. Оператор return
освобождает все локальные функции и выполнение записи на обратном адресе в стеке.
Возвращение из функций или выход из сценариев как можно скорее может значительно повысить производительность и снизить нагрузку на систему, избегая ненужного выполнения кода. Например...
my_function () {
### ALWAYS CHECK THE RETURN CODE
# one argument required. "" evaluates to false(1)
[[ "$1" ]] || return 1
# work with the argument. exit on failure
do_something_with "$1" || return 1
do_something_else || return 1
# Success! no failures detected, or we wouldn't be here
return 0
}