GNU/Linux >> Linux Esercitazione >  >> Linux

È possibile far interagire uno script di shell bash con un altro programma a riga di comando?

Se al tuo comando non importa quanto velocemente gli dai input e non hai davvero bisogno di interagire con esso, allora puoi usare un heredoc.

Esempio:

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

Se hai bisogno di ramificazioni basate sull'output del programma, o se il tuo programma è sensibile alla tempistica dei tuoi comandi, allora Expect è quello che vuoi.


Ti consiglio di usare Expect. Questo strumento è progettato per automatizzare le applicazioni shell interattive.


Dove c'è bisogno, c'è un modo! Penso che sia una buona lezione di bash per vedere come funzionano la gestione dei processi e ipc. La soluzione migliore è, ovviamente, Expect. Ma la vera ragione è che le pipe possono essere complicate e molti comandi sono progettati per attendere i dati, il che significa che il processo diventerà uno zombi per ragioni che potrebbero essere difficili da prevedere. Ma imparare come e perché ci ricorda cosa sta succedendo sotto il cofano.

Quando due processi si impegnano in una conversazione, il pericolo è che uno o entrambi cerchino di leggere dati che non arriveranno mai. Le regole di ingaggio devono essere cristalline. Cose come CRLF e la codifica dei caratteri possono uccidere la festa. Fortunatamente, due partner stretti come uno script bash e il suo processo figlio sono relativamente facili da tenere in riga. La cosa più facile da perdere è che bash sta lanciando un processo figlio per quasi ogni cosa che fa. Se riesci a farlo funzionare con bash, sai perfettamente cosa stai facendo.

Il punto è che vogliamo parlare con un altro processo. Ecco un 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

Ora, lo script che si spera faccia la magia.

# 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

Si noti che non stiamo semplicemente scaricando i comandi SMTP sul server. Controlliamo ogni codice di risposta per assicurarci che tutto sia a posto. In questo caso, le cose non andranno bene e lo script salterà.


Linux
  1. Lo script Bash con `set -e` non si ferma al comando `… &&…`?

  2. Script di shell con funzione e parametro come variabili?

  3. Il comando Rm nello script Bash non funziona con la variabile?

  4. Lo script della shell si blocca sul comando di posta?

  5. 6 Operatori di concatenamento della riga di comando della shell Bash in Linux

Come programmare con Bash:sintassi e strumenti

Shell Scripting Parte I:Introduzione agli script bash

Comando Bash Echo spiegato con esempi in Linux

15 utili comandi integrati di Bash Shell (con esempi)

Aggiungi una riga al file /etc/hosts con lo script della shell

Automatizza mysql_secure_installation con il comando echo tramite uno script di shell