Using netcat/cat in a background shell script (How to avoid Stopped (tty input)? )
Asked Answered
C

6

13

Abstract: How to run an interactive task in background?

Details: I am trying to run this simple script under ash shell (Busybox) as a background task.

myscript.sh&

However the script stops immediately...

[1]+ Stopped (tty input) myscript.sh

The myscript.sh contents... (only the relvant part, other then that I trap SIGINT, SIGHUP etc)

#!/bin/sh

catpid=0

START_COPY()
{
  cat /dev/charfile > /path/outfile &
  catpid = $! 
}

STOP_COPY()
{
  kill catpid 
}

netcat SOME_IP PORT | while read EVENT
do
  case $EVENT in
    start) START_COPY;;
    stop) STOP_COPY;;
  esac
done

From simple command line tests I found that bot cat and netcat try to read from tty. Note that this netcat version does not have -e to supress tty.

Now what can be done to avoid myscript becoming stopped?

Things I have tried so for without any success:

1) netcat/cat ... < /dev/tty (or the output of tty)

2) Running the block containing cat and netcat in a subshell using (). This may work but then how to grab PID of cat?

Over to you experts...


The problem still exists. A simple test for you all to try:

1) In one terminal run netcat -l -p 11111 (without &)

2) In another terminal run netcat localhost 11111 & (This should stop after a while with message Stopped (TTY input) )

How to avoid this?

Clink answered 12/8, 2011 at 15:22 Comment(3)
If you're fine with capturing input and output from a subprocess, you can use script. If that won't work, you might try researching socat; it has advanced PTY handling, but I couldn't figure out how to get it to capture STDIN.Moshe
The illusatration is part of script which didn't work. socat is not the option for the environment I have (can't get it there). Have tired to redirect /dev/ttyS0 to netcat and it seems to be working but then it stop receiving signals.Clink
Is it feasible to restructure your program to use the Unix tool script, with the -f option?Moshe
P
14

you probably want netcat's "-d" option, which tells it not to read from STDIN.

Pomander answered 19/7, 2012 at 16:39 Comment(0)
B
9

I can confirm that -d will help netcat run in the background.

I was seeing the same issue with:

nc -ulk 60001 | nc -lk 60002 &

Every time I queried the jobs, the pipe input would stop.

Changing the command to the following fixed it:

nc -ulkd 60001 | nc -lk 60002 &
Builtin answered 19/6, 2013 at 6:4 Comment(0)
F
4

Are you sure you've given your script as is or did you just type in a rough facsimile meant to illustrate the general idea? The script in your question has many errors which should prevent it from ever running correctly, which makes me wonder.

  1. The spaces around the = in catpid=$! make the line not a valid variable assignment. If that was in your original script I am surprised you were not getting any errors.

  2. The kill catpid line should fail because the literal word catpid is not a valid job id. You probably want kill "$catpid".

As for your actual question:

  • cat should be reading from /dev/charfile and not from stdin or anywhere else. Are you sure it was attempting to read tty input?

  • Have you tried redirecting netcat's input like netcat < /dev/null if you don't need netcat to read anything?

Filicide answered 12/8, 2011 at 16:16 Comment(1)
No, it was just an ilustration and as you pointed out there are typos. Anyway cat is actually reading from /dev/charfile (tested at command line). I just assumed that either netcat or cat is causing this Stopped (tty input) problem. Also tried /dev/null with netcat without success.Clink
K
2

I have to use a netcat that doesn't have the -d option.

"echo -n | netcat ... &" seems to be an effective workaround: i.e. close the standard input to netcat immediately if you don't need to use it.

Kinross answered 19/11, 2013 at 10:33 Comment(0)
P
0

As it was not yet really answered, if using Busybox and -d option is not available, the following command will keep netcat "alive" when sent to background:

tail -f /dev/null | netcat ...

netcat < /dev/null and echo -n | netcat did not work for me.

Plot answered 24/2, 2016 at 8:51 Comment(0)
G
0

Combining screen and disown-ing process work for me, as '-d' option is not a valid anymore for netcat. Tried redirecting like nc </dev/null but session ends prematurely (as I need -q 1 to make sure nc process stop as file transfer finished)

Setup Receiver side first,

on Receiver side, screen keep stdin for netcat so it won't terminated

EDIT: I was wrong, you need to enter command INSIDE screen. You'll end with no file saved, or weird binary thing flow in your terminal while attach to screen, if you redirecting nc inline of screen command. (Example, this is THE WRONG WAY: screen nc -l -p <listen port> -q 1 > /path/to/yourfile.bin)

  1. Open screen , then press return/Enter on welcome message. new blank shell will appear (you're inside screen now)
  2. type command: nc -l -p 1234 > /path/to/yourfile.bin

  3. then, press CTRL + a , then press d to detach screen.

on Sender sides, disown process, quit 1s after reaching EOF

cat /path/to/yourfile.bin | nc -q1 100.10.10.10 1234 & disown
Grip answered 1/1, 2020 at 6:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.