Оболочка допустимых символов имени функции

13

Использование расширенных символов Юникода (без сомнения) полезно для многих пользователей.

Простые оболочки (ash (busybox), dash) и ksh не работают с:

tést() { echo 34; }

tést

Но , , и кажется, позволяют это.

Мне известно, что действительные имена функций POSIX используют это определение имен . Это означает, что это регулярное выражение:

[a-zA-Z_][a-zA-Z0-9_]*

Однако в первой ссылке также сказано:

Реализация может разрешить другие символы в имени функции в качестве расширения.

Вопросы:

  • Это принято и задокументировано?
  • Где?
  • Для каких снарядов (если есть)?

Вопросы по теме:
Можно ли использовать специальные символы в имени функции оболочки?
Меня не интересует использование метасимволов (>) в именах функций.

Имена функций upstart и bash, содержащие «-».
Я не верю, что оператор (вычитание «-») должен быть частью имени.

Сообщество
источник
Вы можете найти aliasнемного более снисходительным. и, таким образом, вы можете написать функцию с некоторым правильным, застегнутым именем, а затем просто определить псевдоним с более стильным именем для вызова функции. в dashесть также некоторые вещи вы можете сделать с $PATHи %func.
mikeserv

Ответы:

16

Поскольку документация POSIX допускает его как расширение, ничто не мешает реализации такого поведения.

Простая проверка (побежал zsh):

$ for shell in /bin/*sh 'busybox sh'; do
    printf '[%s]\n' $shell
    $=shell -c 'á() { :; }'
  done
[/bin/ash]
/bin/ash: 1: Syntax error: Bad function name
[/bin/bash]
[/bin/dash]
/bin/dash: 1: Syntax error: Bad function name
[/bin/ksh]
[/bin/lksh]
[/bin/mksh]
[/bin/pdksh]
[/bin/posh]
/bin/posh: á: invalid function name
[/bin/yash]
[/bin/zsh]
[busybox sh]
sh: syntax error: bad function name

показывают , что bash, zsh, yash, ksh93(что kshсвязано в моей системе), pdkshи его вывод позволяет Многобайтовыестроки символов в качестве имени функции.

yash с самого начала поддерживает многобайтовые символы , поэтому неудивительно, что это сработало.

Другая документация, на которую вы можете ссылаться ksh93:

Пробел - это табуляция или пробел. Идентификатор - это последовательность букв, цифр или подчеркиваний, начинающаяся с буквы или подчеркивания. Идентификаторы используются в качестве компонентов имен переменных. Vname - это последовательность из одного или нескольких идентификаторов, разделенных символом. и, необязательно, перед. Vnames используются как имена функций и переменных. Слово - это последовательность символов из набора символов, определенного текущей локалью , за исключением метасимволов без кавычек.

Итак, установка на Cлокаль:

$ export LC_ALL=C
$ á() { echo 1; }
ksh: á: invalid function name

сделать это не удалось.

cuonglm
источник
poshне стоит быть перечисленным в таком списке. Это зависит от конкретных ошибок в Linux libcи не будет работать на других платформах.
Шили
Я не могу повторить ваши претензии по поводу ksh93использования самостоятельно скомпилированного ksh93 из оригинальных источников. Хотя ksh88кажется, что для имен функций принимаются не-7-битные буквы ASCII, только ksh93двоичный файл из Ubuntu, похоже, принимает их.
18:00
@schily ksh Я использовал в этом тесте двоичный файл в Debian (поэтому он может быть таким же, как и в Ubuntu)
cuonglm
9

Обратите внимание, что функции используют то же пространство имен, что и другие команды, включая команды в файловой системе, которые в большинстве систем не имеют ограничений на символы или даже байты, которые они могут содержать в своем пути.

Таким образом, хотя большинство оболочек ограничивают символы своих функций, нет реальной причины, по которой они это делают. Это означает, что в этих оболочках есть команды, которые нельзя заменить на функцию.

zshи rcразрешить что-нибудь для их имен функций, включая некоторые с /и пустую строку. zshдаже позволяет NUL байтов.

$ zsh
$ $'\0'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test

Простая команда в оболочке представляет собой список аргументов, и первый аргумент используется для получения команды для выполнения. Поэтому логично, что эти аргументы и имена функций имеют одинаковые возможные значения, а в zshаргументах встроенных функций и функций может быть любая последовательность байтов.

Здесь нет проблемы безопасности, так как функции, которые вы (автор сценария) определяете, являются теми, которые вы вызываете.

Возможны проблемы с безопасностью, когда на синтаксический анализ влияет среда, например, в оболочках, где действительные имена для функций зависят от локали.

Стефан Шазелас
источник
Можно играть в игры в Баш тоже, начиная с function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }, и потенциально полезные вещи тоже с функциями имени --, //, @или и %т.д.
mr.spuratic
но разве оболочки не обходят поиск в хеш-таблицах, когда /встречаются в имени? и функция не просто имя исполняемого файла - ее код. Я думаю, что простая реализация может столкнуться с множеством проблем разбора, если имена ее хранимых функций включают метасимволы.
mikeserv
Да, я знаю о неспособности bash содержать нулевые значения в vars, которые могут быть разумно распространены на имена функций. У меня нет конкретного примера, но я чувствую, что игры, допускающие почти все для имен, являются скорее потенциальным нарушением безопасности, чем «простым способом работы». Я надеюсь, что я не прав.