I have a Linux based router that I’m trying to “control” with a home automation controller. On my automation controller I’m able to utilize a ‘two way strings’ driver to send a string to the Linux router upon the push of a button on the remote control. I’m wanting the string sent to be executed on the router.

I’m able to accomplish this by running the commands below while ssh’d into the router:

$ rm -f /tmp/f; mkfifo /tmp/f
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

As long as I keep the terminal window open the automation controller is able to send strings that alter the iptables.

The problem I’m running into is that this does not persist after I close the ssh connection. Is there a way to have the router continue to listen and execute commands from the controller after ssh connection is closed?

Here is an example of the string I’m sending:


Basically my end goal is to be able to drop traffic to a particular device on the network at the push of a button.

Security is not a concern as this is a home lab environment.

  • Why is the string you send percent-encoded? bash won't understand it. – Hermann Dec 30 '18 at 18:09
  • 1
    This feels like a X-Y-Question. Any reason you cannot use ssh on the push-button client-side? – Hermann Dec 30 '18 at 18:10
  • using the %20 was the only way I could get the string to be executed. The automation controller I'm using does not have ssh capabilities - it is a closed system. I'm only able to send strings using the controller. – RaaGee Dec 30 '18 at 18:49

You can use screen to do this.


The steps are:

  1. Open ssh session as normal.
  2. Install screen. (If not already installed)
  3. start a new screen session. (Just type screen and press enter)
  4. Run your command as you have it
  5. Type in ctrl + 'a' and then release both ctrl and a, and press 'd' to disconnect the screen session.

The session stays running in the background. Even if you log out and close out the ssh session completely.

If you're using an enterprise linux such as centos, you can use yum to install screen from the distribution's package repository.

yum -y install screen

If you're using a debian based OS try using:

apt-get install screen

Once installed start a new screen session by just typing screen.

[user@localhost ~]$ screen

Note: This will clear the screen and start a new session.

Run your command:

[user@localhost ~]$ rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

Detach the screen session:

ctrl +a, d


You can verify that your process is still running with netstat. If your OS supports it, you can use the -p flag to show the running process ID.

-p, --program Show the PID and name of the program to which each socket belongs.

[user@localhost ~]$ netstat -anp | grep 1234
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0    *                   LISTEN      30599/nc

And you can use ps to show that the process is still running:

[user@localhost~]$ ps -ef | grep [3]1037
500      31037 31019  0 21:45 pts/2    00:00:00 nc -l 1234

Note: placing square braces '[]' around the first number of the pid, is a little regex trick to avoid showing the grep process itself. Essentially a false match, and not your actual process.

You can show the detached screen session with screen -ls

[user@localhost~]$ screen -ls
There is a screen on:
        30562.pts-0.localhost  (Detached)
1 Socket in /var/run/screen/S-user.

And you can re-attach to it with screen -r, or screen -x and the session name

[user@localhost ~]$ screen -x 30562.pts-0.localhost
  • disown -a && exit will also let you close out the terminal. disown is a bash shell built in. – Chris Smith Apr 23 at 5:42

You want to use nohup for letting your commands run even after the ssh connection is closed (the remote operator hangs up the phone). The procedure is the same as in this answer:

nohup sh -c 'rm -f /tmp/f ; mkfifo /tmp/f && cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f'
  • This does not work. I get the following output when issuing the above command and the strings from the automation controller do not get executed. [root @ untangle] /tmp # nohup sh -c 'rm -f /tmp/f ; mkfifo /tmp/f && cat /tmp/f | /bin/sh -i 2>&1 | nc -l > /tmp/f' nohup: ignoring input and appending output to 'nohup.out' – RaaGee Dec 30 '18 at 17:51
  • Also, sorry for the formatting in the above reply. I'm unable to get linebreaks to work properly, I entered two spaces where I want the linebreaks to happen but it didn't work. I'm new to commenting on this forum so I must be missing something obvious. – RaaGee Dec 30 '18 at 17:54
  • @RaaGee The message is informative, not an error. If the message annoys you, you can redirect nohup's output explicitly: nohup sh -c 'rm -f /tmp/f ; mkfifo /tmp/f && cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f' 1>/tmp/f.out 2>/tmp/f.err – Hermann Dec 30 '18 at 18:07
  • thanks for the info. The message is not necessarily a problem to me but the command does not allow the strings to be executed so in that regard does not acoomplish what I'm wanting. – RaaGee Dec 30 '18 at 18:52
  • How about nohup socat tcp-listen:1234,reuseaddr,fork EXEC:bash on the router then? Works with commands sent via something like echo 'iptables -I INPUT -s -j DROP' | netcat localhost 1234. – Hermann Dec 30 '18 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.