2016-07-07 29 views
0

Im Folgenden beschreibe ich, mit was ich kämpfte und die Entscheidung, dass ich zur Zeit kam. Bitte weisen Sie mich auf die klüger/kleinere Entscheidungen, wäre auch gerne Rückmeldung erhalten.Bash: wie Telnet oder NC im Hintergrund arbeiten, bis die Verbindung geschlossen ist

Also, es gibt einen Verleger und einen Client auf einem localhost, sie kommunizieren über Port 8080. Ich kann telnet oder nc zu diesem Port und schreiben Ausgabe in ein Protokoll normal, aber kann nicht die gleichen Befehle im Hintergrund arbeiten.

Was ich sehe, ist, dass, wenn im Hintergrund gestartet sie stoppen sofort nach dem ersten Eingang bekommen (ist es wirklich so?), aber im Vordergrund sie arbeiten, wie sie sollten und sterben erst nach Verlag Verbindung an diese schließt Hafen.

Dies ist, was normalerweise auftritt:

> telnet localhost 8080 | tee output.log (or >>output.log, no matter) 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 

Verlag startet Informationen über den Port zu senden.

***some necessary output*** 

Publisher schließt den Port.

Connection closed by foreign host. 

Aber wenn im Hintergrund gestartet stoppt sofort, ohne für die Ausgabe zu warten:

> 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. 

Antwort

1

Sie verwenden einen netcat Befehl statt:

nohup nc -d localhost 8080 >>console-8080.txt & 

Wenn Sie die Protokolldatei mit dem Datum einrücken möchten:

nohup nc -d localhost 8080 | while read line ; do echo `date +'%d%m%Y-%H%M%S'`: $line >>console-8080.txt; done & 

nc Prozess im Fall neu zu starten schließt:

#!/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

Hier ist ein Skript, das erwarten zu `ve kommen. Es wird im Hintergrund gestartet.

nohup ./telnet_expect.sh & 

Das Skript laicht neue Bash-Sitzung und übliche Umleitung in eine Datei ausführt.

Normalerweise arrangiere ich die Kommunikation zwischen bash und expect über env Variablen, hier habe ich es nicht implementiert, weil der ganze Anwendungsfall klein genug ist.

#!/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: unten ist mehr konfigurierbare Version, die Protokolldatei als ein Argument nimmt. Dies ist, wie zu starten:

nohup ./telnet_expect.sh <your_output_log_file> & 

Die Werte von IP und den Port hier werden nur einmal definiert, so dass es leicht ist, sie zu Argumenten zu bewegen, wie gut. Außerdem gibt es ein Debug-Protokoll und ein Konsolenprotokoll, um zu verstehen, was genau vor sich geht. Der Benutzer kann einen absoluten oder relativen Pfad zu einer Protokolldatei angeben.

#!/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"