Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何访问子流程的STDIN?_Linux_Bash_Subprocess_Stdin_Netcat - Fatal编程技术网

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
此脚本将文件名作为输入。例如,在您的环境中尝试这些命令(whit
netcat-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