Как использовать Bash для sh в Ubuntu

13

Я устанавливаю огромную программу, которая имеет свои ресурсы в виде rpmфайла. Это застряло на линии

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

Видимо, в Red Hat Linux shработают bashс этим синтаксисом, но он выдает ошибку unexpected operatorв Ubuntu.

Я не могу изменить скрипт, так bashкак скрипт поставляется из rpmпакета. Я могу извлечь и упаковать rpmпакет, но таких сценариев может быть много.

Есть ли способ изменить оболочку по умолчанию, чтобы она воспринималась #!/bin/shкак bashили что-то еще, что может обработать [оператор?

Googlebot
источник
5
Единственное, что не так, это то, ==что должно быть =. Это и то, что расширения переменных должны быть в двойных кавычках.
Кусалананда
4
[это не оператор, а встроенная команда, которая вызывается test. Неожиданный оператор есть, ==и его следует заменить, =потому что он не совместим с POSIX.
Шили
Второе, что является неправильным, это то, что $SCITEGICPERLHOMEследует цитировать.
10
12
Вам следует пожаловаться автору программы. Если они используют #!/bin/sh, они должны убедиться, что они используют только функции оболочки POSIX, а не bashрасширения. Этот программист очень небрежный. Он должен либо исправить свой код, либо использовать #!/bin/bash.
Бармар
Для людей, интересующихся другими подобными проблемами, вот список " Bashisms ". Также посмотрите этот вопрос .
Капитан Мэн

Ответы:

21

Есть несколько программ, которые реализуют язык /bin/sh. В Ubuntu /bin/shэто dash, который предназначен для быстрого использования небольшого объема памяти и не поддерживает намного больше, чем ожидаемый минимум /bin/sh. На RHEL /bin/shэто bash, который работает медленнее и использует больше памяти, но имеет больше возможностей. Одной из таких функций является ==оператор [условного синтаксиса. Dash поддерживает [, что является основной функцией sh, но у него нет ==оператора, который является расширением bash (и ksh и zsh).

Вы можете переключить свою систему на использование bash. На Ubuntu /bin/shесть символическая ссылка на dash. bashВместо этого вы можете сделать это символической ссылкой . Текущие версии Debian и Ubuntu (и производных) делают эту опцию установки dash. Чтобы изменить это, запустите

sudo dpkg-reconfigure dash

и ответьте «да», чтобы сохранить тире как /bin/shили «нет», чтобы переключиться на bash.

Вы можете сохранить bash как /bin/sh, но это сделает вашу систему немного медленнее. Можно даже предположить, что какой-то системный скрипт несовместим с bash, хотя это маловероятно, поскольку bash в основном является надмножеством dash.


Для дистрибутивов, у которых нет интерфейса для выбора между реализациями /bin/sh, вот как переключиться на bash.

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

Держите терминал открытым и убедитесь, что после этого вы можете запустить некоторые shскрипты. Если вы запутаете эту команду, она сделает вашу систему непригодной для использования. (Кстати, причина, по которой я использовал несколько приведенных выше команд, а не прямолинейный взгляд, sudo ln -sf bash /bin/shзаключается в том, что ln -sfон не является атомарным. В маловероятно маловероятном случае сбоя компьютера во время этой операции вам потребуется загрузка с загрузочного носителя для его восстановления. В отличие от mvатомного.)

Чтобы восстановить черту как /bin/sh:

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

Обратите внимание, что если /bin/bashв вашем дистрибутиве по умолчанию используется sh , переключение на dash может привести к сбою сценариев, поскольку bash имеет гораздо больше возможностей, чем dash. Сценарии Bash должны начинаться с #!/bin/bash, и сценарии, начинающиеся с, #!/bin/shне должны использовать специфичные для bash функции, но дистрибутивы, поставляемые с bash, /bin/shмогут использовать специфичные для bash функции в #!/bin/shсценариях, специфичных для этого дистрибутива (это нормально, если пользователи не ожидают может переключиться на dash как /bin/shи нет никаких ожиданий, что эти сценарии будут работать в другом дистрибутиве).

Жиль "ТАК - прекрати быть злым"
источник
По моему не столь скромному мнению, если какой-либо сценарий дает сбой, когда /bin/shиспользуется Bash, это ошибка либо в системе (в пакете со сценарием), либо в sh-mode Bash . Как говорит Стивен, система явно позволяет /bin/shвернуться к Bash через dpkg-reconfigure. Это также упоминается как возможность в вики Ubuntu по этому вопросу: wiki.ubuntu.com/DashAsBinSh
ilkkachu
5
@ilkkachu Да, если скрипт не работает, если /bin/shэто bash, это ошибка. Однако ошибки случаются. Я рекомендую придерживаться значения по умолчанию, если вы не способны и готовы диагностировать такие ошибки, потому что другие люди проверили это для вас. Я использовал dash, как и /bin/shраньше, когда он официально поддерживался в Debian, но я рисковал, зная, что смогу справиться, если что-то случится.
Жиль "ТАК - перестань быть злым"
Обратите внимание, что вручную переопределенные символические ссылки будут восстановлены в любой конфигурации, сохраненной debconfпри следующем dashобновлении; по общему признанию это не случится часто (если вообще, в данном выпуске) для систем, работающих под управлением стабильной Debian.
Стивен Китт
36

Для того, чтобы перейти shк bash(вместо dash, по умолчанию), перенастроить dash(да, это несколько нелогичным):

sudo dpkg-reconfigure dash

Это спросит, хотите ли вы dashбыть системной оболочкой по умолчанию; ответьте «Нет» ( Tabтогда Enter) и bashвместо этого станете по умолчанию ( т.е. /bin/sh укажете на /bin/bash).

Стивен Китт
источник
1
Ваше решение действительно является наиболее разумным, но я принял другой ответ из-за подробного описания, проясняющего проблему. Приносим извинения за доставленные неудобства.
Googlebot
@ Googlebot не нужно извиняться, выбор принятого ответа является привилегией автора. И я получил золотой значок из этого ;-).
Стивен Китт