shopt работает в командной строке, не найден при запуске в скрипте

13

Я пишу скрипт для копирования некоторых файлов и пытаюсь использовать его, shopt -s dotglob чтобы позволить cp копировать точечные файлы, как .jshintи еще много чего.

Я могу запустить shopt -s dotglobнапрямую в командной строке без ошибок. Однако при запуске сценария выдается ошибка:

script.sh: 81: script.sh: shopt: not found

Я запускаю этот скрипт в оболочке bash с заголовком shebang #!/usr/bin/env bash. Строка ошибки:

shopt -s dotglob
cp -r $TEMP/img/* $TARGET/img/
cp -r $TEMP/js/* $TARGET/js/
cp -r $TEMP/less/* $TARGET/less/

Не нашли ничего полезного в Google, есть идеи, в чем проблема?

эксцесс
источник
Спасибо за напоминание, выбрали ответы на все, что я мог. Еще один, кроме этого вопроса, на который пока нет хорошего ответа.
Куртоз
3
Попробуйте с более простым #!/bin/bashзаголовком?
иш
А какая версия Ubuntu?
иш
2
@izx, это правильный ответ, shoptявляется встроенным в bash, shне имеет shopt, и сообщение об ошибке выглядит как сообщение об ошибке от dash. Так что, скорее всего, ошибка здесь заключается в запуске bash-скрипта sh(который в Ubuntu используется dashпо умолчанию). Даже если shэто символическая ссылка bash, запуск bash-скрипта с shтем же, что и запуск с ним bash.
гейра

Ответы:

23

Чтобы сформировать ответ из комментариев:

Многие по привычке запускают свои сценарии shвместо bash. Это хорошая практика, если переносимость является проблемой, но многие люди делают это, потому что они копируют то, что видели, не понимая этого.

Если ваш сценарий не должен работать в не-настольной системе Linux (например, запуск сценариев оболочки на устройствах Android совсем другой), я рекомендую использовать строку Bash shebang в начале:

#!/bin/bash

Эта строка, когда это первая строка в сценарии, определяет, какой интерпретатор (оболочка, такая как bash или sh, Python и т. Д.) Вызывается для ее выполнения. Если вы используете вышеупомянутую строку, вы получите то же поведение (почти), что и из командной строки, при условии, что вы используете оболочку по умолчанию. Если по причинам переносимости или предпочтений вы используете другую строку shebang, имейте в виду, что вам придется обратиться к документации по оболочке, на которую вы ссылаетесь, даже если оболочка, на которую вы ссылаетесь, является символической ссылкой на Bash.

Скотт Северанс
источник
5
Чтобы быть полностью кросс-системным, я предпочитаю: #!/usr/bin/env bash поскольку задача env - знать, какой bash использовать (например, если вы его исправили).
шрике
-1

Вам нужно выйти из zsh и активировать bash, как показано:

exec bash

Выполнить команду

source ~/.bashrc

После чего вы можете реагировать зш:

exec zsh

надеюсь, это поможет

Дэвид Кабии
источник
Хммм. 1) Я не думаю, что OP использовал zsh, 2) AFAIK ~/.basrcзапускается bash при запуске в этом случае, поэтому нет необходимости вызывать его явно, 3) где выполняется команда OP? и 4) использование execдважды приводит к потере любых изменений среды, которые вы сделали в начальной оболочке zsh, что не произошло бы, если бы вы просто вызвали bash.
ксеноид
В моем случае это было необходимо, чтобы выявить изменения в среде, и эти изменения сохраняются. Я просто перезагрузил компьютер, и все мои изменения сохраняются. Может быть, это просто специфично для анаконды, которую я пытался настроить, хотя
Дэвид