我遇到了 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