базовое имя, используемое в подоболочке, возвращает команду, не найденную

При запуске этого скрипта:

#!/bin/sh -ex

if [[ $# -ne 1 ]]; then
  echo "./import-public-ssh-key.sh <absolute path to public key>"
  exit 1;
fi

PATH=$1
KEY=$(basename ${PATH})

Я получил:

./import-public-ssh-key.sh: line 9: basename: command not found

без подоболочки basename работает:

$ basename /Users/mles/.ssh/id_rsa.pub
id_rsa.pub

Почему basename не работает в подоболочке? Я на Mac, если это актуально.


person mles    schedule 29.12.2018    source источник
comment
PATH имеет особое значение. Вот почему вы должны использовать имена в нижнем регистре для своих собственных переменных, чтобы избежать перезаписи тех, которые по ошибке изменяют поведение оболочки или ОС. То есть: path=$1 не будет рисковать никакими проблемами.   -  person Charles Duffy    schedule 29.12.2018
comment
...см. pubs.opengroup.org/onlinepubs/9699919799/basedefs/, четвертый абзац, где это соглашение закреплено в POSIX.   -  person Charles Duffy    schedule 29.12.2018
comment
Кстати, sh -e... спорный вопрос; он легко может вызвать больше ошибок, чем предотвратить, в том числе странным образом зависящих от контекста, которые ускользают от простых попыток тестирования. См. упражнения в BashFAQ #105 и список несовместимостей между различными реализациями на in-ulm.de/~mascheck/various/set-e прежде чем принять решение об его использовании.   -  person Charles Duffy    schedule 29.12.2018
comment
(Кроме того, если вы хотите написать сценарий bash — как следует из использования тега bash здесь — а не сценарий sh, используйте #!/bin/bash, а не #!/bin/sh, как ваш шебанг; использование sh шебанга не гарантирует, что у вас будут доступны какие-либо языковые функции, кроме тех, которые указаны в спецификации языка оболочки POSIX).   -  person Charles Duffy    schedule 29.12.2018
comment
(Кроме того — и это мой последний комментарий, я обещаю — вы можете завести привычку запускать свой код через shellcheck.net; в этом случае он мог бы сказать вам, что вам нужно заключить расширение в кавычки в аргументе, который вы передаете basename -- таким образом, key=$(basename "$path") -- для правильной работы с путями, содержащими пробелы, или когда IFS иначе set, чтобы содержать символы, которые могут существовать внутри ваших имен файлов; фигурные скобки здесь не имеют никакого значения, так или иначе, но кавычки предотвращают разделение строк и расширение универсальных объектов).   -  person Charles Duffy    schedule 29.12.2018
comment
@CharlesDuffy: строчная буква path имеет особое значение в C-shell, но я думаю, что мы не будем опускаться так низко.   -  person cdarke    schedule 29.12.2018
comment
... да, zsh иногда нарушает спецификацию и в этом отношении, но... ну, ни csh, ни zsh не претендуют на то, чтобы быть POSIX-совместимыми оболочками.   -  person Charles Duffy    schedule 29.12.2018


Ответы (1)


Вы сбрасываете ПУТЬ. Не делай этого. Оболочка ищет все каталоги, перечисленные в PATH, и вы изменили его так, что PATH больше не содержит каталог, содержащий базовое имя.

person William Pursell    schedule 29.12.2018
comment
Отвечаете на часто задаваемые вопросы? Тск, тск. - person Charles Duffy; 29.12.2018
comment
хорошо, это было очень плохое имя для переменной: P, спасибо за подсказку - person mles; 29.12.2018