How to make dynamic response with bash - bash

I'm trying to listen socket into bash to produce dynamic response. I tried do like this nc -l 8088 -c``echo 'Request got, let's produce it' but -c option is deprecated and unsupported now.
Then I tried to list port using /dev/tcp: exec 3<>/dev/tcp/127.0.0.1/8088;
cat <&3 But i've got an error:
connect: Connection denied*
line 1: /dev/tcp/127.0.0.1/8088: Connection denied*
line 2: 3: Wrong file descriptor*
Translated from russian word for word

That syntax, according to the Bash manpage, is for opening a connection to an existing socket. I don't know of an option to create a socket using only Bash. And your nc command uses port 8000 not 8088.
[update]
OK then, but you're also missing the -p switch to set the port. Didn't catch that before.
jcomeau#intrepid:~$ nc -l -p8088 -c 'echo bleah' &
[1] 4752
jcomeau#intrepid:~$ exec 3<>/dev/tcp/127.0.0.1/8088; cat <&3
bleah
For an example of using pipes, see the bottom of this page, in the explanation of a proxy: http://www.stearns.org/doc/nc-intro.v0.9.html, hopefully you can adapt it for your needs.
Why not use inetd? The main problem with using netcat with Bash is that there's no straightforward way that I can think of to send back a reply, because you don't know what port they used to connect with. Whereas inetd handles the tcp/ip connection for you, letting your shell script just deal with stdin and stdout.

Related

Bash (simulate a telnet client with tcp socket and obtain the first line)

I'm trying to simulating a telnet client in bash using tcp socket and I'm starting from zero.
Doing this I am reading and writing on a file descriptor (stdin stdout).
(I know that it's too much simple to do $telnet hostname, but I'm doing this to understand bash).
To start I want to get the first line (welcome message).
There are some troubles with particular ip.
With some it works, but with some others it fails. It has to go good with all!
Example with some random Ip I found to test it
It works good with:
exec 3<> /dev/tcp/77.239.64.182/23; cat <&3
output:
????????
* TELRAD CMTS UBR-10K *
User Access Verification
Username:
Here the trouble
It works bad with:
exec 3<> /dev/tcp/77.239.64.158/23; cat <&3
output:
0???? ??#??'
but, if I use telnet the output it's different:
$ telnet 77.239.64.158
Trying 77.239.64.158...
Connected to 77.239.64.158.
Escape character is '^]'.
MikroTik v6.18
Login:
I thought that the trouble was that the client had to send some string before having the welcome message.
So I changed it to:
exec 3<> /dev/tcp/77.239.64.158/23; echo -e "aaaaaaaa\r\n\rAAAA...lonstring...AAAA\r\n\r\n\rAAAAlonstringAAAA\n\r\n" >&3; cat <&3
Same thing, same output.
Someone able to adjust this?!

Send command to open process in Shell file

In bash how can I issue a command to a running process I just started?
For example;
# Start Bluez gatttool then Connect to bluetooth device
gatttool -b $MAC -I
connect # send 'connect' to the gatttool process?
Currently my shell script doesn't get to the connect line because the gatttool process is running.
If you simply want to send the string "connect\n" to the process, you can use a standard pipe:
echo "connect" | gatttool -b $MAC -I
If you want to engage in a more complex "conversation" with the gatttool process, take a look at the expect (1) and chat (8) tool, which allow you to send a sequence of strings, and wait for certain responses.
If you'd prefer a slightly "lighter" way of piping you could use a heredoc such as in:
gatttool -b $MAC -I <<EOF
connect
(...)
EOF
Everything contained between the two EOF tags will be piped to the command's input. I believe this will not allow you to interact with the command whilst between the EOF tags so, as mentioned in the previous answer, you might want to consider using expect if you need to act upon the commands' output before sending something back to it.

BASH: keep connection alive

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

using socat to multiplex incoming tcp connection

An external data provider makes a tcp connection to one of our servers.
I would like to use socat to 'multiplex' the incoming data so that multiple programs can receive data sent from the external data provider.
socat -u TCP4-LISTEN:42000,reuseaddr,fork OPEN:/home/me/my.log,creat,append
happily accepts incoming data and puts it into a file.
What I'd like to do is something that will allow local programs to connect to a TCP port and begin to receive data that arrives from connections to the external port. I tried
socat -u TCP4-LISTEN:42000,reuseaddr,fork TCP4-LISTEN:43000,reuseaddr
but that doesn't work. I haven't been able to find any examples in the socat doco that seem relevant to back to back TCP servers.
Can someone point me in the right direction?
With Bash process-substitution
Multiplexing from the shell can in general be achieved with coreutils tee and Bash process-substitution. So for example to have the socat-stream multiplexed to multiple pipelines do something like this:
socat -u tcp-l:42000,fork,reuseaddr system:'bash -c \"tee >(sed s/foo/bar/ > a) >(cat > b) > /dev/null\"'
Now if you send foobar to the server:
socat - tcp:localhost:42000 <<<fobar
Files a and b will contain:
a
barbar
b
foobar
With named pipes
If the pipelines are complicated and/or you want to avoid using Bash, you can use named pipes to improve readability and portability:
mkfifo x y
Create the reader processes:
sed s/foo/bar/ x > a &
cat y > b &
Start the server:
socat -u tcp-l:42000,fork,reuseaddr system:'tee x y > /dev/null'
Again, send foobar to the server:
echo foobar | socat - tcp:localhost:42000
And the result is the same as in the above.
I found ncat ( http://nmap.org/ncat/) to be flexible and easier to use. I suggest you give it a try. I cannot currently test it for you to find the exact command, but you can let it listen on 2 ports; for one port you use the -k option to accept multiple clients.

Bash programming, interrogating ttyUSB port

I'm new in this of bash programming in linux, basically what I want to do is to program a bash file that can open the port ttyUSB0 and then I need to interrogate it with AT commands (like "0100") and then assign the response to a variable, I've been trying this with this different ways:
1) Using cat
#!/bin/bash
PORT= \ls /dev/ttyU*
cat $PORT
????
2) Using Minicom
`#!/bin/bash
minicom
????
'
3) Using Screen
#!/bin/bash
PORT= \ls /dev/ttyU*
screen $PORT
????
How can I interrogate it before the cat, minicom and screen starts? What should I have to put in ???? of the 3 different codes?
Thank you so much!!!
Don't try writing to a tty device using bash, you'll end up chasing your own tail forever. Use minicom or C-Kermit for that.
If you want to check that the device is active before starting minicom, you can read from it with bash and there is a good explanation of how to achieve this here: Bash read from ttyUSB0 and send to URL
You should be able to use my atinout program for this. It is a command line tool to talk with a modem:
$ echo AT | atinout - /dev/ttyUSB0 -
AT
OK
$
So with a little bit of scripting you should be able to extract the response you want (remember to always check for a successful OK response).

Resources