Einen Befehl / ein Skript aufrufen, das vom steuernden Terminal getrennt ist?

9

Ich untersuche das Verhalten eines Skripts, das normalerweise als automatisierter Prozess ausgeführt wird (z. B. cron, Jenkins). Das Skript kann (eventuell) Befehle aufrufen, die sich bei interaktiver Ausführung anders verhalten (nach Benutzereingaben suchen). Ich patchwerde zum Beispiel fragen, was mit einem umgekehrten Patch zu tun ist, und svnnach Passwörtern fragen, aber ich muss sehen, was passiert, wenn sie nicht interaktiv ausgeführt werden.

Es patchist ziemlich einfach, davon zu überzeugen, dass es nicht interaktiv ist. Ich muss nur umleiten stdout, um ein Nicht-Tty zu sein:

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

Stellt svnjedoch eine Verbindung zum steuernden Terminal her, falls vorhanden. Das Bearbeiten der zu übergebenden Skripte --non-interactiveist keine Option, da dies aus mehreren Ebenen stammt und es schwierig sein könnte, sicher zu sein, dass ich jeden Aufruf gefunden habe.

Gibt es eine Möglichkeit, ein Skript / einen Befehl nicht interaktiv ohne ein steuerndes Terminal aufzurufen (das /dev/ttygibt es also nicht)? Ich würde es vorziehen, wenn stdout / stderr immer noch zu meinem Terminal geht.

(Ich habe die Frage Skript ausführen in einer nicht interaktiven Shell gefunden? In den Antworten darauf werden jedoch die Unterschiede zwischen der Cron- und der Benutzerumgebung erörtert. Ich habe bereits alle Unterschiede außer der Nicht-Interaktivität beseitigt.)

ecatmur
quelle

Antworten:

13

Sie müssen eine andere Sitzung starten, die nicht an ein Terminal angeschlossen ist. Beispiel:

$ 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

Siehe auch den start-stop-daemonBefehl einiger Linux-Distributionen. Es gibt auch einen daemonBefehl.

Stéphane Chazelas
quelle
Was bedeutet diese Ausgabe? Sieht sehr kryptisch aus.
Anatoly Techtonik
2
@anatolytechtonik die wichtigen Teile sind "not a tty", was die Ausgabe der ttyBestätigung ist, dass es kein Terminal auf stdin gibt, und das "?" In der TTY- psAusgabespalte, die bestätigt, dass für den Prozess (und alles, was darunter läuft) kein tty gesteuert wirdsh .
mr.spuratic
Verwenden Sie, um den Befehl wie jeden anderen Befehl auszuführen setsid -w. Beispiel: setsid -w sh -c 'tty < /dev/tty'gibt sh: 1: cannot open /dev/tty: No such device or address(Hinweis: /dev/ttyist Ihre steuernde tty). Ohne -wsetsid läuft der Prozess parallel / im Hintergrund.
Tino
0

Sie werden wahrscheinlich ein Expect-Skript erstellen wollen. Beispiel mit SVN:

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

Bratchley
quelle
Das funktioniert nicht; Erwarten Sie, dass Befehle interaktiv ausgeführt werden.
Ecatmur
In welchem ​​Sinne interaktiv? In dem Sinne, dass es Eingaben des Benutzers erfordert? Wenn Sie das meinen, wäre es in diesem Fall nicht sinnvoll zu erwarten. Ein Beispiel, für das ich es verwende, ist, dass der Befehl passwd unter Solaris keine Option --stdin hat. Daher habe ich einen Cronjob eingerichtet, der ein Erwartungsskript ausführt, das passwd umschließt, um ihm ein zufälliges Kennwort für ein Konto zu geben. Keine menschliche Interaktion erforderlich. Nach meinem Verständnis ist dies die Anforderung des Benutzers. Ich hätte es aber falsch verstehen können.
Bratchley
Je mehr ich das noch einmal lese, desto mehr wird mir klar, dass ich falsch verstanden habe, was Sie wollten. Entschuldigung.
Bratchley
0

Manchmal müssen Sie stdin offen halten (nicht eof auf stdin erhalten) (z. B. erwarten). In diesem Fall ändern Sie / dev / null in / dev / zero.

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