摘要:如何在后台运行交互式任务?
详细信息:我正在尝试在ash shell(Busybox)下运行此简单脚本作为后台任务。
myscript.sh&
但是脚本立即停止...
[1] +已停止(tty输入)myscript.sh
myscript.sh的内容...(仅是相对的部分,其他则是我捕获SIGINT,SIGHUP等)
#!/bin/sh
catpid=0
START_COPY()
{
cat /dev/charfile > /path/outfile &
catpid = $!
}
STOP_COPY()
{
kill catpid
}
netcat SOME_IP PORT | while read EVENT
do
case $EVENT in
start) START_COPY;;
stop) STOP_COPY;;
esac
done
通过简单的命令行测试,我发现bot cat和netcat尝试从tty中读取。请注意,此netcat版本没有-e来限制tty。
现在可以做些什么来避免myscript停止运行?
我尝试过的事没有成功:
1)netcat / cat ... dev / tty(或tty
的输出)
2)使用()在子外壳中运行包含cat和netcat的块。这可能有效,但是然后如何获取cat的PID?
交给您的专家...
问题仍然存在。一个简单的测试供大家尝试:
1)在一个终端中运行netcat -l -p 11111(不带&)
2)在另一个终端中,运行netcat localhost 11111&(这应该在一段时间后停止,并显示消息Stopped(TTY输入))
如何避免这种情况?
您可能想要netcat's "-d" option
,它告诉它不要从STDIN
中读取。
我可以确认-d
将帮助netcat在后台运行。
我在遇到相同的问题:
nc -ulk 60001 | nc -lk 60002 &
每次查询jobs
时,管道输入都会停止。
将命令更改为以下内容进行了修复:
nc -ulkd 60001 | nc -lk 60002 &
您确定已按原样提供了脚本,还是只是键入了一个粗略的传真来说明总体思路?您问题中的脚本有很多错误,应该会阻止它正常运行,这让我感到奇怪。
=
中catpid=$!
周围的空格使该行无效。如果那是您的原始脚本中的内容,我很惊讶您没有收到任何错误。
kill catpid
行应该失败,因为文字catpid
不是有效的作业ID。您可能需要kill "$catpid"
。
关于您的实际问题:
cat
应该从/dev/charfile
读取,而不是从stdin或其他任何地方读取。您确定它正在尝试读取tty输入吗?
[如果您不需要netcat
来读取任何内容,是否尝试过重定向netcat < /dev/null
的输入,例如netcat
?
我必须使用没有-d选项的netcat。
“ echo -n | netcat ...&”似乎是一种有效的解决方法:即,如果不需要使用标准输入,请立即关闭netcat的标准输入。
由于尚未真正回答,如果使用Busybox且-d选项不可用,则以下命令在发送到后台时将使netcat保持“活动”状态:
tail -f /dev/null | netcat ...
[netcat < /dev/null
和echo -n | netcat
对我不起作用。
将screen
和disown
合并处理对我有用,因为'-d'选项对netcat不再有效。尝试过像nc </dev/null
这样的重定向,但是会话过早结束(因为我需要-q 1以确保在文件传输完成后nc进程停止)
[首先设置接收方,
在接收方,屏幕可能会为标准输入保留netcat的标准输入,因此它不会终止
编辑:我错了,您需要输入命令INSIDE screen
。如果将screen
命令的内联重定向到nc
,您将没有保存任何文件,或者在附加到screen
时终端中出现奇怪的二进制内容。 (例如,这是错误的方式:[)screen nc -l -p <listen port> -q 1 > /path/to/yourfile.bin
screen
,然后在欢迎消息上按return/Enter
。将会出现新的空白外壳(您现在在屏幕内)nc -l -p <listen port> -q 1 > /path/to/yourfile.bin
CTRL + a
,然后按d
以分离屏幕。在发送方,拒绝过程
cat </path/to/yourfile.bin> | nc <recv ip/hostname> <port> & disown