Сценарий оболочки может быть запущен только командой sh

У меня есть небольшой скрипт sh, который я использую для резервного копирования на удаленный сервер. Он работал на Ubuntu 16.04 годами, но сейчас, 18.04, не работает. Сначала я думал, что это проблема с анакроном, но теперь я думаю, что это проблема самого скрипта или тире. Вот что происходит:

stefan@stefan-Aspire-F5-573T:/etc/cron.daily$ sudo chmod +x rsync-doc-script 
[sudo] Mot de passe de stefan : 
stefan@stefan-Aspire-F5-573T:/etc/cron.daily$ ./rsync-doc-script 
/bin/sh: 0: Can't open *
stefan@stefan-Aspire-F5-573T:/etc/cron.daily$ sh rsync-doc-script
opening connection using: ssh -i /home/stefan/.ssh/id_rsa -l totem MouseHouse rsync --server -vvlogDtprze.iLsfxC . /totembackup/totemdoc  (11 args)
ssh: connect to host mousehouse port 22: Connection refused
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(235) [sender=3.1.2]
stefan@stefan-Aspire-F5-573T:/etc/cron.daily$ 

Ошибка can't open * препятствует правильной работе скрипта при запуске run-parts, Почему происходит эта ошибка?

Не имеет значения, что в последней строке при запуске скрипта не удалось установить соединение. Сервер выключен.

Вот сценарий:

#!/bin/sh                                                                                     *
rsync -azvv -e "ssh -i /home/stefan/.ssh/id_rsa" /home/stefan/Documents/ totem@MouseHouse:/totembackup/totemdoc

2 ответа

Решение

Я не могу сказать наверняка, но похоже, что у вас есть опечатка на первой линии, где есть заблуждение * направо.

#!/bin/sh                                                                                     *

^^^ Прокрутите вправо, чтобы увидеть его.

пример

$ cat script.bash
#!/bin/sh                    *
echo hi

Запустите прямо:

$ ./script.bash
/bin/sh: *: No such file or directory

Запустить через sh:

$ sh script.bash
hi

Общий совет

Как правило, рекомендуется использовать именно ту оболочку, которую вы ожидаете, со своим шебангом. Если вы подозреваете, что у вас возникли проблемы, в которых вы подозреваете dash или какая-то другая оболочка используется, вы всегда можете сделать ваш shebang явным, изменив его #!/bin/sh как твой шебанг #!/bin/bash,

Вышесказанное основано на вашем комментарии ниже:

но теперь я думаю, что это проблема самого скрипта или тире.

Ошибка can't open * препятствует правильной работе скрипта при запуске run-parts, Почему происходит эта ошибка?

Когда вы выполняете файл 1, который не является двоичным исполняемым файлом, но представляет собой текстовый файл с символом shebang (первая строка файла начинается с #!) ядро ​​(без помощи какой-либо оболочки) создает команду, представляющую собой строку shebang (часть после #!) с последующей исходной командной строкой на уровне пользователя. Например, если doc-script начинается

#!/bin/sh -x

и это вызывается

./doc-script bashful dopey

затем ядро ​​создает и выполняет следующую команду:

/bin/sh -x ./doc-script bashful dopey

что заставляет оболочку читать и интерпретировать doc-script скрипт, с xtrace (-x) опция установлена, и с $1 знак равно bashful а также $2 знак равно dopey, (Естественно, $0 является ./doc-script.) Если исходная предоставленная пользователем команда

./doc-script b* ??p* [ghs]*

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

./doc-script bashful dopey grumpy happy sleepy sneezy

и поэтому ядро ​​собирает и выполняет следующую команду:

/bin/sh -x ./doc-script bashful dopey grumpy happy sleepy sneezy

Но помните: обработка строки shebang выполняется ядром, а не оболочкой. Поэтому, если Шебанг

#!/bin/sh *

тогда последняя построенная команда

/bin/sh * ./doc-script bashful dopey grumpy happy sleepy sneezy

потому что расширение глобуса здесь не происходит. Что касается оболочки, похоже, что пользователь набрал

/bin/sh '*' ./doc-script bashful dopey grumpy happy sleepy sneezy

и потому что * не начинается с - оболочка интерпретирует его как имя файла, поэтому она пытается запустить скрипт с именем * с $0знак равно *, $1 знак равно ./doc-script, $2 знак равно bashful, $3 знак равно dopey и т. д. И, поскольку нет сценария под названием * это не удается.
__________
1 Я предполагаю, что у процесса есть разрешения, необходимые для выполнения файла.

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