Linux script if options

Using if elif fi in shell scripts [duplicate]

Quite a few commentators have suggested you use [[ rather than [ but that makes your script bash-specific. You’ll have fewer maintenance and portability issues if you can stick to plain old Bourne shell (sh) syntax.

6 Answers 6

Josh Lee’s answer works, but you can use the «&&» operator for better readability like this:

echo "You have provided the following arguments $arg1 $arg2 $arg3" if [ "$arg1" = "$arg2" ] && [ "$arg1" != "$arg3" ] then echo "Two of the provided args are equal." exit 3 elif [ $arg1 = $arg2 ] && [ $arg1 = $arg3 ] then echo "All of the specified args are equal" exit 0 else echo "All of the specified args are different" exit 4 fi 

sh is interpreting the && as a shell operator. Change it to -a , that’s [ ’s conjunction operator:

Also, you should always quote the variables, because [ gets confused when you leave off arguments.

To note, this is a solution because the [[ construct is built into the shell while [ is another name for the test command and hence is subject to its syntax — see man test

I have a sample from your code. Try this:

echo "*Select Option:*" echo "1 - script1" echo "2 - script2" echo "3 - script3 " read option echo "You have selected" $option"." if [ $option="1" ] then echo "1" elif [ $option="2" ] then echo "2" exit 0 elif [ $option="3" ] then echo "3" exit 0 else echo "Please try again from given options only." fi 

Gawd this looks quirky to me. Why no then after else ? It may actually not be quirky, but that’s how it looks, compared to C.

 # cat checking.sh #!/bin/bash echo "You have provided the following arguments $arg1 $arg2 $arg3" if [ "$arg1" = "$arg2" ] && [ "$arg1" != "$arg3" ] then echo "Two of the provided args are equal." exit 3 elif [ $arg1 == $arg2 ] && [ $arg1 = $arg3 ] then echo "All of the specified args are equal" exit 0 else echo "All of the specified args are different" exit 4 fi # ./checking.sh You have provided the following arguments All of the specified args are equal 

You can add set -x in script to troubleshoot the errors.

Источник

If в Bash: от новичка до профессионала

Перевод статьи «Bash If Statements: Beginner to Advanced».

Bash это интересный язык. Изначально он был создан для интерактивного использования в командной строке, главным образом в REPL (Read-Evaluate-Print-Loop – «цикл чтение-вычисление-вывод») для работы над одной командой пользователя за раз.

Читайте также:  Изменить время сервера linux

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

В этой статье мы рассмотрим одну из немного запутанных тем: if-предложения. Мы погрузимся в их работу и узнаем, как более точно использовать ее механизмы.

Примечание: эта статья о Bash, однако большая часть всего сказанного здесь применима к Zsh и другим оболочкам. Некоторые из вещей несовместимы с POSIX.

Основы

If-предложения в Bash очень похожи на аналогичные в других языках. Они следуют базовой форме:

if [[ "$some_variable" == "good input" ]]; then echo "You got the right input." elif [[ "$some_variable" == "ok input" ]]; then echo "Close enough" else echo "No way Jose." fi

Дополнительный синтаксис в виде слова then , а также слегка странное закрывающее ключевое слово fi придает предложению немного экзотический вид, но в основе все то же самое, что и в других языках:

Если (if) что-то является истиной, тогда (then) выполни вот это. В противном случае проверяй другие условия по порядку и делай то же самое. Если ни одно из условий не сработало, выполни последнее указание.

Вы можете отбросить одну или все ветки elif , а также ветку else , если в них нет нужды!

Булевы операторы ! (нет), && (и), || (или) могут использоваться для комбинирования выражений, как и в других языках.

if [[ "$name" == "Ryan" ]] && ! [[ "$time" -lt 2000 ]]; then echo "Sleeping" elif [[ "$day" == "New Year's Eve" ]] || [[ "$coffee_intake" -gt 9000 ]]; then echo "Maybe awake" else echo "Probably sleeping" fi

Но здесь есть нечто запутанное. Порой вам встретятся двойные квадратные скобки, как в примере выше. А порой они будут одинарными.

if [ "$age" -gt 30 ]; then echo "What an oldy." fi

Иногда могут быть и круглыми!

if (( age > 30 )); then echo "Hey, 30 is the new 20, right?" fi

И временами их вообще не будет!

if is_upper "$1"; then echo "Stop shouting at me." fi

Как знать, какие именно скобки нужно использовать? Когда каждый из вариантов является подходящим? Почему какие-то из них не будут работать в определенных случаях?

Что происходит на самом деле

Есть магические слова, которые стоят за работой if в Bash: коды выхода. Вот шаблон того, что происходит на самом деле:

if ANY_COMMAND_YOU_WANT_AT_ALL; then # . stuff to do fi

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

Читайте также:  Установка настройка postgresql linux

Но, погодите, это означает, что…

Ага. «[» это команда. Это, собственно, синтаксический сахар для встроенной команды test , которая проверяет и сравнивает переданные ей аргументы. «]» это на самом деле аргумент для команды [ , который говорит ей прекратить проверять аргументы!

if [ "$price" -lt 10 ]; then echo "What a deal!" fi

В этом примере команда [ принимает в качестве аргументов «$price» (переменная сразу же заменяется ее значением), -lt , 10 и ] .

Теперь, с учетом того что -lt , -gt и похожие числовые сравнения на самом деле являются аргументами, не кажется ли странный синтаксис немного более осмысленным? Они выглядят, как опции! Вот почему знаки > и < странно себя ведут внутри одинарных квадратных скобок: Bash думает, что вы пытаетесь перенаправить input или output внутри команды!

Как насчет двойных квадратных скобок?

Довольно странно, однако [[ двойные квадратные скобки ]] и (( двойные круглые скобки )) это не совсем команды. Они представляют собой ключевые слова языка Bash, в результате чего они ведут себя немного более предсказуемо. Тем не менее, в зависимости от своего содержимого, они по-прежнему возвращают код выхода.

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

А двойные круглые скобки?

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

count=0 (( count++ )) echo "$count" # => 1 (( count += 4 )) echo "$count" # => 5

Чего вы не видите, это того, что круглые скобки тоже при каждом запуске возвращают код выхода. Если результат в скобках равен нулю, возвращается код выхода 1 (по сути, нулевой результат это «ложь»). Любой другой результат считается истиной, при нем код выхода будет 0. Вот пример:

if (( -57 + 30 + 27 )); then echo "First one" elif (( 2 + 2 )); then echo "Second one" else echo "Third one" fi # => "Second one"

К счастью для нас, знаки «больше» и «меньше» внутри круглых скобок работают прекрасно. Если сравнение истинно, результат будет 1. В противном случае – 0.

if (( 5 > 3 )); then echo "Numbers make sense." elif (( 3 "Numbers make sense"

У этой функциональности есть странный, но любопытный побочный эффект:

echo $(( (5 > 3) + (0 == 0) )) # => 2 # Each comparison is true, so we're effectively echoing # 1 + 1. Fun, right?

Использование условных предложений с if в bash

Использование команд вместо скобок

Чаще всего в ваших if-предложениях будут использоваться скобки. Однако, поскольку можно использовать команды и их коды выхода, за вашими if-ами будет стоять вся мощь командной строки.

Читайте также:  Low memory mode kali linux

Скажем, мы хотим сделать что-то, но только в том случае, если в файле найдена определенная строка. Какую команду вы будете использовать для поиска текста в файлах? Grep!

echo "Hello, welcome to bean house." >> dialogue.txt echo "Would you like some coffee?" >> dialogue.txt if grep -q coffee dialogue.txt; then echo "Found coffee, boss." else echo "No coffee." fi # => "Found coffee, boss."

Если grep находит искомое, код выхода будет 0 (успех). Если нет, – 1. Мы используем это для запуска нашего if-предложения! Опция -q в grep означает —quiet . Она запрещает вывод найденных строк. Если мы ее уберем, то наш вывод будет выглядеть так:

Would you like some coffee? Found coffee, boss.

Использование ваших собственных функций

Самое лучшее в этом всем то, что вы можете написать собственные функции! Это поможет вам инкапсулировать вашу логику в нечто с высокоуровневым именем. Благодаря этому ваши скрипты станут более читаемыми, а ваши намерения – более понятными. И если есть что-то, где мы можем для примера использовать эту дополнительную ясность, это «выбрасывающий» скрипт, который Джерри написал в прошлом году и который мы до сих пор используем в сборочном конвейере.

Мне стоит написать отдельный пост о функциях в Bash, потому что они прекрасны и я их обожаю. А сейчас лишь отмечу, что эти функции работают как маленькие отдельные скрипты. Любые переданные им аргументы могут назначаться позиционно с помощью особых переменных $1 , $2 , $3 и т. д. Число аргументов содержится в переменной $# .

Обратите внимание на использование return вместо exit. Смысл тот же самый, за исключением того, что exit «убивает» весь скрипт, а не просто завершает функцию. Данная функция может использоваться вот так:

function is_number < if [[ "$1" =~ ^[[:digit:]]+$ ]]; then return 0 else return 1 fi >age="$1" if ! is_number "$age"; then echo "Usage: dog_age NUMBER" exit 1 fi

Видите, как намерение программиста и логика становятся яснее без реализации деталей и написания громоздких регулярных выражений? Функции в Bash это Хорошо.

Фактически, если функция не возвращает (return) значение недвусмысленно, это возвращаемое значение последней команды в функции используется неявно, поэтому функцию можно сократить:

Если регулярное выражение сработает, код возврата двойных квадратных скобок будет нулевым, и таким образом функция возвращает 0. Если нет, и то, и другое возвращает 1. Это отличный способ давать имена регулярным выражениям.

If – это хорошая вещь

Вот и все! Применяйте полученные знания для чистки своих скриптов. Если у вас есть примеры использования if-предложений в Bash, которые могут быть полезны и другим людям, – поделитесь в комментариях!

Источник

Оцените статью
Adblock
detector