昔に書いたFIFOを使ってプロセス間通信をするシェルのサンプルスクリプトを見つけた。
全然覚えていない。
スクリプト中身を確認すると、FIFOを3つ作って、1つは読み書き用、残り2つは通信する2つのプロセスの状態を通知する為に使っているみたい。通信を5往復すると停止する仕組みになっています。
実行結果
$ ./fifo_test.sh
fifo_test.sh: app_KICK(905): begin
fifo_test.sh: app_A(913): begin
fifo_test.sh: app_B(914): begin
seq.0: app_B(914)->app_A(913): I am app_B, 2022/09/11(日) 23:40:18
seq.0: app_A(913)->app_B(914): I am app_A, 2022/09/11(日) 23:40:18
seq.1: app_B(914)->app_A(913): I am app_B, 2022/09/11(日) 23:40:18
seq.1: app_A(913)->app_B(914): I am app_A, 2022/09/11(日) 23:40:19
seq.2: app_B(914)->app_A(913): I am app_B, 2022/09/11(日) 23:40:19
seq.2: app_A(913)->app_B(914): I am app_A, 2022/09/11(日) 23:40:19
seq.3: app_B(914)->app_A(913): I am app_B, 2022/09/11(日) 23:40:19
seq.3: app_A(913)->app_B(914): I am app_A, 2022/09/11(日) 23:40:19
seq.4: app_B(914)->app_A(913): I am app_B, 2022/09/11(日) 23:40:20
seq.4: app_A(913)->app_B(914): I am app_A, 2022/09/11(日) 23:40:20
fifo_test.sh: app_A(913): end
fifo_test.sh: app_KICK(905): collection: app_A(913): fin.
fifo_test.sh: app_B(914): end
fifo_test.sh: app_KICK(905): collection: app_B(914): fin.
fifo_test.sh: app_KICK(905): /tmp/fifo_test.905: remove
fifo_test.sh: app_KICK(905): /tmp/fifo_test.905.A: remove
fifo_test.sh: app_KICK(905): /tmp/fifo_test.905.B: remove
fifo_test.sh: app_KICK(905): end
$
シェルスクリプト
[fifo_test.sh]
#!/bin/sh
fi_fifo_basename="fifo_test"
seq_count=5## script entry point
sh_main ()
{
sh_initarg="$1"
shift
if [ $? -ne 0 ]; then
appid="app_KICK"
else
case "$arg" in
'-a')
appid="app_A"
;;
'-b')
appid="app_B"
;;
*)
perr "$appname: $arg: unknown argument"
return -1
;;
esac
fi$appid ## Role playing
return $?
}## script setup
sh_init ()
{
di_work="`pwd`"
appname="`basename \"$0\"`"
di_tmp="`dirname \"$0\"`"
cd "$di_tmp/"; apppath="`pwd`"; cd "$di_work/"
unset di_tmp
pid="$$"
}## error output
perr ()
{
echo "$@" 1>&2
}## user interrupt
func_trap_SIGINT ()
{
echo "*** Interrupt ***"
# jobs
# kill %1
# kill %2
for cldpid in `ps -f | awk -v PID="$$" '
$3==PID {
print ($2) ;
}'`; do
# echo "cldpid=$cldpid"
kill "$cldpid"
donefunc_cleanup
}## wait
func_wait_term ()
{
cat "$1" | sed "s/^/$appname: $appid($$): collection: /"
}## notify
func_notify_term ()
{
echo "$appid($$): fin." > "$1"
}## app KICK
app_KICK ()
{
echo "$appname: $appid($$): begin"func_initialize
"$apppath/$appname" "-a" &
"$apppath/$appname" "-b" &
trap func_trap_SIGINT SIGINT# sleep 3
func_wait_term "$FI_TERM_A"
func_wait_term "$FI_TERM_B"
trap - SIGINTfunc_cleanup
echo "$appname: $appid($$): end"
}## app A
app_A ()
{
echo "$appname: $appid($$): begin"func_check_callseq "$FI_TERM_A"
idx=0
while [ $idx -lt $seq_count ]; do
func_recv
func_send "I am $appid: `date '+%Y/%m/%d(%a) %H:%M:%S'`"idx=`expr $idx + 1`
doneecho "$appname: $appid($$): end"
func_notify_term "$FI_TERM_A"
}## app B
app_B ()
{
echo "$appname: $appid($$): begin"func_check_callseq "$FI_TERM_B"
idx=0
while [ $idx -lt $seq_count ]; do
func_send "Iam $appid: `date '+%Y/%m/%d(%a) %H:%M:%S'`"
func_recvidx=`expr $idx + 1`
doneecho "$appname: $appid($$): end"
func_notify_term "$FI_TERM_B"
}## check routine
func_check_callseq ()
{
notify_fifo="$1"if [ "$FI_FIFO" = "" ]; then
perr "$appname: $appid($$): \$FI_FIFO: undefined"
perr "$appname: could not call the $arg option directly"
exit -1
fi
if [ ! -p "$FI_FIFO" ]; then
perr "$appname: $appid($$): $FI_FIFO: fifo not found"
exit -1
fiif [ "$notify_fifo" = "" ]; then
perr "$appname: $appid($$): \$notify_fifo: undefined"
exit -1
fi
if [ ! -p "$notify_fifo" ]; then
perr "$appname: $appid($$): $notify_fifo: fifo not found"
exit -1
fi
}## send
func_send ()
{
echo "$appid($$): $1" > "$FI_FIFO"
}## recv
func_recv ()
{
cat "$FI_FIFO" | sed "s/: /->$appid($$): /" | sed "s/^/seq.$idx: /"
}## initialize
func_initialize ()
{
FI_FIFO="/tmp/$fi_fifo_basename.$pid"
export FI_FIFO
mkfifo "$FI_FIFO"FI_TERM_A="$FI_FIFO.A"
export FI_TERM_A
mkfifo "$FI_TERM_A"FI_TERM_B="$FI_FIFO.B"
export FI_TERM_B
mkfifo "$FI_TERM_B"
}## cleanup
func_cleanup ()
{
if [ -p "$FI_FIFO" -o -f "$FI_FIFO" ]; then
echo "$appname: $appid($$): $FI_FIFO: remove"
rm -f "$FI_FIFO"
fiif [ -p "$FI_TERM_A" -o -f "$FI_TERM_A" ]; then
echo "$appname: $appid($$): $FI_TERM_A: remove"
rm -f "$FI_TERM_A"
fiif [ -p "$FI_TERM_B" -o -f "$FI_TERM_B" ]; then
echo "$appname: $appid($$): $FI_TERM_B: remove"
rm -f "$FI_TERM_B"
fi
}sh_main "$@"
exit $?