linux bash 后台运行和 I/O 重定向

linux bash 后台运行和 I/O 重定向

我遇到了 bash 后台和文件重定向问题。

我需要连接到远程传感器盒并将该盒中的 ascii 数据流记录到磁盘文件中。我想将该数据流分成大约 10 分钟的片段,并在文件名后加上日期时间戳。

为此,我有一个脚本,它可以生成一个文件名,并使用 连接到远程框nc > filename。(请注意,我在附加代码中将时间设置为 1 分钟,而不是 10 分钟)。

该脚本按预期将数据记录到生成的文件名中:

#!/bin/bash
DEST=/home/sensors/gps1
[[ -d $DEST ]] || mkdir -p $DEST

while true

do

  DESTFILE=$DEST/"gps1-freq-ref-capture-"`date +"%Y-%m-%d-%H%M"`

  nc fepts03 20014 > $DESTFILE
  NCPID=$!

  sleep 60 ; kill $NCPID

done

但执行从未结束nc

nc另一方面,Backgrounding给出了正确的文件名,但它们是空文件。

 #!/bin/bash
DEST=/home/sensors/gps1
[[ -d $DEST ]] || mkdir -p $DEST

while true

do

  DESTFILE=$DEST/"gps1-freq-ref-capture-"`date +"%Y-%m-%d-%H%M"`

  nc fepts03 20014 > $DESTFILE &     # <-- note backgrounding ampersand
  NCPID=$!

  sleep 60 ; kill $NCPID

done

但文件是空的:

$ ls -la
-rw-rw-rw-+  1 sensors sensors     0 Jul 23 15:00 gps1-freq-ref-capture-2012-07-23-1500
-rw-rw-rw-+  1 sensors sensors     0 Jul 23 15:01 gps1-freq-ref-capture-2012-07-23-1501
-rw-rw-rw-+  1 sensors sensors     0 Jul 23 15:02 gps1-freq-ref-capture-2012-07-23-1502

我认为这是一个 stdin/stdout 控制台的问题,因此我尝试在 dtach 会话中运行,结果相同:文件名不错,没有数据。

答案1

如果另一端没有任何可连接的内容,则输出文件将为空。请在netstat -ln | grep portnumber服务器上检查。如果另一端是 netcat 的另一个实例,则需要等待它在客户端退出后执行并等待新进程启动。

$ cat connect-and-wait.sh
#!/bin/sh

dir=/home/jaroslav/tmp/so/nc-for-5-sec

while true; do
    now=`date +%Y-%m-%d.%H:%M:%S`
    fil=gps1-freq-ref-capture-$now
    out=$dir/$fil

    nc eee.lan 5555 > $out &
    pid=$!

    sleep 5 && kill $pid && echo wrote $out
    #sleep 1;                                  <-- try this 
done

这种方法存在缺陷,因为重新连接时必然会丢失数据。如果另一端确实是 的另一个实例nc,那么在 shell 循环中重新启动服务器就会有问题(根据我的经验,它有时会无法重新绑定)。因此,请尝试保持一个连接并对输出进行一些操作:

$ cat connect-and-rotate-log.sh
#!/bin/sh

dir=/home/jaroslav/tmp/so/nc-for-5-sec

now=out
fil=gps1-freq-ref-capture-$now
out_=$dir/$fil

nc eee.lan 5555 > $out_ &

while [ -f $out_ ]; do
    now=`date +%Y-%m-%d.%H:%M:%S`
    fil=gps1-freq-ref-capture-$now
    out=$dir/$fil

    sleep 5
    echo wrote $out

    cp $out_ $out
    echo > $out_
done

它并不完美,但更好。此外,您可能还想检查连接,nmap例如:

nmap eee.lan -p 5555 | grep -q  '^5555.*open' && echo open

相关内容