Vous appelez une commande / un script déconnecté du terminal de contrôle?

9

J'étudie le comportement d'un script qui est normalement exécuté comme un processus automatisé (par exemple cron, Jenkins). Le script peut (éventuellement) invoquer des commandes qui se comportent différemment (en recherchant la saisie de l'utilisateur) lorsqu'il est exécuté de manière interactive; par exemple, patchdemandera quoi faire avec un patch inversé et svndemandera des mots de passe, mais j'ai besoin de voir ce qui se passe lorsqu'ils sont exécutés de manière non interactive.

Convaincre patchqu'il n'est pas interactif est assez facile; J'ai juste besoin de rediriger stdoutpour être un non-tty:

$ </dev/null > >(cat) /path/to/myscript --args

Cependant, svnse connectera au terminal de contrôle s'il existe; éditer les scripts à passer --non-interactiven'est pas vraiment une option car cela vient de plusieurs niveaux et il serait difficile d'être certain d'avoir trouvé chaque invocation.

Existe-t-il un moyen d'invoquer un script / commande de manière non interactive, sans terminal de contrôle (donc cela /dev/ttyn'existe pas)? Je préfère que stdout / stderr continue d'aller à mon terminal.

(J'ai trouvé la question Exécuter le script dans un shell non interactif? Mais les réponses à cela discutent des différences entre l'environnement cron et l'environnement utilisateur; j'ai déjà éliminé toutes les différences sauf la non-interactivité.)

ecatmur
la source

Réponses:

13

Vous devez démarrer une autre session non attachée à un terminal, par exemple:

$ setsid sh -c 'tty; ps -jp "$$"; echo test' < /dev/null > log 2>&1
$ cat log
not a tty
  PID  PGID   SID TTY          TIME CMD
19506 19506 19506 ?        00:00:00 sh
test

Voir aussi la start-stop-daemoncommande trouvée sur certaines distributions Linux. Il y a aussi une daemoncommande.

Stéphane Chazelas
la source
Que signifie cette sortie? Ça a l'air très cryptique.
anatoly techtonik
2
@anatolytechtonik les parties importantes sont "pas un tty" qui est la sortie de la ttyconfirmation qu'il n'y a pas de terminal sur stdin, et le "?" dans la colonne de pssortie TTY qui confirme qu'il n'y a pas de contrôle tty pour le shprocessus (et tout ce qui s'exécute en dessous).
mr.spuratic
Pour exécuter la commande comme toute autre commande, utilisez setsid -w. Exemple: setsid -w sh -c 'tty < /dev/tty'donne sh: 1: cannot open /dev/tty: No such device or address(Remarque: /dev/ttyest votre tty de contrôle). Sans -wsetsid exécute le processus en parallèle / en arrière-plan.
Tino
0

Vous voudrez probablement faire un script attendu. Exemple avec SVN:

/programming/609445/using-expect-to-login-into-svn

Bratchley
la source
Ça ne marche pas; attendre exécute les commandes de manière interactive.
ecatmur
Interactivement dans quel sens? Dans le sens où cela nécessite une contribution de l'utilisateur? Si c'est ce que vous voulez dire, il ne servirait à rien de s'attendre à exister dans ce cas. Un exemple pour lequel je l'utilise est sur Solaris, la commande passwd n'a pas d'option --stdin, j'ai donc une configuration cronjob qui exécute un script expect qui entoure passwd pour lui fournir un mot de passe aléatoire pour un compte. Aucune interaction humaine requise. Je crois comprendre que c'est l'exigence de l'utilisateur. J'aurais peut-être mal compris.
Bratchley
En fait, plus je relis ceci, plus je me rends compte que j'ai mal compris ce que vous vouliez. Mes excuses.
Bratchley
0

Parfois, vous devez garder stdin ouvert (ne pas recevoir eof sur stdin) (par exemple, attendre). Dans ce cas, remplacez / dev / null par / dev / zero.

setsid sh -c 'make test' </dev/zero >log 2>&1
Roger
la source