How to totally fork a shell command that is using redirection

You should try setsid(1). Use it like you'd use nohup:

setsid command_which_takes_time input > output

This (as per the setsid(2) manpage), does a fork(2), an _exit(2) of the parent process, then the child process calls setsid(2) to create a new process group (session).

You can't kill that by logging out, and it's not part of the Bash job control shebang. For all intents and purposes, it's a proper daemon.


Try creating subshell with (...) :

( command_which_takes_time input > output ) &

Example:

~$ ( (sleep 10; date) > /tmp/q ) &
[1] 19521
~$ cat /tmp/q # ENTER
~$ cat /tmp/q # ENTER
(...) #AFTER 10 seconds
~$ cat /tmp/q #ENTER
Wed Jan 11 01:35:55 CET 2012
[1]+  Done                    ( ( sleep 10; date ) > /tmp/q )

there is disown bash builtin command:

[1] 9180
root@ntb1:~# jobs
[1]+  Running                 sleep 120 &
root@ntb1:~# disown
root@ntb1:~# jobs
... no jobs, disowned
root@ntb1:~# ps aux | grep sleep | grep -v grep
root      9180  0.0  0.0   4224   284 pts/0    S    17:55   0:00 sleep 120
... but the sleep still runing
root@ntb1:~#

After disown, the job is disowned from your shell (so You can even logout) and it still remains running until finished.

See the 1st jobs command listed the sleep however the 2nd jobs after the disown did not. But using the ps we can see that the job is still running.