GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Ist es möglich, ein Bash-Shell-Skript mit einem anderen Befehlszeilenprogramm interagieren zu lassen?

Wenn es Ihrem Befehl egal ist, wie schnell Sie ihm Eingaben geben, und Sie nicht wirklich interagieren müssen damit können Sie ein Heredoc verwenden.

Beispiel:

#!/bin/bash
prog <<EOD
cmdx
save filex
cmdy
save filey
q
EOD

Wenn Sie eine Verzweigung basierend auf der Ausgabe des Programms benötigen oder wenn Ihr Programm überhaupt empfindlich auf das Timing Ihrer Befehle reagiert, dann ist Expect genau das, was Sie wollen.


Ich empfehle Ihnen, Expect zu verwenden. Dieses Tool wurde entwickelt, um interaktive Shell-Anwendungen zu automatisieren.


Wo Not ist, ist auch ein Weg! Ich denke, dass es eine gute Bash-Lektion ist, um zu sehen, wie Prozessmanagement und IPC funktionieren. Die beste Lösung ist natürlich Erwarten. Aber der wahre Grund ist, dass Pipes knifflig sein können und viele Befehle darauf ausgelegt sind, auf Daten zu warten, was bedeutet, dass der Prozess aus Gründen, die schwer vorhersehbar sind, zu einem Zombie wird. Aber zu erfahren, wie und warum, erinnert uns daran, was unter der Haube vor sich geht.

Wenn zwei Prozesse miteinander kommunizieren, besteht die Gefahr, dass einer oder beide versuchen, Daten zu lesen, die niemals ankommen werden. Die Einsatzregeln müssen glasklar sein. Dinge wie CRLF und Zeichenkodierung können die Party ruinieren. Glücklicherweise sind zwei enge Partner wie ein Bash-Skript und sein untergeordneter Prozess relativ einfach in Einklang zu bringen. Was am leichtesten zu übersehen ist, ist, dass bash für fast alles, was es tut, einen untergeordneten Prozess startet. Wenn Sie es mit Bash zum Laufen bringen können, wissen Sie genau, was Sie tun.

Der Punkt ist, dass wir mit einem anderen Prozess sprechen wollen. Hier ist ein Server:

# a really bad SMTP server

# a hint at courtesy to the client
shopt -s nocasematch

echo "220 $HOSTNAME SMTP [$$]"

while true
do
    read
    [[ "$REPLY" =~ ^helo\ [^\ ] ]] && break
    [[ "$REPLY" =~ ^quit ]] && echo "Later" && exit
    echo 503 5.5.1 Nice guys say hello.
done

NAME=`echo "$REPLY" | sed -r -e 's/^helo //i'`
echo 250 Hello there, $NAME 

while read
do
    [[ "$REPLY" =~ ^mail\ from: ]] && { echo 250 2.1.0 Good guess...; continue; }
    [[ "$REPLY" =~ ^rcpt\ to: ]] && { echo 250 2.1.0 Keep trying...; continue; }
    [[ "$REPLY" =~ ^quit ]] && { echo Later, $NAME; exit; }
    echo 502 5.5.2 Please just QUIT
done

echo Pipe closed, exiting

Nun, das Skript, das hoffentlich die Magie ausübt.

# Talk to a subprocess using named pipes

rm -fr A B      # don't use old pipes
mkfifo A B

# server will listen to A and send to B
./smtp.sh < A > B &

# If we write to A, the pipe will be closed.
# That doesn't happen when writing to a file handle.
exec 3>A

read < B
echo "$REPLY"

# send an email, so long as response codes look good
while read L
do
    echo "> $L"
    echo $L > A
    read < B
    echo $REPLY
    [[ "$REPLY" =~ ^2 ]] || break

done <<EOF
HELO me
MAIL FROM: me
RCPT TO: you
DATA
Subject: Nothing

Message
.
EOF

# This is tricky, and the reason sane people use Expect.  If we
# send QUIT and then wait on B (ie. cat B) we may have trouble.
# If the server exits, the "Later" response in the pipe might
# disappear, leaving the cat command (and us) waiting for data.
# So, let cat have our STDOUT and move on.
cat B &

# Now, we should wait for the cat process to get going before we
# send the QUIT command. If we don't, the server will exit, the
# pipe will empty and cat will miss its chance to show the
# server's final words.
echo -n > B     # also, 'sleep 1' will probably work.

echo "> quit"
echo "quit" > A

# close the file handle
exec 3>&-

rm A B

Beachten Sie, dass wir die SMTP-Befehle nicht einfach auf dem Server ausgeben. Wir überprüfen jeden Antwortcode, um sicherzustellen, dass alles in Ordnung ist. In diesem Fall sind die Dinge nicht in Ordnung und das Skript bricht ab.


Linux
  1. Befehlszeilenargumente an Bash-Skript übergeben?

  2. Shell-Script-Wrapper, um das Ausführen von Befehlen ohne Argumente zu verhindern?

  3. Shell-Skript mit Funktion und Parameter als Variablen?

  4. Shell-Skript hängt am Mail-Befehl?

  5. So echoen Sie eine neue Zeile in Bash-Shell-Skripten

Shell-Scripting Teil I:Erste Schritte mit Bash-Scripting

Bash Echo-Befehl mit Beispielen in Linux erklärt

Rm-Befehl im Bash-Skript funktioniert nicht mit Variablen?

15 nützliche integrierte Bash Shell-Befehle (mit Beispielen)

Zeile für Zeile im Bash-Skript lesen

Zeile mit Shell-Skript an die Datei /etc/hosts anhängen