На этот вопрос уже есть ответ здесь:
Я использую Ubuntu 15.10. Я заметил странную проблему.
При запуске команды rsync
, встроенной в сценарий оболочки (от имени root) с опциями --exclude={}
, rsync
работает и исключает пути, как и должно быть, когда я запускаю его от имени root через
./rBackup.sh
Однако, когда я запускаю его от имени root через
sh rBackup.sh
опции исключения каталогов не переносятся, и он бесконечно зацикливается при резервном копировании диска, на который выполняется резервное копирование в /media/
. Почему?
Редактировать - это не разница между sh и bash - или не должно быть. У меня #!/bin/bash в качестве первой строки, поэтому при запуске через "sh *.sh" он должен использовать интерпретатор bash - по крайней мере, теоретически.
Сценарий выглядит следующим образом:
#!/bin/bash
StandbyMount="/media/astump/sdb2"
mount /dev/sdb2 $StandbyMount
rsync -aAXv --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found,/etc/fstab,/boot/grub/grub.cfg} --delete-before / $StandbyMount
umount $StandbyMount
rm -fr $StandbyMount
Когда вы запускаете
sh rBackup.sh
, скрипт rBackup.sh
выполняется sh
(dash
), который не поддерживает расширение скобок.
С другой стороны, когда вы делаете
./rBackup.sh
, тогда в первой строке #!/bin/bash
указывается точный интерпретатор для использования. Бывает, что bash
поддерживает расширение скобок.
Если вы не включили допустимый исполняемый файл в строку shebang, вы просто запускаете скрипт под текущей оболочкой, в которой находитесь (или sh
в зависимости от реализаций оболочки).
Пример: Из bash
:
$ cat scr.sh
echo {bar,spam}
$ sh scr.sh
{bar,spam}
$ ./scr.sh
bar spam
Моя оболочка для входа - zsh
. Вот некоторые моменты, на которые следует обратить внимание:
В то время как в zsh
, ./scr.sh
отправляется в sh
(dash
)
bash
, ./scr.sh
отправляется в bash
В то время как в ksh
, ./scr.sh
отправляется в ksh
Находясь на dash
, ./scr.sh
отправляется в sh
(dash
)
Чтобы быть на более безопасной стороне всегда пытайтесь упомянуть желаемого переводчика, используя шебанг (первая строка сценария), например:
#!/usr/bin/env bash
Следует иметь в виду это sh
на самом деле вызовы dash
, который ограничен по сравнению с, скажем, Bash.
Как наблюдался @Serg в комментарии к вопросу, фигурные скобки интерпретируются как исходные данные для подчеркивания штриховой линией, возможно, который является, почему он не будет работать. Поэтому это перестало работать - Тире не делает Расширения Фигурной скобки.
Вы, вероятно, ожидаете, что система будет использовать интерпретацию стиля Bash. Если Вы используете оболочку по умолчанию bash
затем выполняя сценарий с ./rBackup.sh
я верю, выполнит его в той рабочей оболочке.
Я думаю, что Вы ожидаете, что этот сценарий будет обработан Bash, который не будет работать, когда Вы сделаете sh
.
Поэтому давайте сделаем пару вещей по-другому здесь:
(1) Определить #!/bin/bash
вначале, чтобы заставить его использовать Bash при прямом выполнении.
(2) chmod +x rBackup.sh
- Это установит исполняемый бит
(3) Выполните команду только с ./rBackup.sh
или bash ./rBackup.sh
или bash rBackup.sh
. Это гарантирует, что Bash используется для интерпретации функции во всех случаях; так как это определяет для использования #!/bin/bash
в начале файла, если Вы сделали шаг 1, он попытается использовать Bash при выполнении сценария.