Rozważ następujące:
$ ksh -c '1(){ echo hi;};1'
ksh: 1: invalid function name
$ dash -c '1(){ echo hi;};1'
dash: 1: Syntax error: Bad function name
$ bash -c '1(){ echo hi;};1'
bash: `1': not a valid identifier
bash: 1: command not found
$ mksh -c '1(){ echo hi;};1'
hi
Zasadniczo, starałem się deklarować funkcje 1
i 0
co byłoby dla shorthands true
a false
, ale jak widać wpadłem na problem z użyciem nazwy numeryczne funkcje. To samo zachowanie występuje w przypadku aliasów i dwucyfrowych nazw.
Pytanie brzmi „dlaczego”? Czy jest to wymagane przez POSIX? czy po prostu dziwactwo muszli przypominających bourne?
Zobacz także powiązane pytanie z tym.
command-line
bash
dash-shell
ksh
Sergiy Kolodyazhnyy
źródło
źródło
0
jesttrue
w skryptach powłoki i1
jestfalse
(tak naprawdę każdy niezerowy traktowany jest jako fałsz), na wypadek, gdyby ktoś czytający to nie był świadomy. Jest to odwrotnie niż w przypadku większości innych języków programowania.true
w powłoce. Jednak w interpretacji arytmetycznej$((...))
odwracane są statusy powrotu - 1 oznacza,true
a 0 oznaczafalse
spójność ze składnią języka C. Spróbuj na przykładbash -c 'echo $((1==1));echo $((1==2))'
To, co próbowałem zrobić poza tym pytaniem, było w rzeczywistości „odwróceniem” zachowania. Zobacz ostatni przykład mojej odpowiedzi tutaj, aby zobaczyć, co dokładnie próbowałem zrobić. Głupi pomysł, ale mimo to działaOdpowiedzi:
POSIX mówi:
I:
Zatem słowo zaczynające się od cyfry nie może być nazwą funkcji.
źródło
1L
znaczyło? Nazwa funkcji? Czylong int
dosłownie?()
, być może wraz z argumentami w środku, co oznacza wywołanie danej funkcji (i przyjmuje wartość zwracaną przez wywoływaną funkcję). Więc jeśli masz funkcjęint f() { return 42; }
w C,f
jest poprawna w kontekście wskaźnika if()
jest poprawna w kontekście innym niż wskaźnik, liczba całkowita.Jest to standard w wielu językach, aby zapobiec pomyłkom między operacjami matematycznymi a zmiennymi, funkcjami lub metodami.
Rozważać:
Jak widać, jeśli liczby byłyby dozwolone jako nazwy zmiennych lub funkcji, późniejsze wykonywanie matematyki w programie mogłoby stać się bardzo mylące i musiałbyś wymyślić twórcze obejścia, gdybyś musiał później zrobić matematykę z tymi liczbami. Może również powodować nieoczekiwane wyniki w niektórych językach. Wyobraź sobie, że zwiększasz liczbę dla pętli, ale jedna z cyfr jest już zmienną równą łańcuchowi. Natychmiast rzuciłby błąd. Jeśli nie jesteś oryginalnym autorem kodu, znalezienie błędu może zająć sporo czasu.
W skrócie, dlatego większość języków nie pozwala na użycie liczby jako nazwy zmiennej, funkcji, metody itp.
źródło
$
rozszerzenie”, ale z drugiej strony, jeśli powłoka jest inspirowana innymi językami, to chyba tak, a poza tym arytmetyczne((
zmienne rozszerzenia nie muszą mieć wiodącej pozycji$
. OK, rozumiem to$
, więc jest to. Ale to prawdopodobnie drugorzędne w stosunku do innego powodu „po prostu przestrzegania wspólnej konwencji”0
nazwy powłoki lub skryptu1
,2
, ..., dla parametrów pozycyjnych,*
dla nich dołączył,-
do włączonych opcji,?
za ostatni stan wyjścia, a!
dla najnowszy PID zadania asynchronicznego. (Tak więc, nawet w$((
))
The$
często jest potrzebne.) Kod pokazany tutaj wykazać sugerowanego uzasadnienie nie jest skryptem powłoki Bourne'a dla każdego stylu, ponieważ nie ma sposobu, aby wykazać to w ten sposób, jak to nie ma zastosowania do im.W C rozważmy wyrażenie takie jak:
Czy
1000l
zmienna czy stała? Ponieważ nazwy zmiennych nie mogą zaczynać się cyfrą, musi być stała. To sprawia, że parsowanie jest łatwiejsze i bardziej rygorystyczne (literówki1000k
można łatwo złapać). Łatwiej jest też mieć jedną regułę dla zmiennych i nazw funkcji, ponieważ funkcje można również traktować jak zmienne. Teraz, oczywiście, parsery są znacznie bardziej złożone i wydajne, a my mamy takie rzeczy jak niestandardowe literały w C ++. Ale w dawnych czasach prehistorii poświęcenie odrobiny niepotrzebnej elastyczności może znacznie skrócić czas kompilacji (lub interpretacji) (a ludzie nadal narzekają na czasy kompilacji w C ++).I możesz zobaczyć efekty wpływu C w całym języku powłoki, więc nie jest zaskakujące, że powłoka Bourne'a (lub powłoka C), a zatem POSIX, ograniczyła klasę dozwolonych nazw do tego samego co klasa C.
źródło
&&
i||
brak wsparcia dla ASCII nul w ciągach,