Bash распознает аргумент функции как программу

Bash распознает аргумент функции как программу

Я новичок в синтаксисе bash, и у меня есть фрагмент кода в файле '.bash_aliases'. Он получает либо целое число в качестве аргумента, либо букву 'c', когда он получает целое число, он помещает это целое число в переменную окружения, которая может использоваться веб-серверами в качестве порта. Когда он получает букву 'c' в качестве входных данных, он очищает переменную.

Когда я пытаюсь выполнить команду с целым числом, я получаю ошибку

main@linuxWSL:~$ serverp 2000
-bash: [: missing `]'
2000: command not found

и когда я пробую это с буквой «с», я получаю

main@linuxWSL:~$ serverp c
-bash: [: missing `]'
c: command not found

Вот мой bash-код:

serverp () {
  if [ "$1" = "clear" || "$1" = "c" ]
  then
    unset PORT
    echo -e "\e$CLEAR$GREEN""mWebServer port has been reset!""$CLEAN"
    return 0
  fi

  export PORT="$1"
}

Кто-нибудь может мне помочь? Спасибо!

решение1

[не является ключевым словом в Bash, которое заставило бы анализатор оболочки интерпретировать остальную часть командной строки по-другому. [является командой, подобной catили echo. [(подобно echo) является встроенной функцией в Bash, но это означает только то, что ее можно запустить, не порождая дополнительный процесс; она все равно ведет себя как команда.

И для ясности: [ … ]это не часть if … then …синтаксиса. ifПросто проверяет статус завершения некоторого кода: if true; then …допустим, if sleep 5; then …допустим, аналогично if [ … ]; then …допустим (если [ … ]часть сама по себе является допустимой командой).

[Вероятно, в вашей системе есть исполняемый файл. Попробуйте type -a [. Сравните с type -a [[. В отличие от [, [[является ключевым словом в Bash, и оно заставляет синтаксический анализатор обрабатывать вещи между [[и ]]особым образом.

[не является ключевым словом. Правильно написанная [ … ]команда, где ]— это просто последний аргумент. [требует ]в качестве последнего аргумента, иначе она отказывается работать. Это сделано только для того, чтобы [ … ]выделиться в блок, как будто это какой-то особый синтаксис; но это не особый синтаксис.

Ваш [ "$1" = "clear" || "$1" = "c" ]интерпретируется оболочкой как [ "$1" = "clear"и "$1" = "c" ]связан с ||. Таким образом, есть две команды. Первая команда — [ "$1" = "clear", [выполняется, она не получает ]в качестве последнего аргумента, жалуется и завершается с ненулевым статусом выхода. Из-за ненулевого статуса и из-за ||, оболочка пытается выполнить вторую команду, которая начинается с того, что "$1"расширяется до. Таким образом, первый аргумент вашего скрипта интерпретируется как исполняемый файл для запуска.

Исправьте это [ … || … ]так:

[ "$1" = "clear" ] || [ "$1" = "c" ]

Этот фрагмент состоит из двухдействительный [команды. Он должен делать то, что вы хотите.

Примечание [[ "$1" = "clear" || "$1" = "c" ]]— это рабочий фрагмент кода, а [ "$1" = "clear" || "$1" = "c" ]не . Это потому, что , [[это не команда. Это ключевое слово, и оно заставляет парсер оболочки обрабатывать все до ]]по-особенному; это включает ||. Есть и другиеразличия между [[и[, не меняйте их местами вслепую.

Встроенная поддержка [Bash-oили-aдляи), так что это тоже сработает:

[ "$1" = "clear" -o "$1" = "c" ]

Это ваш код, где ||(специальный для оболочки) был заменен на -o(неспециальный для оболочки). -oОднако вам следует избегать. ИзЭта статья:

Двоичные -aи -o[…] являются расширениями XSI стандарта POSIX. Все они помечены как устаревшие в POSIX-2008. Их не следует использовать в новом коде. Одна из практических проблем с [ A = B -a C = D ](or -o) заключается в том, что POSIX не определяет результаты команды testor [с более чем 4 аргументами. Вероятно, это работает в большинстве оболочек, но вы не можете на это рассчитывать. Если вам нужно писать для оболочек POSIX, то вместо этого вам следует использовать две команды testor [, разделенные оператором &&.

Обратите внимание, что статья подробно описывает -a, поэтому " &&оператор вместо". В вашем случае это -oи ||соответственно. Два теста, разделенные оператором, ||— это как раз наше решение.

решение2

Его if [ "$1" = "clear" ] || [ "$1" = "c" ].

Связанный контент