Exécuter un script dans un shell non interactif?

17

J'ai un travail cron qui exécute un script. Lorsque j'exécute le script via un shell interactif (ssh'ed to bash), cela fonctionne très bien. Lorsque le script s'exécute de lui-même via cron, il échoue.

Je suppose qu'il utilise certaines des variables d'environnement définies dans le shell interactif. Je vais dépanner le script et les supprimer.

Après avoir apporté des modifications, je sais que je pourrais mettre le script en file d'attente dans cron pour qu'il s'exécute normalement, mais existe-t-il un moyen de l'exécuter à partir de la ligne de commande, mais de lui dire de s'exécuter comme il le ferait à partir de cron - c'est-à-dire dans un environnement non interactif?

cwd
la source
Associé et donc peut-être utile: "Comment obtenir un environnement propre dans un shell ksh?" voir notamment la réponse de @Gilles concernant unset.
sr_
1
Depuis le lien de @ sr_, j'ai recherché env, et vous voudrez peut-être essayer env -i ./my-script.sh. De plus, recevez-vous un message d'erreur?
Kevin
Quelle implémentation cron utilisez-vous?
rozcietrzewiacz
@kevin - je voterai favorablement si vous répondez avec.
cwd

Réponses:

12

Les principales différences entre l'exécution d'une commande à partir de cron et l'exécution sur la ligne de commande sont les suivantes:

  • cron utilise probablement un shell différent (généralement /bin/sh);
  • cron fonctionne définitivement dans un petit environnement (lesquels dépendent de l'implémentation de cron, alors vérifiez la page de manuel cron(8)ou crontab(5); généralement il y a juste HOME, peut SHELL-être LOGNAME, peut USER- être , et une petite PATH);
  • cron traite le %personnage spécialement (il est transformé en une nouvelle ligne);
  • les tâches cron s'exécutent sans terminal ni environnement graphique.

L'invocation suivante exécutera l'extrait de shell à peu près comme s'il avait été appelé à partir de cron. Je suppose que l'extrait ne contient pas les caractères 'ou %.

env - HOME="$HOME" USER="$USER" PATH=/usr/bin:/bin /bin/sh -c 'shell snippet' </dev/null >job.log 2>&1

Voir aussi l' exécution d'un script sh à partir du cron , ce qui pourrait aider à résoudre votre problème.

Gilles 'SO- arrête d'être méchant'
la source
Salut @Giles - juste pensé à quelque chose - exécuter un script comme sudo -u user /path/to/scriptserait également un moyen de l'exécuter sans aucun ensemble de variables?
cwd
@cwd Non, généralement pas. sudoefface certaines variables et définit d'autres à une valeur connue, mais cela dépend de la façon dont il est configuré. Il est souvent configuré pour conserver les paramètres régionaux et TERM, par exemple.
Gilles 'SO- arrête d'être méchant'
2

Depuis le lien de @ sr_ ( Comment obtenir un environnement propre dans un shell ksh? ), J'ai recherché env, et vous voudrez peut-être essayer ceci:

env -i ./my-script.sh
Kevin
la source
Cela a bien fonctionné pour moi, bien que la réponse @Gilles soit également très bonne.
cwd
@cwd: ne fonctionne pas pour moi: echo -e '#!/bin/bash -i\necho interactive $-' > ~/test.sh && chmod +x ~/test.sh && env -i ~/test.shsorties interactive himB.
Alix Axel
1

Je vous suggère d'utiliser des chemins absolus pour vos scripts lorsque vous les mettez dans cron et que vous les utilisez ailleurs et pour toutes les commandes linux qui y sont utilisées, mieux les déclarer comme variables et les utiliser!

Gaumire
la source
Oui. mais bien sûr.
cwd
0

Cron n'utilise pas nécessairement le même shell que vous utilisez. vérifier:

cat /etc/crontab |grep SHELL

Pour déterminer le shell et tenter d'exécuter votre script là-bas, cela fonctionne-t-il? C'est une cause fréquente de problèmes pour de nombreuses personnes qui ajoutent des scripts à cron.

Si c'est le problème - vous pouvez ajouter "bash" au début de votre script dans cron pour forcer ce script à s'exécuter dans bash. Si cela ne résout pas le problème, faites-le moi savoir et je creuserai un peu plus.

Mat
la source
0

Si vous souhaitez ignorer certaines questions interactives fournies par un script, vous pouvez essayer:

yes | your_command

Ou yes "n"si vous souhaitez répondre à toutes les questions.

Commander:

oui - être affirmatif de façon répétitive oui renvoie des mots explicatifs ou, par défaut, «y» pour toujours.

kenorb
la source
0

Pour exécuter votre script dans un shell non interactif (sans égard aux détails de cron), vous pouvez le faire via ssh.

Testez si vous vous retrouvez vraiment dans un shell non interactif:

> ssh someuser@somehost tty
not a tty

Exécutez le script dans un shell non interactif:

> ssh someuser@somehost /tmp/myscript.sh
dokaspar
la source