J'ai un petit script sh que j'utilise pour sauvegarder sur un serveur distant. Cela a fonctionné sur Ubuntu 16.04 pendant des années, mais maintenant, le 18.04, il échoue. Au début, je pensais que c'était un problème avec anacron, mais maintenant je pense que c'est un problème avec le script lui-même ou avec dash. Voici ce qui se passe:
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$
L'erreur can't open *
empêche le script de s'exécuter correctement lorsqu'il est exécuté par run-parts
. Pourquoi cette erreur se produit-elle?
Il n'est pas pertinent que dans la dernière ligne, lors de l'exécution du script, il ne puisse pas établir de connexion. Le serveur est maintenant éteint.
Voici le script:
#!/bin/sh *
rsync -azvv -e "ssh -i /home/stefan/.ssh/id_rsa" /home/stefan/Documents/ totem@MouseHouse:/totembackup/totemdoc
Je ne peux pas dire avec certitude, mais il semble que vous ayez une faute de frappe sur la première ligne où il y a un _ *
vers la droite.
#!/bin/sh *
^^^ Faites défiler vers la droite pour le voir.
$ cat script.bash
#!/bin/sh *
echo hi
Exécutez directement:
$ ./script.bash
/bin/sh: *: No such file or directory
Exécutez via sh
:
$ sh script.bash
hi
Il est généralement conseillé d'utiliser la coque exacte que vous attendez avec votre Shebang. Si vous pensez que vous rencontrez des problèmes où vous pensez que dash
ou un autre Shell est utilisé, vous pouvez toujours rendre votre Shebang explicite en le changeant de #!/bin/sh
comme votre Shebang #!/bin/bash
.
Ce qui précède est basé sur votre commentaire ci-dessous:
mais maintenant je pense que c'est un problème avec le script lui-même ou avec le tiret.
L'erreur
can't open *
empêche le script de s'exécuter correctement lorsqu'il est exécuté parrun-parts
. Pourquoi cette erreur se produit-elle?
Lorsque vous exécutez un fichier1 ce n'est pas un exécutable binaire, mais c'est un fichier texte avec un Shebang (la première ligne du fichier commence par #!
), le noyau (sans l'aide d'aucun shell) construit une commande qui est la ligne Shebang (la partie après le #!
) suivi de la ligne de commande d'origine au niveau de l'utilisateur. Par exemple, si doc-script
commence
#!/bin/sh -x
et il est invoqué
./doc-script bashful dopey
puis le noyau construit et exécute la commande suivante:
/bin/sh -x ./doc-script bashful dopey
ce qui oblige le shell à lire et interpréter le doc-script
script, avec xtrace (-x
) ensemble d'options, et avec $1
= bashful
et $2
= dopey
. (Naturellement, $0
est ./doc-script
.) Si la commande d'origine fournie par l'utilisateur est
./doc-script b* ??p* [ghs]*
le shell qui gère cette commande (pour simplifier, supposons qu'il s'agit du shell interactif s'exécutant sur le terminal de l'utilisateur) pourrait l'étendre à
./doc-script bashful dopey grumpy happy sleepy sneezy
et ainsi le noyau construit et exécute la commande suivante:
/bin/sh -x ./doc-script bashful dopey grumpy happy sleepy sneezy
Mais rappelez-vous: le traitement de la ligne Shebang est fait par le noyau, pas par le Shell . Par conséquent, si le Shebang est
#!/bin/sh *
alors la commande finale et construite est
/bin/sh * ./doc-script bashful dopey grumpy happy sleepy sneezy
car l'expansion globale ne se produit pas ici. En ce qui concerne le Shell, cela ressemble à l'utilisateur tapé
/bin/sh '*' ./doc-script bashful dopey grumpy happy sleepy sneezy
et parce que *
ne commence pas par -
, le shell l'interprète comme un nom de fichier, il essaie donc d'exécuter un script appelé *
avec $0
= *
, $1
= ./doc-script
, $2
= bashful
, $3
= dopey
, etc. Et, puisqu'il n'y a pas de script appelé *
, cela échoue.
__________
1Je suppose que le processus dispose des autorisations nécessaires pour exécuter le fichier.