netcat的Linux脚本在x小时后停止工作

我必须脚本:

#!/bin/bash netcat -lk -p 12345 | while read line do match=$(echo $line | grep -c 'Keep-Alive') if [ $match -eq 1 ]; then [start a command] fi done 

 #!/bin/bash netcat -lk -p 12346 | while read line do match=$(echo $line | grep -c 'Keep-Alive') if [ $match -eq 1 ]; then [start a command] fi done 

我已经把这两个脚本放在'/etc/init.d/'

当我重启我的Linux机器(RasbPi)时,两个脚本都能正常工作。

我已经尝试过20次,并且保持正常工作。

但大约12个小时后,整个系统停止工作。 我已经把一些login,但似乎脚本没有反应了。 但是当我;

 ps aux 

我可以看到脚本仍在运行:

 root 1686 0.0 0.2 2740 1184 ? S Aug12 0:00 /bin/bash /etc/init.d/script1.sh start root 1689 0.0 0.1 2268 512 ? S Aug12 0:00 netcat -lk 12345 root 1690 0.0 0.1 2744 784 ? S Aug12 0:00 /bin/bash /etc/init.d/script1.sh start root 1691 0.0 0.2 2740 1184 ? S Aug12 0:00 /bin/bash /etc/init.d/script2.sh start root 1694 0.0 0.1 2268 512 ? S Aug12 0:00 netcat -lk 12346 root 1695 0.0 0.1 2744 784 ? S Aug12 0:00 /bin/bash /etc/init.d/script2.sh start 

重新启动后,他们再次开始工作……但这是一个罪过,定期重新启动一台Linux机器…

我插入了一些logging,这是结果;

 Listening on [0.0.0.0] (family 0, port 12345) [2013-08-14 11:55:00] Starting loop. [2013-08-14 11:55:00] Starting netcat. netcat: Address already in use [2013-08-14 11:55:00] Netcat has stopped or crashed. [2013-08-14 11:49:52] Starting loop. [2013-08-14 11:49:52] Starting netcat. Listening on [0.0.0.0] (family 0, port 12345) Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6333) Connection closed, listening again. Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6334) [2013-08-14 12:40:02] Starting loop. [2013-08-14 12:40:02] Starting netcat. netcat: Address already in use [2013-08-14 12:40:02] Netcat has stopped or crashed. [2013-08-14 12:17:16] Starting loop. [2013-08-14 12:17:16] Starting netcat. Listening on [0.0.0.0] (family 0, port 12345) Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6387) Connection closed, listening again. Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6388) [2013-08-14 13:10:08] Starting loop. [2013-08-14 13:10:08] Starting netcat. netcat: Address already in use [2013-08-14 13:10:08] Netcat has stopped or crashed. [2013-08-14 12:17:16] Starting loop. [2013-08-14 12:17:16] Starting netcat. Listening on [0.0.0.0] (family 0, port 12345) Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6167) Connection closed, listening again. Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6168) 

谢谢

Solutions Collecting From Web of "netcat的Linux脚本在x小时后停止工作"

关于循环,它可能看起来像这样。

 #!/bin/bash for (( ;; )) do netcat -lk -p 12345 | while read line do match=$(echo "$line" | grep -c 'Keep-Alive') if [ "$match" -eq 1 ]; then [start a command] fi done sleep 4s done 

加双引号保持安全。

你可以尝试捕获错误,并添加一些这种格式的日志记录:

 #!/bin/bash { echo "[$(date "+%F %T")] Starting loop." for (( ;; )) do echo "[$(date "+%F %T")] Starting netcat." netcat -lk -p 12345 | while read line do match=$(echo "$line" | grep -c 'Keep-Alive') if [ "$match" -eq 1 ]; then [start a command] fi done echo "[$(date "+%F %T")] Netcat has stopped or crashed." sleep 4s done } >> "/var/log/something.log" 2>&1 

您的读取命令在这种格式下也可能会更好,因为它会读取未修改的行:

 ... | while IFS= read -r line 

