Poprawne znaki nazwy funkcji powłoki

13

Korzystanie z rozszerzonych znaków Unicode jest (bez wątpienia) przydatne dla wielu użytkowników.

Prostsze powłoki (ash (busybox), myślnik) i ksh nie działają z:

tést() { echo 34; }

tést

Ale , , i wydają się na to pozwalać.

Wiem, że prawidłowe nazwy funkcji POSIX używają tej definicji nazw . Oznacza to, że wyrażenie regularne:

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

Jednak w pierwszym linku jest również powiedziane:

Implementacja może dopuszczać inne znaki w nazwie funkcji jako rozszerzenie.

Pytania są następujące:

  • Czy jest to akceptowane i dokumentowane?
  • Gdzie?
  • Dla jakich muszli (jeśli istnieją)?

Powiązane pytania: Czy
możliwe jest użycie znaków specjalnych w nazwie funkcji powłoki?
Nie jestem zainteresowany używaniem metaznaków (>) w nazwach funkcji.

Nazwy funkcji upstart i bash zawierające „-”
Nie uważam, że operator (odejmowanie „-”) powinien być częścią nazwy.

Społeczność
źródło
możesz aliasbyć nieco łagodniejszy. a więc możesz napisać funkcję pod jakąś właściwą, zapinaną na guziki nazwą, a następnie po prostu zdefiniować bardziej stylowy alias do wywołania funkcji. w dashtam również pewne rzeczy można zrobić z $PATHi %func.
mikeserv

Odpowiedzi:

16

Ponieważ dokumentacja POSIX zezwala na to jako rozszerzenie, nic nie stoi na przeszkodzie implementacji tego zachowania.

Prosta kontrola (uruchomiona 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

pokazują, że bash, zsh, yash, ksh93(co kshwiąże się w moim systemie), pdksha jego pochodzenie pozwalają multi-bajty znaków jako nazwa funkcji.

yash jest przeznaczony do obsługi znaków wielobajtowych od samego początku, więc nic dziwnego, że zadziałał.

Inna dokumentacja, do której możesz się odwołać, to ksh93:

Puste miejsce to tabulator lub spacja. Identyfikator to ciąg liter, cyfr lub znaków rozpoczynających się od litery lub znaku podkreślenia. Identyfikatory są używane jako składniki nazw zmiennych. Vname jest sekwencją jednego lub więcej identyfikatorów oddzielonych przez. i opcjonalnie poprzedzone znakiem .. Nazwy są używane jako nazwy funkcji i zmiennych. Słowo jest sekwencją znaków z zestawu znaków zdefiniowanego przez bieżące ustawienia narodowe , z wyłączeniem niecytowanych metaznaków.

Więc ustawienie Cregionalne:

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

sprawić, że się nie uda.

Cuonglm
źródło
poshnie warto być wymienionym na takiej liście. To zależy od błędów specyficznych dla Linuksa libci nie będzie działać na innych platformach.
schily
Nie mogę powtórzyć twoich twierdzeń na temat ksh93korzystania z samodzielnie skompilowanego ksh93 z oryginalnych źródeł. Chociaż ksh88wydaje się akceptować litery nie 7-bitowe ASCII dla nazw funkcji, ksh93wydaje się , że tylko pliki binarne z Ubuntu je akceptują.
schily
@schily ksh, którego użyłem w tym teście, to plik binarny w Debianie (więc może być taki sam jak jeden na Ubuntu)
cuonglm
9

Zauważ, że funkcje mają tę samą przestrzeń nazw, co inne polecenia, w tym polecenia w systemie plików, które w większości systemów nie mają ograniczeń co do znaków, a nawet bajtów, które mogą zawierać na swojej ścieżce.

Tak więc, chociaż większość powłok ogranicza znaki swoich funkcji, nie ma naprawdę dobrego powodu, aby to zrobić. Oznacza to, że w tych powłokach są polecenia, których nie można zastąpić funkcją.

zshi rczezwalaj na dowolne nazwy funkcji, w tym niektóre z /i pusty ciąg znaków. zshpozwala nawet na bajty NUL.

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

Proste polecenie w powłoce to lista argumentów, a pierwszy argument służy do wyprowadzenia polecenia do wykonania. Logiczne jest więc, że te argumenty i nazwy funkcji mają te same możliwe wartości, a zshargumenty wbudowanych funkcji mogą mieć dowolną sekwencję bajtów.

Nie ma problemu dotyczącego zabezpieczeń tutaj jako funkcji wy (autor skryptu) są te definiują Państwo wywoływać.

Mogą występować problemy z bezpieczeństwem, gdy środowisko ma wpływ na analizowanie, na przykład w powłokach, w których ustawienia regionalne mają wpływ na prawidłowe nazwy funkcji.

Stéphane Chazelas
źródło
Można grać w bash zbyt, zaczynając function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }i potencjalnie przydatnych rzeczy też z funkcji o nazwie --, //, @lub %itd.
mr.spuratic
ale czy powłoki nie mają tendencji do omijania wyszukiwania tablicy skrótów, gdy /znajduje się w nazwie? a funkcja to nie tylko nazwa wykonywalna - jej kod. pomyślałbym, że prosta implementacja może napotkać wiele problemów z analizą, jeśli jej nazwy funkcji składowanych zawierają metaznaki.
mikeserv
Tak, zdaję sobie sprawę z niemożności basha do przechowywania wartości null w zmiennych, które można rozsądnie rozszerzyć na nazwy funkcji. Nie mam konkretnego przykładu, ale uważam, że ta gra polegająca na przyznawaniu prawie wszystkiego dla nazwisk jest bardziej potencjalnym naruszeniem bezpieczeństwa niż „łatwym sposobem pracy”. Mam nadzieję, że się mylę.