我必须要脚本:
#!/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个小时后,整个系统停止工作。我已经添加了一些loggin,但似乎脚本不再响应了。但是当我;
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机器......
我已插入一些loggin,这是结果;
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)
由于
答案 0 :(得分:5)
关于循环它可能看起来像这样。
#!/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上运行并保留外部{ {1}}循环安全以防它崩溃。此外,实际上并不存在for
循环中需要的变量。
我实际上已经知道这个问题可能实际上与输入有关, while
块如何处理它而不是netcat本身。您的变量未被正确引用可能是其中之一,或者可能是实际原因为什么您的netcat崩溃。
答案 1 :(得分:5)
如果你的命令没有包括netcat从stdin读取输入,你可以完全使它独立于终端运行。有时,仍然依赖于终端的后台进程在尝试从后台读取输入时会暂停(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"
答案 2 :(得分:3)
你提到“大约12个小时之后,整个系统停止工作” - 脚本可能正在执行[start a command]
中的任何内容,并使内存膨胀。你确定[start a command]
不是经常分发许多进程并释放内存吗?
答案 3 :(得分:3)
我经常遇到nc
或netcat
的奇怪行为。您应该看一下ncat
几乎相同的工具,但它在所有平台上的行为都相同(nc
和netcat
表现不同,具体取决于distri,linux,BSD,Mac)。 / p>
答案 4 :(得分:2)
定期netcat将打印,而不是一行,而是一块二进制数据。因此,内置读取可能会失败。
我认为您正在使用此程序验证远程主机是否仍连接到端口12345和12346并且尚未重新启动。
我的解决方案是将netcat的输出传递给sed,然后将那个(大大减少的)一行传递给read builtin ...
#!/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兼容,但是,调用您的脚本2会容易得多.sh从init.d中的一些简单文件的副本。目前,script2是启动脚本,但不符合您使用的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
答案 5 :(得分:1)
如果您要等待传入的连接请求,则不能使用-p选项。 (参见nc的手册页)Hostname和Port是命令行的最后两个参数。
可能是它连接到自己的端口,几个小时后会丢失一些资源吗?