4

我想运行命令:

nc localhost 9998

然后我希望我的脚本监视一个文件,并在文件更改时将文件的内容回显到该子进程。

我无法制定重定向方案。如何访问子进程的 STDIN?

4

4 回答 4

2

怎么样

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
于 2011-07-06T10:31:13.087 回答
1
mkfifo X
some_program <X >output &
create_input >X

some_program将阻止读取 X 直到create_input写入它。

于 2011-07-06T14:01:15.853 回答
0

我认为可以接受的两种解决方案:

1) 使用协程,这样我们就可以通过 COPROC[0/1] 数组访问协程命令创建的进程的标准输入和标准输出。

2)我最终所做的是将我的应用程序分成两个代码块,如下所示。第一个块写入标准输出,然后通过管道传输到第二个块的标准输入。当第二个代码块中的 netcat 出现问题时,这为我提供了一种缓冲数据的干净方法:

{ while true;
  write to STDOUT; } |
{ while true
  nc localhost 9998 }

(实际上脚本要复杂得多,因为第二个命令在 netcat 无法连接时提供到磁盘缓冲,但使用管道提供缓冲,因此当网络问题中断 netcat 时数据不会丢失)

于 2011-07-07T03:30:00.887 回答
0

我找到了一个使用 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

该脚本将文件名作为输入。例如,在您的环境中尝试这些命令(netcat -l 9998运行时):

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

注意:临时文件会被陷阱清理掉,所以你可以优雅地中断这个脚本。

于 2011-07-07T03:59:18.283 回答