下面我描述了我正在努力解决的问题以及我目前的决定。 请指出更聪明/更小的决定,也很乐意收到反馈。
因此,本地主机上有一个发布者和一个客户端,它们通过端口8080进行通信。我可以telnet或者nc到这个端口并正常地将输出写入日志,但不能使相同的命令在后台运行。
我看到的是,当它们在后台启动时,它们会在获得第一个输入后立即停止( 它真的如此吗? ),但在前景中它们可以正常工作发布商在此端口关闭连接后才会死亡。
这是正常情况:
> telnet localhost 8080 | tee output.log (or >>output.log, no matter)
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Publisher开始通过端口发送信息。
***some necessary output***
Publisher关闭端口。
Connection closed by foreign host.
但是当它在后台启动时会立即停止,无需等待输出:
> nohup telnet localhost 8080 | tee output.log (or <command> &, or nohup <command> &)
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
答案 0 :(得分:2)
您改为使用netcat命令:
nohup nc -d localhost 8080 >>console-8080.txt &
如果要使用日期缩进日志文件:
nohup nc -d localhost 8080 | while read line ; do echo `date +'%d%m%Y-%H%M%S'`: $line >>console-8080.txt; done &
要在关闭时重新启动nc进程:
#!/bin/bash
ip=$1
port=$2
while [ 1 ]
do
nc -d $ip $port | while read line ; do echo `date +'%d%m%Y-%H%M%S'`: $line >>console-$ip-$port.txt; done
sleep .1
done
答案 1 :(得分:1)
这是我要来的期望剧本。它正在后台推出。
nohup ./telnet_expect.sh &
该脚本生成新的bash会话并执行通常的文件重定向。
通常我会安排bash之间的通信和期望通过env变量,这里我没有实现它,因为整个用例足够小。
#!/bin/bash
echo -e "\n$(date +%Y-%m-%d_%H:%M:%S,%3N) -- Started telnet_expect.sh\n"
logFile="/export/home/<user>/<folder>/output.log"
logFileExpect="/export/home/<user>/<folder>/expect.log"
echo > "$logFile"
echo > "$logFileExpect"
until nc -w 1 localhost 8080
do
sleep 1
done
expect -c "
log_user 1
set timeout 250
proc err_exit {msg} {
puts \"---\"
puts stderr \"\$msg\"
send \"exit status: \$?\r\"
exit 1
}
exp_internal -f /export/home/<user>/<folder>/expect.log 1
spawn bash
send \"telnet localhost 8080 >> /export/home/<user>/<folder>/output.log\r\"
sleep 10
expect {
\"*onnection closed by foreign host*\" {
send \"echo Success\r\"
}
timeout {
err_exit \"\nError: timeout\n\"
}
}
send \"exit\r\"
expect eof
"
echo -e "\n$(date +%Y-%m-%d_%H:%M:%S,%3N) -- Finished telnet_expect.sh\n"
Upd:下面是更具可配置性的版本,它将日志文件作为参数。这是如何推出:
nohup ./telnet_expect.sh <your_output_log_file> &
此处的IP和端口值仅定义一次,因此很容易将它们移动到参数中。还有调试日志和控制台日志,以了解究竟发生了什么。用户可以提供日志文件的绝对或相对路径。
#!/bin/bash
scriptFolderPath=$(dirname $(readlink -f "$0"))
logDir="$scriptFolderPath"
logFileDefault="$logDir"/"output_default.log"
logFileExpect="$logDir"/"expect.log"
ip="localhost"
port="8080"
logConsole="$logDir"/"console_telnet.log"
echo > "$logConsole"
echo -e "\n$(date +%Y-%m-%d_%H:%M:%S,%3N) -- Started telnet_expect.sh\n" >> "$logConsole"
### debug info
logDebug="$logDir"/"debug_telnet.log"
echo > "$logDebug"
exec 5> "$logDebug"
BASH_XTRACEFD="5"
PS4='$LINENO: '
set -x
if [ -z "$1" ]; then
logFile="$logFileDefault"
else
if [[ $logFile =~ "/" ]]; then
logFile="$1"
else
echo "Got the log file in the same folder as the script" >> "$logConsole"
logFile="$scriptFolderPath"/"$1"
fi
fi
echo > "$logFile"
echo > "$logFileExpect"
### setting envs
echo -e "\nsetting BCKGR_TELNET_LOG" >> "$logConsole"
export BCKGR_TELNET_LOG="$logFile"
echo "set BCKGR_TELNET_LOG: $BCKGR_TELNET_LOG" >> "$logConsole"
echo -e "\nsetting BCKGR_TELNET_LOG_EXPECT" >> "$logConsole"
export BCKGR_TELNET_LOG_EXPECT="$logFileExpect"
echo -e "set BCKGR_TELNET_LOG_EXPECT: $BCKGR_TELNET_LOG_EXPECT\n" >> "$logConsole"
echo -e "\nsetting BCKGR_TELNET_LOG_PORT" >> "$logConsole"
export BCKGR_TELNET_LOG_PORT="$port"
echo -e "set BCKGR_TELNET_LOG_PORT: $BCKGR_TELNET_LOG_PORT\n" >> "$logConsole"
echo -e "\nsetting BCKGR_TELNET_LOG_IP" >> "$logConsole"
export BCKGR_TELNET_LOG_IP="$ip"
echo -e "set BCKGR_TELNET_LOG_IP: $BCKGR_TELNET_LOG_IP\n" >> "$logConsole"
until nc -w 1 "$ip" "$port"
do
sleep 1
done
expect -c "
log_user 1
set timeout 250
proc err_exit {msg} {
puts \"---\"
puts stderr \"\$msg\"
send \"exit status: \$?\r\"
exit 1
}
puts \"Reading BCKGR_TELNET_LOG_EXPECT\"
if {[info exists env(BCKGR_TELNET_LOG_EXPECT)]} {
set bckgr_telnet_log_expect $::env(BCKGR_TELNET_LOG_EXPECT)
puts \"Found BCKGR_TELNET_LOG_EXPECT\"
} else {
err_exit \"Error while reading env variable BCKGR_TELNET_LOG_EXPECT\"
}
puts \"Reading BCKGR_TELNET_LOG\"
if {[info exists env(BCKGR_TELNET_LOG)]} {
set bckgr_telnet_log $::env(BCKGR_TELNET_LOG)
puts \"Found BCKGR_TELNET_LOG\"
} else {
err_exit \"Error while reading env variable BCKGR_TELNET_LOG\"
}
puts \"Reading BCKGR_TELNET_LOG_PORT\"
if {[info exists env(BCKGR_TELNET_LOG_PORT)]} {
set bckgr_telnet_log_port $::env(BCKGR_TELNET_LOG_PORT)
puts \"Found BCKGR_TELNET_LOG_PORT\"
} else {
err_exit \"Error while reading env variable BCKGR_TELNET_LOG_PORT\"
}
puts \"Reading BCKGR_TELNET_LOG_IP\"
if {[info exists env(BCKGR_TELNET_LOG_IP)]} {
set bckgr_telnet_log_ip $::env(BCKGR_TELNET_LOG_IP)
puts \"Found BCKGR_TELNET_LOG_IP\"
} else {
err_exit \"Error while reading env variable BCKGR_TELNET_LOG_IP\"
}
exp_internal -f \$bckgr_telnet_log_expect 1
spawn bash
send \"telnet \$bckgr_telnet_log_ip \$bckgr_telnet_log_port >> \$bckgr_telnet_log\r\"
sleep 10
expect {
\"*onnection closed by foreign host*\" {
send \"echo Success\r\"
}
timeout {
err_exit \"\nError: timeout\n\"
}
}
send \"exit\r\"
expect eof
"
echo -e "\nUnsetting env variables" >> "$logConsole"
unset BCKGR_TELNET_LOG
unset BCKGR_TELNET_LOG_EXPECT
unset BCKGR_TELNET_LOG_PORT
unset BCKGR_TELNET_LOG_IP
echo -e "\n$(date +%Y-%m-%d_%H:%M:%S,%3N) -- Finished telnet_expect.sh\n" >> "$logConsole"