Linux 如何访问子流程的STDIN?
我要运行以下命令:Linux 如何访问子流程的STDIN?,linux,bash,subprocess,stdin,netcat,Linux,Bash,Subprocess,Stdin,Netcat,我要运行以下命令: nc localhost 9998 然后,我希望我的脚本监视一个文件,并在文件更改时将文件内容回显到此子进程 我无法制定出重新定向计划。如何访问子流程的STDIN?如何 tail -f $file |nc localhost 9998 编辑: 既然您已经有了缓冲区,那么您可以尝试以下方法: while [ 1 ]; do # Your stuff here. buf=yourfunctionhere buffer=$buffer$buf
nc localhost 9998
然后,我希望我的脚本监视一个文件,并在文件更改时将文件内容回显到此子进程
我无法制定出重新定向计划。如何访问子流程的STDIN?如何
tail -f $file |nc localhost 9998
编辑:
既然您已经有了缓冲区,那么您可以尝试以下方法:
while [ 1 ]; do
# Your stuff here.
buf=yourfunctionhere
buffer=$buffer$buf
if [ ! -z $buffer ]; then
echo $buffer |nc localhost 9998
# Empty buffer on success.
if [ $? -eq 0 ]; then
buffer="";
fi
fi
done
mkfifox
一些程序输出&
创建输入>X
某些程序将阻止读取X,直到创建输入写入它。我发现两种解决方案是可以接受的:
1) 使用协进程,这样我们就可以通过COPROC[0/1]数组访问由协进程命令创建的进程的stdin和stdout
2) 我最终将我的应用程序分成两个代码块,如下所示。第一个块写入标准输出,然后通过管道传输到第二个块的标准输入。这为我在第二个代码块中出现netcat问题时提供了一种干净的缓冲数据的方法:
{ while true;
write to STDOUT; } |
{ while true
nc localhost 9998 }
(实际上,当netcat无法连接时,脚本要复杂得多,因为第二个命令提供了磁盘缓冲,但管道的使用提供了缓冲,这样当网络问题中断netcat时,数据就不会丢失)我找到了一个使用diff和简单bash脚本的解决方案
文件更改时,以下脚本将执行cat$file>$namedpipe
。这是我制作的脚本check file.sh
:
#!/bin/bash
file=$1
tmp=`mktemp`
cp "$file" "$tmp"
namedpipe=`mktemp`
rm -rf $namedpipe
mkfifo $namedpipe
function cleanup() {
echo "end of program"
rm -rf $tmp
rm -rf $namedpipe
exit 1;
}
trap cleanup SIGINT
tail -f $namedpipe 2> /dev/null | netcat localhost 9998 &
while true; do
diff=$(diff "$file" "$tmp")
if [ ! -z "$diff" ]; then
cat $file > $namedpipe
cp $file $tmp
fi
sleep 1
done
此脚本将文件名作为输入。例如,在您的环境中尝试这些命令(whitnetcat-l 9998
running):
注意:临时文件被陷阱清除,因此您可以优雅地中断此脚本。我的脚本有点复杂。实际上,文件每分钟都会被截断和重新写入(状态文件),我只需要解析出一些行来发送到套接字。最重要的是,当套接字不可用时,我想写入一个缓冲区,这样我就不会错过任何状态更新。我有一个脚本可以完成所有这些,但我需要将数据发送到服务器。使用exec 3/dev/tcp/host/port无法让我知道连接何时失败,使用nc,我至少可以在套接字故障(服务器重新启动、网络问题等)时捕获nc关闭。如果您已经实现了缓冲区,那么您可以通过nc发送,您可以在每次需要时执行nc并检查退出状态。@PacoRG:这将为每个新数据块建立新的TCP连接。根据最初的问题,这不是我们想要的。我认为,如果您在整个while循环中使用parens来创建子shell,并将子shell输出输送到nc
,它应该可以工作。
#!/bin/bash
file=$1
tmp=`mktemp`
cp "$file" "$tmp"
namedpipe=`mktemp`
rm -rf $namedpipe
mkfifo $namedpipe
function cleanup() {
echo "end of program"
rm -rf $tmp
rm -rf $namedpipe
exit 1;
}
trap cleanup SIGINT
tail -f $namedpipe 2> /dev/null | netcat localhost 9998 &
while true; do
diff=$(diff "$file" "$tmp")
if [ ! -z "$diff" ]; then
cat $file > $namedpipe
cp $file $tmp
fi
sleep 1
done
touch /tmp/test
bash check-file.sh /tmp/test &
echo "change 1" > /tmp/test
sleep 1
echo "change 2" > /tmp/test
sleep 1
echo "change 3" > /tmp/test