GNU/Linux >> Znalost Linux >  >> Linux

Je možné, aby skript bash shell interagoval s jiným programem příkazového řádku?

Pokud vašemu příkazu nezáleží na tom, jak rychle jej zadáte, a ve skutečnosti nepotřebujete interagovat s ním, pak můžete použít heredoc.

Příklad:

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

Pokud potřebujete větvení na základě výstupu programu nebo pokud je váš program vůbec citlivý na časování vašich příkazů, pak je Expect to, co chcete.


Doporučuji použít Expect. Tento nástroj je navržen pro automatizaci interaktivních aplikací shellu.


Kde je potřeba, tam je cesta! Myslím, že je to dobrá lekce bash, abyste viděli, jak funguje procesní řízení a ipc. Nejlepším řešením je samozřejmě Expect. Ale skutečným důvodem je, že roury mohou být složité a mnoho příkazů je navrženo tak, aby čekaly na data, což znamená, že se proces stane zombie z důvodů, které lze jen těžko předvídat. Ale zjistit, jak a proč, nám připomíná, co se děje pod kapotou.

Když se dva procesy zapojí do konverzace, existuje nebezpečí, že se jeden nebo oba pokusí přečíst data, která nikdy nedorazí. Pravidla zapojení musí být křišťálově jasná. Věci jako CRLF a kódování postav mohou zničit party. Naštěstí jsou dva blízcí partneři, jako je bash skript a jeho podřízený proces, relativně snadno udržovat v souladu. Nejjednodušší věc, kterou přehlédnete, je, že bash spouští podřízený proces téměř pro každou věc, kterou dělá. Pokud dokážete, aby to fungovalo s bashem, dobře víte, co děláte.

Jde o to, že chceme mluvit s jiným procesem. Zde je 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

Nyní skript, který doufejme dělá kouzlo.

# 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

Všimněte si, že na server jednoduše neukládáme příkazy SMTP. Kontrolujeme každý kód odpovědi, abychom se ujistili, že je vše v pořádku. V tomto případě nebude vše OK a scénář bude kauce.


Linux
  1. Který Shell Interpreter spouští skript s No Shebang?

  2. Předat argumenty příkazového řádku skriptu Bash?

  3. Shell Script Wrapper zabránit spuštění příkazu bez argumentů?

  1. Příkaz Rm ve skriptu Bash nefunguje s proměnnou?

  2. Skript Shell visí na příkazu Mail?

  3. Čtěte řádek po řádku v bash skriptu

  1. Jak programovat s Bash:Syntaxe a nástroje

  2. Připojte řádek do souboru /etc/hosts pomocí skriptu shellu

  3. echo text s novým řádkem v bash