Richiamare un comando / script disconnesso dal terminale di controllo?


9

Sto studiando il comportamento di uno script che normalmente viene eseguito come processo automatizzato (ad es. Cron, Jenkins). Lo script può (eventualmente) invocare comandi che si comportano in modo diverso (ricercando l'input dell'utente) quando eseguiti in modo interattivo; per esempio, patchchiederà cosa fare con una patch invertita e svnchiederà le password, ma devo vedere cosa succede quando vengono eseguite in modo non interattivo.

Persuadere patchche non è interattivo è abbastanza facile; Devo solo reindirizzare stdoutper essere un non-tty:

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

Tuttavia svnsi collegherà al terminale di controllo se esiste; la modifica degli script da passare --non-interactivenon è in realtà un'opzione in quanto proviene da diversi livelli di profondità e sarebbe difficile essere certi di aver trovato ogni invocazione.

C'è un modo per invocare uno script / comando in modo non interattivo, senza un terminale di controllo (quindi /dev/ttynon esiste)? Preferirei che stdout / stderr vadano ancora al mio terminale.

(Ho trovato la domanda Esegui script in una shell non interattiva? Ma le risposte a questa discutono delle differenze tra il cron e l'ambiente utente; ho già eliminato tutte le differenze tranne la non interattività.)

Risposte:


13

È necessario avviare un'altra sessione non collegata a un terminale, quindi ad esempio:

$ 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

Vedi anche il start-stop-daemoncomando trovato su alcune distribuzioni Linux. C'è anche un daemoncomando.


Cosa significa questo output? Sembra molto criptico.
Anatoly Techtonik,

2
@anatolytechtonik le parti importanti sono "non una tty" che è l'output di ttyconfermare che non c'è terminale su stdin e il "?" nella colonna di psoutput TTY che conferma che non vi è alcun controllo tty per il shprocesso (e qualsiasi cosa in esecuzione al suo interno).
mr.spuratic,

Per eseguire il comando come qualsiasi altro comando, utilizzare setsid -w. Esempio: setsid -w sh -c 'tty < /dev/tty'sh: 1: cannot open /dev/tty: No such device or address(Nota: /dev/ttyè il tuo tty di controllo). Senza -wsetsid esegue il processo in parallelo / in background.
Tino,

0

Probabilmente vorrai fare uno script di attesa. Esempio con SVN:

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


Questo non funziona; prevede di eseguire i comandi in modo interattivo.
ecatmur

In modo interattivo in che senso? Nel senso che richiede input da parte dell'utente? Se è questo che intendi, non ci sarebbe molto da aspettarsi di esistere in quel caso. Un esempio per cui lo uso è su Solaris il comando passwd non ha un'opzione --stdin quindi ho un cronjob impostato che esegue uno script prevede che avvolge passwd per fornire una password casuale per un account. Nessuna interazione umana richiesta. Comprendo che questo è il requisito dell'utente. Avrei potuto fraintendere però.
Bratchley,

In realtà, più rileggo questo, più mi rendo conto di aver frainteso ciò che stavate cercando. Scuse.
Bratchley,

0

A volte è necessario mantenere lo stdin aperto (non ricevere eof sullo stdin) (ad es. Aspettarsi). In tal caso, modifica / dev / null in / dev / zero.

setsid sh -c 'make test' </dev/zero >log 2>&1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.