Linux bash проверить параметр

Check existence of input argument in a Bash shell script

You did not tell us how you invoked this script. most likely, the first parameter was not an integral number.

How do I check the input argument1 first to see if it exists? : Do you mean «how do I check whether the argument 1 is non-empty?» or do you mean «how do I check whether the number of arguments is greater than zero?». Please clarify this in your question.

12 Answers 12

if [ $# -eq 0 ] then echo "No arguments supplied" fi 

The $# variable will tell you the number of input arguments the script was passed.

Or you can check if an argument is an empty string or not like:

if [ -z "$1" ] then echo "No argument supplied" fi 

The -z switch will test if the expansion of «$1» is a null string or not. If it is a null string then the body is executed.

I like to do it this way, in terse syntax and still POSIX acceptable. [ -z «$1» ] && echo «No argument supplied» I prefer one-liners, as they are easier for me; and it’s also faster to check exit value, compared to using if

You probably want to add an exit 1 at the end of your echos inside the if block when the argument is required for the script to function. Obvious, but worth noting for completeness.

It is possible, though rarely useful, for the first argument to be initialized but empty; programname «» secondarg third . The $# check unambiguously checks the number of arguments.

For a noob, especially someone who comes from a non-scripting background, it is also important to mention some peculiarities about these things. You could have also mentioned that we need a space after the opening and the closing brace. Otherwise things do not work. I am myself a scripting noob (I come from C background) and found it the hard way. It was only when I decided to copy the entire thing «as is» that things worked for me. It was then I realized I had to leave a space after the opening brace and before the closing one.

Источник

Validating parameters to a Bash script

I came up with a basic one to help automate the process of removing a number of folders as they become unneeded.

#!/bin/bash rm -rf ~/myfolder1/$1/anotherfolder rm -rf ~/myfolder2/$1/yetanotherfolder rm -rf ~/myfolder3/$1/thisisafolder 

The problem is that if you forget to type in the id-number (as I did just then), then it could potentially delete a lot of things that you really don’t want deleted. Is there a way you can add any form of validation to the command line parameters? In my case, it’d be good to check that a) there is one parameter, b) it’s numerical, and c) that folder exists; before continuing with the script.

10 Answers 10

#!/bin/sh die () < echo >&2 "$@" exit 1 > [ "$#" -eq 1 ] || die "1 argument required, $# provided" echo $1 | grep -E -q '^7+$' || die "Numeric argument required, $1 provided" while read dir do [ -d "$dir" ] || die "Directory $dir does not exist" rm -rf "$dir" done  

edit: I missed the part about checking if the directories exist at first, so I added that in, completing the script. Also, have addressed issues raised in comments; fixed the regular expression, switched from == to eq .

This should be a portable, POSIX compliant script as far as I can tell; it doesn't use any bashisms, which is actually important because /bin/sh on Ubuntu is actually dash these days, not bash .

i found two things in my answer that you may also want to fix in yours: first the SO hilighter goes crazy for $# (treating it as a commentar). i did "$#" to fix it. second, the regex also matches "foo123bar". i fixed it by doing ^9+$. you may also fix it by using grep's -x option

@ojblass I was missing one of the tests he was asking about. Adding that in meant also adding in his directories to test against, which significantly expanded the size of the answer since they can't fit on one line. Can you suggest a more compact way of testing for the existence of each directory?

as per @Morten Nielsen's answer-comment below, the grep '$6+^' looks strange indeed. Shouldn't it be '^1+$' ?

Not as bulletproof as the above answer, however still effective:

#!/bin/bash if [ "$1" = "" ] then echo "Usage: $0 " exit fi # rm commands go here 

The sh solution by Brian Campbell , while noble and well executed, has a few problems, so I thought I'd provide my own bash solution.

