Wie kann ich auf eine Eingabeaufforderung in einem Shell-Skript reagieren, das im Hintergrund ausgeführt wird?

8

Ich schreibe die Installation von Software auf einem HP-UX-Server. Sobald das Skript gestartet ist, werden Sie aufgefordert, den Installationspfad einzugeben. Ich muss den Pfad zum Skript übergeben, damit es weiter ausgeführt werden kann. Es gibt nur eine Stelle im Skript, an der dieser Bedarf besteht.

Die Eingabeaufforderung des Skripts lautet: Drücken Sie die EINGABETASTE für den Standardpfad oder geben Sie den Pfad ein, um die Software zu installieren:

Ich möchte den Standardpfad nicht verwenden, daher muss ich einen neuen Pfad eingeben. Aber dieses Skript wird im Hintergrund ausgeführt und ich muss den Pfad angeben. Ich bin mir der genauen Antwort in Skriptform nicht sicher.

37Scheper
quelle
Könnten Sie bitte klarer sein, was "das Skript" ist? Ist es das Installationsprogramm, das Sie aus irgendeinem Grund nicht bearbeiten können? Oder ein anderes Skript, das Sie schreiben, um das Installationsprogramm auszuführen? Wie starten Sie das Installationsprogramm, damit es im Hintergrund ausgeführt wird?
JigglyNaga
Schauen Sie sich meine Antwort an und testen Sie sie!
Jay Jargot

Antworten:

4

Sie können Ihre Antwort mithilfe einer Pipe in die Standardeingabe des Skripts übertragen.

echo "My/Path/not/default"| yourscript.sh
X Tian
quelle
Also sollte ich im selben Skript nach dem Befehl zum Ausführen des Installationsprogramms ... ./INSTALL quiet ... die folgende Zeile einfügen ... echo "my / path / not / default /" | installscript.sh?
37Scheper
3

Wenn Sie beim Starten des Skripts alle Eingaben bereitstellen können, leiten Sie die Eingaben des Programms um. Das heißt, anstatt zu rennen /path/to/installer, laufen

{ echo '/the/path/where/to/install';
  echo 'answer to the second prompt';
} | /path/to/installer

oder verwenden Sie ein hier Dokument :

/path/to/installer <<'EOF'
/the/path/where/to/install
answer to the second prompt
EOF

Wenn Sie von Zeit zu Zeit mit einem Programm interagieren möchten, Ihr Terminal jedoch für andere Zwecke dazwischen verwenden möchten , führen Sie das Programm in einem Terminal-Multiplexer wie Screen oder tmux aus . Starten Sie mit screen eine Sitzung, indem Sie ausführen screen, und starten Sie dann das Programm. Um etwas anderes zu tun, drücken Sie Ctrl+ A, cum ein zweites Fenster zu erstellen, und dann Ctrl+ A, num zwischen den Fenstern zu navigieren. Zum Verlassen Bildschirm aber lassen Sie das Programm läuft, drücken Sie Ctrl+ A, d( „detach“). Führen Sie Folgendes aus, um zur vorhandenen Bildschirmsitzung zurückzukehren screen -rd( screenohne Option würde eine neue Sitzung gestartet).

Gilles 'SO - hör auf böse zu sein'
quelle
0

Um eine automatische Antwort bereitzustellen, können Sie eine der folgenden Methoden verwenden:

insaller.sh < an_input_file

oder

command-line | installer.sh

Es gibt etwas zu beachten, wenn das installer.shSkript verwendet wird read -p, wie im folgenden Beispiel:

read -p "Press ENTER for default path or enter path to install software:" answer

man bash Gibt an, dass nichts gedruckt wird, wenn der Standardeingang kein Terminal ist.

Wenn dies Ihre Situation ist, können Sie diese seltsame Sache ausprobieren:

( sleep 30 ; printf "/my/own/path\n" ) | insaller.sh

Sie sollten die Anzahl der Sekunden ( 30im obigen Beispiel) an Ihre Situation anpassen.

Wenn es vorkommt, dass read -p es nicht im Installationsskript verwendet wird, können Sie diese GNULösung ausprobieren :

 tempdir="$(mktemp -d)"
 mkfifo  "${tempdir}"/input
 touch "${tempdir}"/output.log
 ./installer.sh <"${tempdir}"/input >"${tempdir}"/output.log 2>&1 &
 installerpid=$!
 tail --pid=$installerpid -fn 1 "${tempdir}"/output.log | ( fgrep -q "Press ENTER for default path or enter path to install software:"; printf "/new/path\n" ) >> "${tempdir}"/input &

 # ... do stuff


 # before ending the script, just wait that all background processes stop
 wait
 rm -f "${tempdir}"/input "${tempdir}"/output.log

Die Idee ist, zwei Hintergrundbefehlszeilen zu verwenden, eine für das Installationsskript und eine, um auf die Eingabeaufforderung zu warten und die Antwort bereitzustellen.

Für die Kommunikation werden eine Named Pipe ( input) und eine reguläre Datei ( output.log) verwendet.

tail --pid=$installerpid -fn 1 "${tempdir}"/output.logdruckt Zeilen so, wie sie in der output.logDatei geschrieben sind. Es wird angezeigt, wenn das Installationsskript beendet wird.

( fgrep -q ... ; printf .. ) >> ...input: blockiert, bis die Eingabeaufforderung gefunden wird, und gibt den neuen Pfad zum Installationsskript an.

Jay Jargot
quelle