gpt4 book ai didi

linux - 尝试在没有阅读器的情况下编写时捕获 SIGPIPE

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:32:49 25 4
gpt4 key购买 nike

我正在尝试在 Bash 中的两个进程之间实现命名管道通信解决方案。

第一个进程向命名管道写入内容:

send(){
echo 'something' > $NAMEDPIPE
}

第二个脚本应该像这样读取命名管道:

while true;do
if read line < $NAMEDPIPE;do
someCommands
fi
done

注意之前已经使用传统命令创建了命名管道

mkfifo $NAMEDPIPE

我的问题是读取器脚本并不总是运行,因此如果写入器脚本尝试写入命名管道,它将一直处于阻塞状态,直到读取器连接到管道。

我想避免这种行为,解决方案是捕获 SIGPIPE 信号。事实上,根据 man 7 的说法,当试图在没有阅读器的管道中写入时,应该发送信号。所以我改变了我的红色功能:

read(){
trap 'echo "SIGPIPE received"' SIGPIPE
echo 'something' > $NAMEDPIPE
}

但是当我运行阅读器脚本时,脚本保持阻塞状态,并且不会打印“SIGPIPE received”。

我是对信号机制有误解还是有更好的解决方案来解决我的问题?

最佳答案

这是我刚刚制作的一个有趣的代码。也许你可以引用这个:

#!/bin/bash

shopt -s extglob

NAMEDPIPE=/var/run/sr-pipe
RECEIVER_PID_FILE=/var/run/sr-receiver-pid

function sender_start {
# Create named pipe.

if [[ -e $NAMEDPIPE ]]; then
echo "[Sender] Named pipe \"$NAMEDPIPE\" already exists."
else
echo "[Sender] Creating named pipe \"$NAMEDPIPE\"."
mkfifo "$NAMEDPIPE" || {
echo "Failed to create named pipe \"$NAMEDPIPE\"."
exit 1
}
fi

# Wait for receiver.

echo "[Sender] Waiting for receiver."
local PID
until [[ -e $RECEIVER_PID_FILE ]] \
&& read PID < "$RECEIVER_PID_FILE" \
&& [[ $PID == +([[:digit:]]) ]] \
&& kill -s 0 "$PID" &>/dev/null; do
sleep 1s
done
echo "[Sender] Receiver is [now] active."

# Send signal.

kill -s SIGPIPE "$PID"

# Send messages.

local SEND=''

echo "[Sender] Now sending messages."
while sleep 1s; do
SEND=$RANDOM
echo "[Sender] Sending $SEND."
echo "$SEND" >&4
done 4>"$NAMEDPIPE"
}

function receiver_start {
echo "$BASHPID" > "$RECEIVER_PID_FILE"

echo "[Receiver] Receiver is now active."

local QUIT=false RECEIVE=false

trap 'RECEIVE=true' SIGPIPE
trap 'QUIT=true' SIGINT SIGTERM SIGHUP

while [[ $QUIT == false ]]; do
if [[ $RECEIVE == true ]]; then
RECEIVE=false
echo "[Receiver] Now receiving messages."
while [[ $QUIT == false ]] && IFS= read -r -u 4 LINE; do
echo "[Receiver] Received $LINE."
done 4<"$NAMEDPIPE"
fi
sleep 1s
done
}

if [[ $1 == send ]]; then
sender_start
elif [[ $1 == receive ]]; then
receiver_start
fi

我在一个终端上运行了这个:

# bash sender-receiver.sh send
[Sender] Named pipe "/var/run/sr-pipe" already exists.
[Sender] Waiting for receiver.
[Sender] Receiver is [now] active.
[Sender] Now sending messages.
[Sender] Sending 21524.
[Sender] Sending 1460.
[Sender] Sending 8352.
[Sender] Sending 4424.
...

在另一个上我得到了这个(更正):

# bash sender-receiver.sh receive
[Receiver] Receiver is now active.
[Receiver] Now receiving messages.
[Receiver] Received 21524.
[Receiver] Received 1460.
[Receiver] Received 8352.
[Receiver] Received 4424.
...

您可能可以在同一终端上在后台运行发送方,在前台运行接收方。

关于linux - 尝试在没有阅读器的情况下编写时捕获 SIGPIPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24201856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com