У меня есть маленький sh сценарий, который я использую для резервного копирования к удаленному серверу. Это работало над Ubuntu 16.04 в течение многих лет, но теперь над 18,04 это перестало работать. Сначала я думал, что это была проблема с anacron, но теперь я думаю, что это - проблема с самим сценарием или с тире. Вот то, что происходит:
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
Я не могу сказать наверняка, но похоже, что у Вас есть опечатка на первой строке, где существует случайное *
направо.
#!/bin/sh *
Прокрутка ^^^ к праву видеть его.
$ cat script.bash
#!/bin/sh *
echo hi
Выполнение непосредственно:
$ ./script.bash
/bin/sh: *: No such file or directory
Выполненный через sh
:
$ sh script.bash
hi
Обычно желательно использовать точную оболочку, которую Вы ожидаете со своей хижиной. Если Вы подозреваете столкновение с проблемами, где Вы подозреваете dash
или некоторая другая оболочка используется, можно всегда делать хижину явной путем изменения ее от #!/bin/sh
как Ваша хижина #!/bin/bash
.
Вышеупомянутое основано на Вашем комментарии ниже:
но теперь я думаю, что это - проблема с самим сценарием или с тире.
Ошибка
can't open *
препятствует тому, чтобы сценарий работал правильно, когда выполненоrun-parts
. , Почему эта ошибка происходит?
При выполнении file1, который не является двоичным исполняемым файлом, но является текстовым файлом с хижиной (первая строка файла начинается #!
), ядро (без справки от любой оболочки) создает команду, которая является строкой хижины (часть после #!
) сопровождаемый исходной, командной строкой уровня пользователя. Например, если 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
Но помните: обработка строки хижины сделана ядром, не оболочкой. Поэтому, если хижина
#!/bin/sh *
затем заключительная, созданная команда
/bin/sh * ./doc-script bashful dopey grumpy happy sleepy sneezy
потому что расширения шарика не происходит здесь. Что касается оболочки, это похоже на введенного пользователя
/bin/sh '*' ./doc-script bashful dopey grumpy happy sleepy sneezy
и, потому что *
не начинается -
, оболочка интерпретирует его как имя файла, таким образом, это пытается запустить названный скрипт *
with $0
= *
, $1
= ./doc-script
, $2
= bashful
, $3
= dopey
, и т.д. И, с тех пор нет никакого названного сценария *
, это перестало работать.
__________
1 I предполагаю, что процесс имеет полномочия, необходимые для выполнения файла.