GNU/Linux >> Tutoriels Linux >  >> Linux

Est-il possible de faire interagir un script shell bash avec un autre programme en ligne de commande ?

Si votre commande ne se soucie pas de la vitesse à laquelle vous lui donnez une entrée, et que vous n'avez pas vraiment besoin d'interagir avec lui, vous pouvez utiliser un heredoc.

Exemple :

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

Si vous avez besoin d'un branchement basé sur la sortie du programme, ou si votre programme est du tout sensible au timing de vos commandes, alors Attendez est ce que vous voulez.


Je vous recommande d'utiliser Expect. Cet outil est conçu pour automatiser les applications shell interactives.


Là où il y a un besoin, il y a un moyen ! Je pense que c'est une bonne leçon de bash pour voir comment la gestion des processus et l'ipc fonctionnent. La meilleure solution est, bien sûr, Attendre. Mais la vraie raison est que les canaux peuvent être délicats et que de nombreuses commandes sont conçues pour attendre des données, ce qui signifie que le processus deviendra un zombie pour des raisons difficiles à prévoir. Mais apprendre comment et pourquoi nous rappelle ce qui se passe sous le capot.

Lorsque deux processus s'engagent dans une conversation, le danger est que l'un ou les deux essaient de lire des données qui n'arriveront jamais. Les règles d'engagement doivent être limpides. Des choses comme CRLF et l'encodage de caractères peuvent tuer la fête. Heureusement, deux partenaires proches comme un script bash et son processus enfant sont relativement faciles à garder en ligne. La chose la plus facile à manquer est que bash lance un processus enfant pour à peu près tout ce qu'il fait. Si vous pouvez le faire fonctionner avec bash, vous savez parfaitement ce que vous faites.

Le fait est que nous voulons parler d'un autre processus. Voici un serveur :

# 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

Maintenant, le script qui, espérons-le, fait la magie.

# 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

Notez que nous ne déversons pas simplement les commandes SMTP sur le serveur. Nous vérifions chaque code de réponse pour nous assurer que tout va bien. Dans ce cas, les choses n'iront pas bien et le script sera renfloué.


Linux
  1. Comment programmer avec Bash :syntaxe et outils

  2. Comment passer un argument de ligne de commande dans un script shell ?

  3. Le script Bash avec `set -e` ne s'arrête pas sur la commande `… &&…` ?

  4. Shell Script Wrapper pour empêcher l'exécution de la commande sans arguments ?

  5. La commande Rm dans le script Bash ne fonctionne pas avec la variable ?

Shell Scripting Partie I :Premiers pas avec les scripts bash

La commande Bash Echo expliquée avec des exemples sous Linux

Le script shell se bloque sur la commande de messagerie ?

6 opérateurs de chaînage de ligne de commande Bash Shell sous Linux

Automatisez mysql_secure_installation avec la commande echo via un script shell

texte d'écho avec une nouvelle ligne dans bash