The problems with the sh one:

  • The tilde in ~/foo doesn't expand to your homedirectory inside heredocs. And neither when it's read by the read statement or quoted in the rm statement. Which means you'll get No such file or directory errors.
  • Forking off grep and such for basic operations is daft. Especially when you're using a crappy shell to avoid the "heavy" weight of bash.
  • I also noticed a few quoting issues, for instance around a parameter expansion in his echo .
  • While rare, the solution cannot cope with filenames that contain newlines. (Almost no solution in sh can cope with them - which is why I almost always prefer bash , it's far more bulletproof & harder to exploit when used well).

While, yes, using /bin/sh for your hashbang means you must avoid bash isms at all costs, you can use all the bash isms you like, even on Ubuntu or whatnot when you're honest and put #!/bin/bash at the top.

So, here's a bash solution that's smaller, cleaner, more transparent, probably "faster", and more bulletproof.

[[ -d $1 && $1 != *[^0-9]* ]] || < echo "Invalid input." >&2; exit 1; > rm -rf ~/foo/"$1"/bar . 
  1. Notice the quotes around $1 in the rm statement!
  2. The -d check will also fail if $1 is empty, so that's two checks in one.
  3. I avoided regular expressions for a reason. If you must use =~ in bash, you should be putting the regular expression in a variable. In any case, globs like mine are always preferable and supported in far more bash versions.

Источник

Аргументы командной строки Bash

Функциональность интерпретатора Bash позволяет работать не только со статистическими данными, записанными в скриптах. Иногда возникает необходимость добавить сценарию интерактивности, позволяя принимать внешние параметры скрипта для манипуляции ими в коде.

В этой статье будет рассмотрено, как принимать аргументы командной строки bash, способы его обработки, проверка опций, а также известные особенности при работе с ними.

Параметры скрипта Bash

Интерпретатор Bash присваивает специальным переменным все параметры, введённые в командной строке. В их состав включено название сценария, выполняемого интерпретатором. Такие переменные называются ещё числовыми переменными, так как в их названии содержится число:

Ниже приведён пример использования одного параметра скрипта Bash:

#!/bin/bash
factorial=1
for (( number = 1; number do
factorial=$[ $factorial * $number ]
done
echo "Факториал числа $1 равен $factorial"

Переменная $1 может использоваться в коде точно так же, как и любая другая. Скрипт автоматически присваивает ей значение из параметра командой строки — пользователю не нужно делать это вручную.

Если необходимо ввести дополнительные параметры, их следует разделить в командной строке пробелами.

#!/bin/bash
total=$[ $1 * $2 ]
echo "Первый параметр равен $1."
echo "Второй параметр равен $2."
echo "Произведение параметров равно $total."

Командный интерпретатор присвоил числа 5 и 10 соответствующим переменным — $1 и $2.

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

#!/bin/bash
echo "Добро пожаловать, $1"

На заметку: кавычки, которые используются при передаче параметров, обозначают начало и конец данных и не являются их частью.

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

#!/bin/bash
total=$[ $ * $ ]
echo "Десятый параметр равен $"
echo "Одиннадцатый параметр равен $"
echo "Произведение этих параметров равно $total"

Получение названия скрипта Bash

Как уже упоминалось, имя сценария является самым первым параметром скрипта. Чтобы определить название программы, используется переменная $0. Такая необходимость возникает, например, при написании скрипта, который может выполнять несколько функций. Однако при этом возникает одна особенность, которую нужно учитывать на практике:

#!/bin/bash
echo "Имя сценария: $0"

Как видно, если строкой, фактически переданной в переменную $0, является весь путь к сценарию, то на вывод будет идти весь путь, а не только название программы.

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

Для этого специально предусмотрена небольшая команда. Команда basename возвращает только название скрипта без абсолютного или относительного пути к нему:

#!/bin/bash
name=`basename $0`
echo "Имя запущенной программы: $name"

Проверка параметров скрипта

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

Если попробовать запустить написанный ранее скрипт test2 без аргументов, то перед выводом команд echo будет отображена ошибка:

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

#!/bin/bash
if [ -n "$1" ]
then
echo "Добро пожаловать, $1"
else
echo "Простите, вы не представились"
fi

В данном случае использовалась опция -n из предыдущей статьи о сравнении строк в Bash для проверки на наличие значения в переменной, которая считала параметр.

Обработка неизветсного числа параметров

Для начала рассмотрим один из часто используемых инструментов при работе с параметрами Bash — команду shift. Её прямое назначение заключается в сдвиге параметров на одну позицию влево. Таким образом, значение из переменной $3 переместится в $2, а из $2 — в $1. Но из $1 значение просто отбросится и не сместится в $0, так как там неизменно хранится название запущенной программы.

Эта команда является эффективным способом обработки всех параметров, переданных сценарию, особенно, когда нельзя заранее узнать их количество. Достаточно лишь обработать $1, сделать сдвиг и повторить процедуру.

#!/bin/bash
count=1
while [ -n "$1" ]
do
echo "Параметр №$count = $1"
count=$[ $count + 1 ]
shift
done

Этот скрипт выполняет цикл while, в условии которого указана проверка первого параметра на длину. И если она равна нулю, цикл прерывает свою работу. При положительном результате проверки команда shift сдвигает все параметры влево на одну позицию.

Ещё один вариант использование shift — смещать на несколько позиций. Для этого достаточно через пробел указать количество, на которое будет смещён ряд параметров скрипта.

#!/bin/bash
echo "Первый параметр из переданных: $1"
shift 2
echo "Теперь первый параметр: $1"

На заметку: при использовании shift нужно быть осторожным, ведь сдвинутые за пределы $1 параметры не восстанавливаются в период работы программы.

Обработка опций в Bash

Помимо параметров скрипт может принимать опции — значения, состоящие из одной буквы, перед которыми пишется дефис. Рассмотрим 3 метода работы с ними в скриптах. Сперва кажется, что при работе с опциями не должно возникать каких-либо сложностей. Они должны быть заданы после имени запускаемой программы, как и параметры. При необходимости можно сделать обработку опций командной строки по такому же принципу, как это делается с параметрами.

По примеру выше можно применять shift для обработки простых опций. С помощью инструкции case можно определять, являются ли аргументы Bash опциями:

#!/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a | -b | -c) echo "Найдена опция $1" ;;
*) echo "$1 не опция" ;;
esac
shift
done

Блок case работает правильно вне зависимости от того, как расположены аргументы командной строки bash.

Выводы

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

Команда basename используется для обрезания пути запущенного сценария, что часто необходимо для создания гибких программ. Использование команды shift позволяет эффективно проходить по переданным скрипту параметрам, особенно когда их количество неизвестно.

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Источник

Читайте также:  Icloud bypass on linux
Оцените статью
Adblock
detector