Jika perintah Anda tidak peduli seberapa cepat Anda memberikan masukan, dan Anda tidak benar-benar perlu berinteraksi dengan itu, maka Anda dapat menggunakan heredoc.
Contoh:
#!/bin/bash
prog <<EOD
cmdx
save filex
cmdy
save filey
q
EOD
Jika Anda memerlukan percabangan berdasarkan keluaran program, atau jika program Anda sangat sensitif terhadap pengaturan waktu perintah Anda, maka Harapkan yang Anda inginkan.
Saya sarankan Anda menggunakan Harapkan. Alat ini dirancang untuk mengotomatiskan aplikasi shell interaktif.
Di mana ada kebutuhan, di situ ada jalan! Saya pikir ini adalah pelajaran bash yang bagus untuk melihat bagaimana manajemen proses dan ipc bekerja. Solusi terbaik adalah, tentu saja, Harapkan. Tetapi alasan sebenarnya adalah bahwa pipa bisa rumit dan banyak perintah dirancang untuk menunggu data, yang berarti bahwa proses tersebut akan menjadi zombie karena alasan yang sulit diprediksi. Namun mempelajari bagaimana dan mengapa mengingatkan kita tentang apa yang terjadi di balik terpal.
Ketika dua proses terlibat dalam percakapan, bahayanya adalah salah satu atau keduanya akan mencoba membaca data yang tidak akan pernah sampai. Aturan keterlibatan harus sangat jelas. Hal-hal seperti CRLF dan pengkodean karakter dapat mematikan pesta. Untungnya, dua mitra dekat seperti skrip bash dan proses anaknya relatif mudah untuk tetap sejalan. Hal termudah untuk dilewatkan adalah bahwa bash meluncurkan proses anak untuk hampir semua hal yang dilakukannya. Jika Anda dapat membuatnya bekerja dengan bash, Anda benar-benar tahu apa yang Anda lakukan.
Intinya adalah kami ingin berbicara dengan proses lain. Ini servernya:
# 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
Sekarang, skrip yang diharapkan melakukan keajaiban.
# 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
Perhatikan bahwa kami tidak hanya membuang perintah SMTP di server. Kami memeriksa setiap kode respons untuk memastikan semuanya baik-baik saja. Dalam hal ini, semuanya tidak akan baik-baik saja dan skrip akan ditebus.