哪裏有需求,有辦法!我認爲這是一個很好的bash課程,可以看到 流程管理和ipc是如何工作的。當然,最好的解決方案是預期。 但真正的原因是管道可能會非常棘手,許多命令設計爲等待數據,這意味着該過程將成爲殭屍,因爲難以預測的原因。但是學習如何以及爲什麼會讓我們想起 正在發生什麼。
當兩個進程進行對話時,其中一個或兩個進程會嘗試讀取永遠不會到達的數據。交戰規則必須是清晰的 。像CRLF和字符編碼這樣的東西可能會殺死這個派對。 幸運的是,像bash腳本和它的子進程這樣的兩個關係密切的合作伙伴 相對容易保持一致。最容易遺漏的是bash是 幾乎爲它所做的每件事都啓動了一個子進程。如果你可以讓 與bash一起工作,你完全知道你在做什麼。
問題是我們想要與另一個進程交談。這裏是一個服務器:
# 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
現在,腳本,希望做的魔術。
# 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
請注意,我們不是簡單地在服務器上轉儲SMTP命令。我們檢查 每個響應代碼,以確保事情是確定的。在這種情況下,事情不會是 行,腳本將保釋。
這符合我的目的。我不確定標準輸出的位置。 – rup 2010-08-12 10:37:21