Дійсні символи оболонки оболонки


13

Використання розширених символів Unicode (без сумніву) корисно для багатьох користувачів.

Простіші оболонки (зола (зайнятий ящик), тире) та кш не виходять із:

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 - це послідовність одного або декількох ідентифікаторів, розділених a. і необов'язково передує .. Імена використовуються як імена функцій та змінних. Слово - це послідовність символів із набору символів, визначених поточним локалом , за винятком нецитованих метахарактерів.

Отже, налаштування для Cлокалізації:

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

зробити це не вдалося.


poshНе варто вказуватись у такому списку. Це залежить від конкретних помилок Linux libcі не працюватиме на інших платформах.
schily

Я не можу повторити ваші претензії щодо ksh93використання самостійно складеного ksh93 з оригінальних джерел. Хоча, ksh88здається, приймає не 7-бітові ASCII букви для імен функцій, але лише ksh93двійковий файл Ubuntu, схоже, приймає їх.
schily

@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

але оболонки Dont мають тенденцію обходити пошук хеш-таблиці, коли /вони знайдені в імені? а функція не просто ім'я, яке виконується - його код. Я думаю, що проста реалізація може зіткнутися з безліччю проблем розбору, якщо її збережені назви функцій включатимуть метахарактеристики.
mikeserv

Так, я знаю про нездатність bash містити нулі в vars, що може бути розумно розширено до імен функцій. Я не маю конкретного прикладу, але я вважаю, що такі ігри, що дозволяють отримати майже все для імен, є скоріше потенційним порушенням безпеки, ніж «простим способом роботи». Я сподіваюся, що я помиляюся.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.