проверка аргумента для сценария bash – это строка из всех цифр

Часто задаваемые вопросы по Bash

Если вы проверяете простую «строку цифр», вы можете сделать это с помощью glob:

# Bash if [[ $foo = *[!0-9]* ]]; then echo "'$foo' has a non-digit somewhere in it" else echo "'$foo' is strictly numeric" fi 

Я подумал: «Хорошо, это выглядит красиво и просто». Затем я ввел именно это в скрипт, за исключением того, что я добавил «exit 1» после первого эха и изменил $foo на $1 , так что это выглядело так:

 if [[ $1 = *[!0-9]* ]]; then echo "'$1' has a non-digit somewhere in it" exit 1 else echo "'$1' is strictly numeric" fi 

Затем я попытался запустить это и получил

 $ sh foo.sh bar bar foo.sh: 6: [[: not found 'bar' is strictly numeric 

Я безграмотен, я стыжусь сказать, поэтому я понятия не имею, что здесь может быть неправильным. У меня сложилось впечатление, что при поддержке онлайн-руководства Bash оператор для сопоставления с регулярными выражениями =~ , но изменение этого не имеет никакого значения. И что [[ оператор, который кажется проблематичным, выглядит стандартно, хотя я не знаю, какая разница между [[ ]] и [ ] , что соответствует тестированию выражения, насколько я знаю. Я использую сжатие Debian с bash

 $ bash --version GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu) 

Debian говорит версию 4.1-3 .

3 Solutions collect form web for “проверка аргумента для сценария bash – это строка из всех цифр”

Почему вы называете sh , если это сценарий bash? Понятно, что в вашей системе sh не bash, а какая-то другая оболочка семейства Bourne / POSIX. Фактически, это тире , меньшая оболочка, предназначенная для низкого потребления памяти и скорости, которая в значительной степени поддерживает только конструкции POSIX и встроенные утилиты.

[[ … ]] является расширением ksh для синтаксиса Bourne, который был выбран bash и zsh, но не POSIX. В переносном сценарии вам нужно использовать [ … ] для тестов. Стандартная конструкция не поддерживает привязку шаблонов; стандартная идиома – использовать конструкцию case :

 case $1 in # branch to the first pattern that $1 matches *[!0-9]*) # pattern = anything containing a non-digit echo not a number # do this if the first pattern triggered ;; # end of this case branch *) # pattern = anything (else) echo successor of $(($1-1)) # do this if the second pattern triggered ;; # end of this case branch esac # end of the case construct 

Вот функция, которая проверяет, является ли ее аргумент целыми цифрами:

 is_all_digits () { case $1 in *[!0-9]*) false;; esac } 

Отступление : я изначально сделал опечатку в фрагменте выше: я написал $(($0-1)) . Это вызвало появление нечетных сообщений об ошибках:

 $ ash foo.sh 42 foo.sh: 4: arithmetic expression: expecting EOF: "foo.sh-1" $ ash ./foo.sh 42 ./foo.sh: 4: arithmetic expression: expecting primary: "./foo.sh-1" $ ksh ./foo.sh 42 ./foo.sh: line 3: foo.sh: invalid variable name $ pdksh ./foo.sh 42 ./foo.sh[4]: ./foo.sh-1: unexpected `.' $ bash foo.sh 42 foo.sh: line 3: foo.sh-1: syntax error: invalid arithmetic operator (error token is ".sh-1") $ bash ./foo.sh 42 ./foo.sh: line 3: ./foo.sh-1: syntax error: operand expected (error token is "./foo.sh-1") $ zsh foo.sh 42 foo.sh:3: bad floating point constant 

$0 – это имя скрипта, поэтому арифметическое выражение, которое должно быть оценено, было foo.sh-1 или ./foo.sh-1 . Вы можете наблюдать разнообразие сообщений об ошибках среди оболочек. Я был немного удивлен, увидев, что сообщения пепла и сообщение ./ без ./ были самыми ясными: ни одна из других оболочек не упоминает, что проблема заключается в арифметическом выражении. Ash и pdksh получают стыковочные точки за сообщение об ошибке на одну строку слишком далеко.

Попробуйте запустить его с bash foo.sh bar Если вы собираетесь писать сценарий bash, вам нужно использовать bash. Используемые выше [[и]] находятся только в bash, который является производной оболочки Bourne. sh означает Bourne Shell и может отличаться от bash. Я думаю, что debian использует тире для sh. Если вы хотите узнать, как писать переносные сценарии оболочки Bourne, которые не требуют специальных функций bash, вы можете переписать это вместо использования grep:

 if echo "$foo" | grep '^[0-9][0-9]*$' >/dev/null 2>&1; then echo "'$1' has a non-digit somewhere in it" exit 1 else echo "'$1' is strictly numeric" fi 

Я предлагаю использовать expr потому что он совместим с POSIX:

 if [ "$(expr "$1" : '^[0-9]\+$')" = "0" ]; then echo "'$1' has a non-digit somewhere in it" exit 1 else echo "'$1' is strictly numeric" fi 
  • Как найти имена файлов / каталогов, которые являются одинаковыми, но с разной капитализацией / случаем?
  • Замена команд с помощью pkg-config в Fish
  • Выполнение сценария оболочки на нескольких серверах
  • $ PATH на Fish Shell OS X
  • Изменить шрифт в команде echo
  • Как я могу распечатать полное объявление функции любой функции, которая содержит в себе определенную строку?
  • Как разбить файл, например split на stdout, для подключения к команде?
  • Ошибка ./c.sh: строка 24: [: слишком много аргументов в программе оболочки
  • Как изменить рабочий каталог для сценария оболочки
  • Расширение поиска истории в zsh
  • Навигация по истории в режиме Vi оболочки Bash
  • Linux и Unix - лучшая ОС в мире.