Почему скрипты, запущенные через "sh *.sh", работают иначе, чем "./*.sh"? [duplicate]

Я использую 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
2
задан 9 February 2016 в 19:24

2 ответа

Когда вы запускаете

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)

  • [ 1138] В то время как в bash, ./scr.sh отправляется в bash

  • В то время как в ksh, ./scr.sh отправляется в ksh

    [ 1128]
  • Находясь на dash, ./scr.sh отправляется в sh (dash)


Чтобы быть на более безопасной стороне всегда пытайтесь упомянуть желаемого переводчика, используя шебанг (первая строка сценария), например:

#!/usr/bin/env bash
5
ответ дан 2 December 2019 в 01:30

Следует иметь в виду это 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 при выполнении сценария.

4
ответ дан 2 December 2019 в 01:30

Другие вопросы по тегам:

Похожие вопросы: