Проверка параметров к сценарию Bash

Все переменные, содержащие объекты, такие как списки, по сути являются указателями (придирки могут не согласиться с точной терминологией, но я уверен, что это достаточно близко). Поэтому, когда вы говорите

this.allCustomers = parent.allCustomers

, this.allCustomers и parent.allCustomers теперь указывают на один и тот же объект List. Затем

this.allCustomers.remove(currentCustomer)

запускает .remove () в этом списке ... который является allCustomers родителя ... который в настоящее время перебирается. Поскольку список изменяется, итерация не выполняется.

Чтобы пояснить комментарий, сделанный по этому вопросу, «Java на 100% передается по значению. Ссылки на объекты передаются по значению». означает, что вы не можете реализовать функцию «swap» из языка C [1] , потому что функция получает копии (значения) указателей / ссылок и не может изменять значения оригиналов, но функция может изменить свойства объекта, указателю / ссылке которого он дан, и сделать эти изменения видимыми для вызывающего абонента, который передал объект, потому что они ссылаются на один и тот же объект. Примитивные типы (int, boolean и т. Д.) Передаются по значению, но они неизменны (можно сказать, x = 3, а затем x = 5, но не существует 3.changeValueTo (5)), поэтому разницу можно в значительной степени игнорировать.

···

[1]: это запрещает использование класса Unsafe, который имеет прямой доступ к памяти. Не используйте это, поскольку это может серьезно сломать вещи. Умным инженерам, которые могут использовать его навсегда (например, иногда его используют внутренние Java-компоненты), в любом случае, мне не понадобится мой совет.

91
задан codeforester 17 February 2017 в 06:10
поделиться

7 ответов

#!/bin/sh
die () {
    echo >&2 "$@"
    exit 1
}

[ "$#" -eq 1 ] || die "1 argument required, $# provided"
echo $1 | grep -E -q '^[0-9]+$' || die "Numeric argument required, $1 provided"

while read dir 
do
    [ -d "$dir" ] || die "Directory $dir does not exist"
    rm -rf "$dir"
done <<EOF
~/myfolder1/$1/anotherfolder 
~/myfolder2/$1/yetanotherfolder 
~/myfolder3/$1/thisisafolder
EOF

править: Я пропустил часть о проверке, если каталоги существуют сначала, таким образом, я включил это, завершив сценарий. Кроме того, решили вопросы, поднятые в комментариях; зафиксированный регулярное выражение, переключенное с == кому: eq.

Это должно быть портативным устройством, POSIX совместимый сценарий насколько я могу сказать; это не использует bashisms, который на самом деле важен потому что /bin/sh на Ubuntu на самом деле dash в эти дни, нет bash.

152
ответ дан Brian Campbell 24 November 2019 в 06:41
поделиться

Я использовал бы удар [[:

if [[ ! ("$#" == 1 && $1 =~ ^[0-9]+$ && -d $1) ]]; then 
    echo 'Please pass a number that corresponds to a directory'
    exit 1
fi

Я нашел, что эти часто задаваемые вопросы были хорошим источником информации.

14
ответ дан Dave 24 November 2019 в 06:41
поделиться

sh решение Brian Campbell, в то время как благородный и хорошо выполняемый, имеет несколько проблем, таким образом, я думал, что обеспечу свое собственное bash решение.

Проблемы с sh один:

  • Тильда в ~/foo не расширяется до Вашего homedirectory внутри heredocs. И ни один, когда это читается read оператор или заключенный в кавычки в rm оператор. Что означает, что Вы доберетесь No such file or directory ошибки.
  • Разветвление прочь grep и такой для основных операций ненормален. Особенно, когда Вы используете дрянную оболочку для предотвращения "тяжелого" веса удара.
  • Я также заметил несколько проблем заключения в кавычки, например, вокруг расширения параметра в его echo.
  • В то время как редкий, решение не может справиться с именами файлов, которые содержат новые строки. (Почти никакое решение в sh может справиться с ними - который является, почему я почти всегда предпочитаю bash, это является намного более пуленепробиваемым и более твердым использовать при использовании хорошо).

В то время как, да, с помощью /bin/sh поскольку Ваш hashbang означает, что необходимо избежать bashизмы любой ценой, можно использовать весь bashизмы, которые Вы любите, даже на Ubuntu или этажерке, когда Вы честны и помещаетесь #!/bin/bash наверху.

Так, вот a bash решение это является меньшим, более чистым, более прозрачным, вероятно, "быстрее", и более пуленепробиваемым.

[[ -d $1 && $1 != *[^0-9]* ]] || { echo "Invalid input." >&2; exit 1; }
rm -rf ~/foo/"$1"/bar ...
  1. Заметьте кавычки вокруг $1 в rm оператор!
  2. -d проверка также перестанет работать если $1 пусто, таким образом, это - две регистрации один.
  3. Я избежал регулярных выражений по причине. Если необходимо использовать =~ в ударе необходимо помещать регулярное выражение в переменную. В любом случае шарики как мои всегда предпочтительны и поддерживаются в намного большем количестве версий удара.
21
ответ дан twernt 24 November 2019 в 06:41
поделиться

Не столь пуленепробиваемый как вышеупомянутый ответ, однако все еще эффективный:

#!/bin/bash
if [ "$1" = "" ]
then
  echo "Usage: $0 <id number to be cleaned up>"
  exit
fi

# rm commands go here
12
ответ дан Boiler Bill 24 November 2019 в 06:41
поделиться

Используйте '-z' для тестирования на пустые строки и '-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
8
ответ дан guns 24 November 2019 в 06:41
поделиться

Страница справочника для теста (man test) обеспечивает все доступные операторы, которые можно использовать в качестве булевых операторов в ударе. Используйте те флаги в начале Вашего сценария (или функции) для контроля ввода точно так же, как Вы были бы на любом другом языке программирования. Например:

if [ -z $1 ] ; then
  echo "First parameter needed!" && exit 1;
fi

if [ -z $2 ] ; then
  echo "Second parameter needed!" && exit 2;
fi
8
ответ дан whaley 24 November 2019 в 06:41
поделиться

Вы можете компактно проверить точки a и b, выполнив что-то вроде следующего:

#!/bin/sh
MYVAL=$(echo ${1} | 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>

Этот метод должен работать нормально в ш.

5
ответ дан 24 November 2019 в 06:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: