Czy istnieje kod sh, który nie jest poprawnym składniowo kodem bash?

31

Czy jest jakiś shkod, który nie jest poprawnym składniowo kodem bashowym (nie zapisuje kodu przy składni)?

Mam na myśli nadpisanie shz bashpewnych poleceń.

Alexander Mills
źródło
1
Wydaje mi się, że przez poprawne miałem na myśli poprawną składniowo, więc nie będzie to fałszować składni
Alexander Mills
2
Inny tokenizacja? np. ((przychodzi mi na myśl.
ccorn
1
Dla niektórych dystrybucji /usr/bin/shjest to tylko sym-link do /usr/bin/bash(używam CentOS 7.3 i tak jest). Powinieneś sprawdzić, czy shto naprawdę jest bashdla twojej dystrybucji.
Centimane
1
Kilka lat temu cały mój projekt się zepsuł, gdy coś zostało „ulepszone” w bash. Musiałem zmienić wszystkie linie shebang z #!/bin/shna #!/bin/bash. Potem wszystko znów działało, więc naprawdę musisz być ostrożny. Może się tak zdarzyć, gdy zaczęli używać myślnika zamiast bash dla sh.
Joe
1
@Joe, to jest przeciwieństwo tego, o co prosi OP - miałeś kod bash, który został błędnie oznaczony jako kod sh, ale nie był. OP pyta, czy mogą mieć (rzeczywisty, niepoprawnie oznakowany) kod sh, który pęka, gdy działa z bash, a nie, czy mogą mieć kod bash, który pęka, gdy działa z sh (co jest oczywiste - jeśli rozszerzenia bash nie mają wpływ na dostępne funkcje językowe, nie byłyby rozszerzeniami).
Charles Duffy,

Odpowiedzi:

49

Oto kod, który robi coś innego w POSIX sh i Bash:

hello &> world

Czy to dla ciebie „nieważne”, nie wiem.

W Bash przekierowuje zarówno standardowe wyjście, jak i standardowy błąd z hellodo pliku world. W POSIX shdziała hellow tle, a następnie dokonuje pustego przekierowania world, obcinając go (tzn. Jest traktowany jak & >).

Istnieje wiele innych przypadków, w których rozszerzenia Bash zrobią coś, gdy zostaną uruchomione bash, i miałyby różne efekty w czystym POSIX sh. Na przykład rozszerzenie nawiasów klamrowych jest kolejnym, a także działa tak samo w trybie POSIX Basha, a nie.


Jeśli chodzi o błędy statycznej składni, Bash ma zarówno zastrzeżone słowa (jak [[i time), które nie są określone przez POSIX, takie jak [[ xpoprawny kod powłoki POSIX, ale błąd składniowy Bash, oraz historia różnych błędów niezgodności POSIX, które mogą powodować błędy składniowe, taki jak ten z tego pytania :

x=$(cat <<'EOF'
`
EOF
)
bash: line 2: unexpected EOF while looking for matching ``'
bash: line 5: syntax error: unexpected end of file

Tylko błędy składniowe to dość niebezpieczna definicja „niepoprawna” w każdych okolicznościach, w których ma to znaczenie, ale tak jest.

Michael Homer
źródło
3
Zauważ, że podczas gdy rozwijanie nawiasów powoduje obecnie, że bash (i zsh, pdksh, ksh93) jest niezgodny, POSIX pracuje nad dodaniem przepisu w specyfikacji, aby umożliwić rozwinięcie nawiasu (i {fd}>filepodobny problem), aby bash mógł być ponownie zgodny (rozwinięcie nawiasu) pozostanie nieokreślony, ale zgodne skrypty będą musiały zrobić, echo "{a,b}"jeśli chcą {a,b}zostać wyświetlone). Zobacz dyskusję, która ją rozpoczęła
Stéphane Chazelas,
2
Dotyczy
Stéphane Chazelas
2
Czy ktoś piszący skrypt w POSIX sh kiedykolwiek napisałby takie polecenie? OP zmierza od sh do bash, a z mojego zrozumienia wydaje się, że byłby to większy problem w innym kierunku?
Bogaty
1
@Rich: Jasne. Nie używam żadnych systemów, w których /bin/shjest bash, więc jeśli nie byłbym aktywnie świadomy tego bashizmu, napisanie linii poleceń mogłoby się łatwo zdarzyć. Odstępy w odpowiedzi sprawiają, że wygląda to mało prawdopodobne, ale hello&>worldjest mniej naciągane.
R ..
2
Właśnie widziałem błąd z powodu &>różnicy w zeszłym miesiącu!
Gordon Davisson
16

Krótki przykład:

time()(:)

timew Bash jest słowem zastrzeżonym i zachowuje się inaczej niż timeprogram. Jest całkiem prawdopodobne, że złamiesz kilka praktycznych skryptów, próbując przeanalizować wynik timeza pomocą bash. Ale technicznie nie jest to błąd składniowy. Ponowne zdefiniowanie timejako funkcji byłoby rzadkie, ale powoduje błąd składniowy, jak to pytanie określa.

Krótszy przykład:

a():

Prawidłowe dash, ale niezgodne z POSIX.

użytkownik23013
źródło
3
Mówiąc bardziej ogólnie, każde słowo, które jest niestandardowym słowem kluczowym lub wbudowanym poleceniem w Bash, spowoduje ten sam efekt. Obok time, tam takie rzeczy declare, function, select, i coproc. Choć niektóre z nich są wyraźnie oznaczone jako nieokreślona w normie ( kluczowych i builtins / Utilities ), ale nie widzę np timelub coprocna liście. I używanie --posixnie wydaje się pomóc.
ilkkachu