Проверка параметров для сценария Bash
Я придумал базовый, чтобы помочь автоматизировать процесс удаления ряда папок, поскольку они становятся ненужными.
#!/bin/bash
rm -rf ~/myfolder1//anotherfolder
rm -rf ~/myfolder2//yetanotherfolder
rm -rf ~/myfolder3//thisisafolder
это вызывается так:
./myscript.sh <{id-number}>
проблема в том, что если вы забыли введите id-number
(как я сделал), то он может удалить много вещей, которые вы не хотели удалять.
есть ли способ добавить любую форму проверки в командную строку параметры? в моем случае было бы хорошо проверить, что a) есть один параметр, b) он числовой, и c) Эта папка существует; прежде чем продолжить сценарий.
9 ответов:
#!/bin/sh die () { echo >&2 "$@" exit 1 } [ "$#" -eq 1 ] || die "1 argument required, $# provided" echo | grep -E -q '^[0-9]+$' || die "Numeric argument required, provided" while read dir do [ -d "$dir" ] || die "Directory $dir does not exist" rm -rf "$dir" done <<EOF ~/myfolder1//anotherfolder ~/myfolder2//yetanotherfolder ~/myfolder3//thisisafolder EOF
edit: я пропустил часть о проверке, существуют ли каталоги сначала, поэтому я добавил Это, завершив скрипт. Кроме того, были рассмотрены вопросы, поднятые в комментариях; исправлено регулярное выражение, переключенное с
==
toeq
.это должен быть портативный, совместимый с POSIX скрипт, насколько я могу судить; он не использует никаких башизмов, что на самом деле важно, потому что
/bin/sh
на Ubuntu на самом делеdash
в эти дни, неbash
.
The
sh
решениеBrian Campbell
, в то время как благородный и хорошо выполненный, имеет несколько проблем, поэтому я подумал, что предоставлю свой собственныйbash
решение.проблемы с
sh
первый:
- Тильда в
~/foo
не распространяется на ваш homedirectory внутри heredocs. И ни тогда, когда его читаетread
заявление или цитата вrm
заявление. Что означает, что вы получитеNo such file or directory
ошибки.- разветвление от
grep
и такие для основных операции-это безумие. Особенно, когда вы используете дерьмовую оболочку, чтобы избежать "тяжелого" веса bash.- я также заметил несколько проблем с цитированием, например, вокруг расширения параметра в его
echo
.- в то время как редко, решение не может справиться с именами файлов, которые содержат новые строки. (Почти нет решения в
sh
может с ними справиться - именно поэтому я почти всегда предпочитаюbash
, это гораздо более пуленепробиваемый и труднее использовать при использовании ну.)в то время как, да, используя
/bin/sh
для вашего hashbang означает, что вы должны избегатьbash
isms любой ценой, вы можете использовать всеbash
измы вам нравятся, даже на Убунуту или еще что-то, когда вы честны и ставите#!/bin/bash
в верхней части.так вот
bash
решение, которое меньше, чище, прозрачнее, вероятно, "быстрее" и более пуленепробиваемое.[[ -d && != *[^0-9]* ]] || { echo "Invalid input." >&2; exit 1; } rm -rf ~/foo/""/bar ...
- обратите внимание на кавычки
на
rm
заявление!- The
-d
проверка также не удастся, еслипусто, так что это две проверки в одном.
- я избегал регулярных выражений по какой-то причине. Если вы должны использовать
=~
в bash вы должны поместить регулярное выражение в переменную. В любом случае, такие глобусы, как мой, всегда предпочтительны и поддерживаются в гораздо большем количестве версий bash.
Я бы использовал Баш
[[
:if [[ ! ("$#" == 1 && =~ ^[0-9]+$ && -d ) ]]; then echo 'Please pass a number that corresponds to a directory' exit 1 fi
нашел этот faq чтобы быть хорошим источником информации.
Не такой пуленепробиваемый, как приведенный выше ответ, однако все еще эффективный:
#!/bin/bash if [ "" = "" ] then echo "Usage: <id number to be cleaned up>" exit fi # rm commands go here
использовать
set -u
что приведет к тому, что любая ссылка на незаданный аргумент немедленно завершит работу скрипта.http://www.davidpashley.com/articles/writing-robust-shell-scripts.html
использовать '-З' для проверки на пустые строки и '-D, чтобы проверить по справочникам.
if [[ -z "$@" ]]; then echo >&2 "You must supply an argument!" exit 1 elif [[ ! -d "$@" ]]; then echo >&2 "$@ is not a valid directory!" exit 1 fi
man-страница для теста (
man test
) предоставляет все доступные операторы, которые можно использовать в качестве логических операторов в bash. Используйте эти флаги в начале вашего скрипта (или функций) для проверки ввода так же, как и на любом другом языке программирования. Например:if [ -z ] ; then echo "First parameter needed!" && exit 1; fi if [ -z ] ; then echo "Second parameter needed!" && exit 2; fi
вы можете проверить точки A и b компактно, выполнив что-то вроде следующего:
#!/bin/sh MYVAL=$(echo | awk '/^[0-9]+$/') MYVAL=${MYVAL:?"Usage - testparms <number>"} echo ${MYVAL}
что дает нам ...
$ ./testparams.sh Usage - testparms <number> $ ./testparams.sh 1234 1234 $ ./testparams.sh abcd Usage - testparms <number>
этот метод должен отлично работать в sh.
старый пост, но я решил, что могу внести свой вклад в любом случае.
сценарий, возможно, не нужен и с некоторым допуском к диким картам может быть выполнен из командной строки.
дикие везде соответствующие. Позволяет удалить любое появление под "папка"
$ rm -rf ~/*/folder/*
оболочке повторяемых. Позволяет удалить определенные папки pre и post с одним линия
$ rm -rf ~/foo{1,2,3}/folder/{ab,cd,ef}
оболочка повторяется + var (bash tested).
$ var=bar rm -rf ~/foo{1,2,3}/${var}/{ab,cd,ef}