4

i want to detach command either with 'command &' in the end, or with 'nohup command &', but it stops right after detaching it.

command is little specific, if it receives eof on input, it breaks so /dev/null as input will lead to end and solution that usualy works:

$ command < /dev/null > /dev/null 2>&1 &

not working...

is there other device in unix/linux, that can replace /dev/null and behave like empty input, but not sending eof.

(by the way, command is very useful multicasting tool emcast, I can try patching it my self, or find patched version for this purpose... but it seems that problem can be solved outside)

I'm adding this EDIT to make my question more clear. I made this C program of 2 lines that works perfectly: program name is "donothing"

#include <unistd.h>
int main() {  while (1)  { sleep(10); } return 0; }

and it is what I am looking for, some device/program, that doing nothing, but leave its stdout open. Both ("command & ... disown" and "nohup command &") works.

$ donothing | mycommand >/dev/null & 
$ disown %1

works well, so now question is only: what unix device/program behaves like my 'donothing'.

3 Answers 3

9

For your command to detect eof, it has to read from stdin. So presumably it is expecting some input. So it sounds like what you need is not an empty input (/dev/null is exactly meant for that), but input that never comes.

It can be simulated with a pipe where nobody is ever going to write on the other end like:

sleep 999999999 | the-command

Or to avoid having to run that extra sleep command, it could be done with a named pipe:

fifo=$(mktemp -u) &&
  mkfifo "$fifo" &&
  (rm "$fifo" && the-command <&3 3<&- &) 3<> "$fifo"

Here using an intermediary file descriptor to work around the fact that the shell connects stdin to /dev/null implicitely when you start a command with & (unless you add an explicit stdin redirection like our <&3 here).

On Linux (and probably on Linux only), you can also do:

the-command < /dev/fd/1 3>&1 > /dev/null | :

/dev/fd/1 where fd 1 is connected to a pipe, on Linux, behaves like a named pipe. That is, when you open it in read mode, you get the reading end of the pipe.

So above, fd 0 will be connected to the reading end of a pipe whose other end is on the fd 3 of the-command. Because the-command is not going to write anything on its fd 3, any read attempt on fd 0 will block (or a non-blocking read will return with there's nothing to read yet, or a select/poll will return nothing to read either as the-command is probably doing if it's doing anything else than waiting for input that never comes).

7
  • ok i understand sleep, (tested-works) and i will try to understand fifo part ... if no one provide something new in next few hours, i will mark this as answer. Mar 17, 2013 at 20:48
  • 999999999 seems safe (32 years) ... i wonder what real limit is of sleep command. Mar 17, 2013 at 20:55
  • @OmerMerdan, On my system (Linux, coreutils 8.13), it converts the argument to a double and repeats the sleep as many times as necessary to reach that number. So I can do sleep infinity or sleep 1e200. Portably I suspect the best you can expect is 2^31-1: 2147483647. Mar 17, 2013 at 21:12
  • 1
    @vonbrand, that's the requirement. As I said, presumably, the program is some sort of interactive tool that does a select/poll or uses non-blocking I/O, or threads to check if there's something to be read on stdin while doing something useful in background and we need to simulate an idle user. Mar 18, 2013 at 9:49
  • 1
    @StéphaneChazelas This post changed my life. You, sir, are a true gentleman and scholar. I can't possibly thank you enough Dec 21, 2017 at 16:19
1

You need to use the command disown. This will release the STDIN/STDOUT from the current shell where you're running these commands.

% disown -a

-or-

% sleep 100 &
[1] 7987
% disown %1

See the bash man page for further details.

disown [-ar] [-h] [jobspec ...] Without options, each jobspec is removed from the table of active jobs. If the -h option is given, each jobspec is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. If no jobspec is present, and neither the -a nor the -r option is supplied, the current job is used. If no jobspec is supplied, the -a option means to remove or mark all jobs; the -r option without a jobspec argument restricts operation to running jobs. The return value is 0 unless a jobspec does not specify a valid job.

3
  • thanks, this 'disown' command looks better and more logical then 'nohup', but still not resolved my problem, i tested $ (sleep 10; mycommand >myLog 2>&1) & ... and disown it inside 10 seconds ... but log file do not grows... i will check more. Mar 17, 2013 at 19:55
  • @OmerMerdan, do you mean that the log file isn't appended or that it isn't created? The truncating redirection operator (>) will not allow the file to "grow" even if you don't disown.
    – depquid
    Mar 17, 2013 at 20:24
  • it starts to fill it ... few kilobytes, and then stops. I have edited my question to make problem more clear. Mar 17, 2013 at 20:32
1

I needed something like this for running expect scripts from an automated test system (Jenkins). Expect automatically closes stdout when it detects EOF on stdin, and that causes all writes to stdout to fail and terminate the test. I worked around it by simply making its stdin /dev/zero.

mycommand </dev/zero

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .