Jak korzystać z Bash dla sh w Ubuntu

14

Instaluję ogromny program, który ma swoje zasoby w postaci rpmpliku. Utknął na linii

#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]

Widocznie shpracować bashw systemie Red Hat Linux z tej składni, ale daje błąd unexpected operatorw Ubuntu.

Nie mogę zmienić skryptu na, bashponieważ skrypt pochodzi z rpmpakietu. Mogę wyodrębnić i przepakować rpmpakiet, ale może być wiele takich skryptów.

Czy istnieje sposób na zmianę domyślnej powłoki tak, aby traktowała ją #!/bin/shjak bashcoś innego, co może obsłużyć [operatora?

Googlebot
źródło
5
Jedyne złe jest to, ==co powinno być =. To i że zmienne rozszerzenia powinny być podwójnie cytowane.
Kusalananda
4
[nie jest operatorem, ale wywoływanym wbudowanym poleceniem test. Nieoczekiwany operator jest ==i powinien zostać zastąpiony przez, =ponieważ nie jest zgodny z POSIX.
schily
Drugą jedyną rzeczą, która jest błędna, jest to, że $SCITEGICPERLHOMEnależy ją zacytować.
l0b0
12
Powinieneś złożyć skargę do autora programu. Jeśli używają #!/bin/sh, powinni upewnić się, że używają tylko funkcji powłoki POSIX, a nie bashrozszerzeń. Ten programista jest bardzo niechlujny. Powinien albo naprawić swój kod, albo użyć #!/bin/bash.
Barmar
Dla osób zastanawiających się nad innymi podobnymi problemami znajduje się lista „ Baszizmów ”. Zobacz także to pytanie .
Kapitan Man

Odpowiedzi:

21

Istnieje wiele programów, które implementują język /bin/sh. Na Ubuntu /bin/shjest dash, który ma być szybki, zużywać niewielką ilość pamięci i nie obsługuje dużo więcej, niż oczekiwane minimum /bin/sh. Na RHEL /bin/shjest bash, który jest wolniejszy i zużywa więcej pamięci, ale ma więcej funkcji. Jedną z tych funkcji jest ==operator [składni warunkowej. Dash obsługuje [, co jest podstawową funkcją sh, ale nie ma ==operatora, który jest rozszerzeniem bash (i ksh i zsh).

Możesz przełączyć system na bash. Na Ubuntu /bin/shjest dowiązaniem symbolicznym dash. Zamiast tego możesz uczynić z niego link symboliczny bash. Obecne wersje Debiana i Ubuntu (i pochodnych) sprawiają, że jest to opcja instalacji dash. Aby to zmienić, uruchom

sudo dpkg-reconfigure dash

i odpowiedz „tak”, aby zachować myślnik jako /bin/shlub „nie”, aby przejść do bash.

Możesz zachować Bash jako /bin/sh, ale spowoduje to, że twój system będzie trochę wolniejszy. Jest nawet możliwe, że jakiś skrypt systemowy jest niezgodny z bash, chociaż jest to mało prawdopodobne, ponieważ bash jest przeważnie nadzbiorem dash.


W przypadku dystrybucji, które nie mają interfejsu do wyboru pomiędzy implementacjami /bin/sh, oto jak przejść na bash.

sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh

Pozostaw terminal otwarty i sprawdź, czy nadal możesz uruchamiać niektóre shskrypty. Jeśli zepsujesz to polecenie, spowoduje to, że twój system będzie bezużyteczny. (Nawiasem mówiąc, powodem, dla którego użyłem wielu powyższych poleceń zamiast prostego wyglądu, sudo ln -sf bash /bin/shjest to, że ln -sfnie jest atomowy. W bardzo mało prawdopodobnym przypadku awarii komputera podczas tej operacji, musisz uruchomić komputer z nośnika ratunkowego, aby go przywrócić. Przeciwnie, mvjest atomowy.)

Aby przywrócić myślnik jako /bin/sh:

sudo ln -s dash /bin/sh.dash
sudo mv /bin/sh.dash /bin/sh

Zauważ, że jeśli sh jest /bin/bashdomyślnie w twojej dystrybucji, przejście na myślnik może spowodować awarię skryptów, ponieważ bash ma o wiele więcej funkcji niż myślnik. Skrypty Bash powinny zaczynać się od #!/bin/bash, a skrypty rozpoczynające się od #!/bin/shnie powinny używać funkcji specyficznych dla bash, ale dystrybucje dostarczane z bash /bin/shmogą używać funkcji specyficznych dla bash w #!/bin/shskryptach specyficznych dla tej dystrybucji (jest to w porządku, o ile użytkownicy nie oczekują, że użytkownicy można zmienić na myślnik jako /bin/shi nie ma żadnych oczekiwań, że te skrypty będą działać w innej dystrybucji).

Gilles „SO- przestań być zły”
źródło
Moim niezbyt skromnym zdaniem, jeśli jakiś skrypt zawiedzie, gdy /bin/shjest Bash, jest to błąd albo w systemie (pakiet ze skryptem), albo w trybie Bash sh. Jak mówi Stephen, system wyraźnie pozwala na /bin/shpowrót do Bash za pośrednictwem dpkg-reconfigure. Jest również wspomniany jako możliwość w wiki Ubuntu w tej sprawie: wiki.ubuntu.com/DashAsBinSh
ilkkachu
5
@ilkkachu Tak, jeśli skrypt zawiedzie, jeśli /bin/shjest bash, to błąd. Jednak zdarzają się błędy. Zalecam pozostanie przy ustawieniach domyślnych, jeśli nie jesteś w stanie i nie chcesz zdiagnozować takich błędów, ponieważ inne osoby przetestowały je dla Ciebie. Użyłem myślnika, tak jak /bin/shpoprzednio, był on oficjalnie wspierany na Debianie, ale zaryzykowałem, wiedząc, że dam sobie radę, jeśli coś się stanie.
Gilles „SO- przestań być zły”
Zauważ, że ręcznie zastąpione dowiązania symboliczne zostaną przywrócone do dowolnej konfiguracji zapisanej debconfprzy następnej dashaktualizacji; co prawda nie zdarza się to często (jeśli w ogóle, w danej wersji) dla systemów z stabilną wersją Debiana.
Stephen Kitt,
36

Aby przełączyć się shna bash(zamiast dashdomyślnego), ponownie skonfigurować dash(tak, jest to nieco sprzeczne z intuicją):

sudo dpkg-reconfigure dash

To zapyta, czy chcesz dashbyć domyślną powłoką systemową; odpowiedz „Nie” ( Tabwtedy Enter) i bashzamiast tego stanie się domyślnym ( tzn. /bin/sh wskaże /bin/bash).

Stephen Kitt
źródło
1
Twoje rozwiązanie jest rzeczywiście najbardziej rozsądne, ale zaakceptowałem inną odpowiedź z powodu szczegółowych opisów wyjaśniających problem. Przepraszam za jakiekolwiek niedogodności.
Googlebot
@ Googleogle nie musi przepraszać, wybór zaakceptowanej odpowiedzi jest przywilejem pytającego. I mam z tego złotą odznakę ;-).
Stephen Kitt