有些人也可能会建议使用流程替代,但是这次我不推荐这样做 | while ...方法while循环将能够在子shell上运行,并保持外部for循环安全以防万一它崩溃。 除此之外, while循环中并没有真正的变量, while循环在外面是需要的。

实际上,我现在的想法是,这个问题实际上可能与输入有关,以及如何while read line; do ...; done while read line; do ...; done while read line; do ...; done块处理它, 而不是netcat本身 。 你的变量没有正确引用“”可能是其中之一, 或者可能是你的netcat崩溃的实际原因

如果没有包括netcat的命令从标准输入读取输入,则可以完全独立于终端运行。 有时后台进程仍然依赖于终端暂停(S),当他们尝试从背景上读取输入。 实际上,因为你正在运行一个守护进程,你应该确保你的命令都没有从它(终端)读取输入。

 #!/bin/bash set +o monitor # Make sure job control is disabled. ( : # Make sure the shell runs a subshell. exec netcat -lk -p 12345 | while read line ## Use exec to overwrite the subshell. do match=$(echo $line | grep -c 'Keep-Alive') if [ $match -eq 1 ]; then [start a command] fi done ) <&- >&- 2>&- </dev/null &>/dev/null & TASKPID=$! sleep 1s ## Let the task initialize a bit before we disown it. disown "$TASKPID" 

而且我认为我们可以再次尝试日志记录的事情:

 set +o monitor ( echo "[$(date "+%F %T")] Starting loop with PID $BASHPID." for (( ;; )) do echo "[$(date "+%F %T")] Starting netcat." netcat -vv -lk -p 12345 | while read line do match=$(echo "$line" | grep -c 'Keep-Alive') if [ "$match" -eq 1 ]; then [start a command] fi done echo "[$(date "+%F %T")] Netcat has stopped or crashed." sleep 4s done ) <&- >&- 2>&- </dev/null >> "/var/log/something.log" 2>&1 & TASKPID=$! sleep 1s disown "$TASKPID" 

你提到“大约12个小时之后,整个系统停止工作” – 这些脚本很可能正在执行任何你在[start a command]并且膨胀了内存的东西。 你确定[start a command]是不是非常频繁地分出很多进程并释放内存?

我经常用nc或者netcat经历奇怪的行为。 你应该看看ncat它几乎是相同的工具,但它在所有平台上表现相同( ncnetcat行为有所不同,取决于distri,linux,BSD,Mac)。

定期netcat会打印,而不是一行,但一块二进制数据。 读内建可能会因此失败。

我想你使用这个程序来验证远程主机仍然连接到端口12345和12346,并没有重新启动。

我的解决方案是将netcat的输出管道sed,然后管(减少)线到读内置…

 #!/bin/bash { echo "[$(date "+%F %T")] Starting loop." for (( ;; )) do echo "[$(date "+%F %T")] Starting netcat." netcat -lk -p 12345 | sed 's/.*Keep-Alive.*/Keep-Alive/g' | \ \ while read line do match=$(echo "$line" | grep -c 'Keep-Alive') if [ "$match" -eq 1 ]; then [start a command] fi done echo "[$(date "+%F %T")] Netcat has stopped or crashed." sleep 4s done } >> "/var/log/something.log" 2>&1 

另外,还需要查看一下/etc/init.d中的其他一些启动程序,以确保它们与系统使用的任何版本的rc兼容,但是调用script2.sh会更容易init.d中的一些简单文件的副本 就目前而言,脚本2是启动脚本,但不符合您使用的init软件包。

这听起来更复杂,我的意思是…让我更好地解释:

 /etc/init.d/syslogd ## a standard init script that calls syslogd /etc/init.d/start-monitor ## a copy of a standard init script that calls script2.sh 

作为附加说明,我认为你可以将netcat绑定到你正在监视的特定IP地址,而不是绑定到所有地址0.0.0.0

在等待传入连接请求的情况下,您可能不会使用-p选项。 (请参阅nc的手册页)主机名和端口是命令行的最后两个参数。

可能是连接到自己的端口,几个小时后有一些资源丢失?