Reputation: 1141
I have the following scenario:
I use netcat
to connect to a host running telnet
server on port 23, I log in using provided username and password, issue some commands, after which I need to do fairly complex analysis of the provided output. Naturally, expect
comes to mind, with a script like this:
spawn nc host 23
send "user\r"
send "pass\r"
send "command\r"
expect EOF
then, it is executed with expect example.scr >output.log
, so the output file can be parsed. The parser is 150+ lines of bash
code that executes under 2 seconds, and makes a decision what command should be executed next. Thus, it replaces "command" with "command2", and executes the expect
script again, like this:
sed -i '/send "command\r"/send "command2\r"/' example.scr
expect example.scr >output.log
Obviously, it is not needed to re-establish telnet
connection and perform log in process all over again, just to issue a single telnet
command after 2 seconds of processing. A conclusion can be made, that telnet
session should be kept alive as a background process, so one could freely talk to it at any given time. Naturally, using named pipes
comes to mind:
mkfifo in
mkfifo output.log
cat in | nc host 23 >output.log &
echo -e "user\npass\ncommand\n" >in
cat output.log
After the file is written to, EOF
causes the named pipe
to close, thus terminating the telnet
session. I was thinking what kind of eternal process could be piped to netcat
so it can be used as telnet
relay to host. I came up with a very silly idea, but it works:
nc -k -l 666 | nc host 23 >output.log &
echo -e "user\npass\ncommand\n" | nc localhost 666
cat output.log
The netcat
server is started with k(eep alive), listening on port 666, and any data stream is redirected to the netcat
telnet
client connected to the host, while the entire conversation is dumped to output.log. One can now echo
telnet commands to nc localhost 666
, and read the result from output.log.
One should keep in mind that the expect
script can be easily modified to accommodate SSH
and even serial console
connection, just by spawning ssh
or socat
instead of netcat
. I never liked expect
because it forces a use of another scripting language within bash
, requires tcl
libraries, and needs to be compiled for the embedded platforms, while netcat
is a part of busybox
and readily available everywhere.
So, the question is - could this be done in a simpler way? I'd put my bet on having some sort of link between console and TCP socket
. Any suggestions are appreciated.
Upvotes: 1
Views: 2666
Reputation: 20980
How about using like a file descriptor?
exec 3<>/dev/tcp/host/port
while true; do
echo -e "user\npass\ncommand" >&3
read_response_generate_next_command <&3 >&3
# if no more commands, break;
done
exec 3>&-
Upvotes: 1