2

I have a program prog that takes stdin input like this:

prog < test.txt

But the processing takes quite a lot time, so once the input is read, it the process should background.

From this answer https://unix.stackexchange.com/a/71218/201221 I have working solution, but without nohup. How modify it to use nohup too?

#!/bin/sh
{ prog <&3 3<&- & } 3<&0
8
  • 2
    You don't need nohup -- it does nothing the shell can't do on its own. See disown Commented Dec 31, 2017 at 17:01
  • BTW, you're using /bin/sh but tagging the question bash. sh specifies POSIX sh, not bash -- does the tag mean a bash-only answer is acceptable? Commented Dec 31, 2017 at 17:07
  • @Charles Duffy At best the solution should be compatible with sh and bash.
    – mvorisek
    Commented Dec 31, 2017 at 17:09
  • 1
    If you want POSIX sh (which would give you compatibility with both), the question should be tagged sh, not bash. Commented Dec 31, 2017 at 17:10
  • 1
    ...that said, I'm not at all convinced that this is possible relying only on baseline POSIX sh functionality, since nohup closes stdin (behavior you don't want), and disown is a non-POSIX extension. Commented Dec 31, 2017 at 17:11

2 Answers 2

3

disown is a shell builtin which tells bash to remove a process from its recordkeeping -- including the recordkeeping that forwards HUP signals. Consequently, if stdin, stdout and stderr are all redirected or closed before the terminal disappears, there's absolutely no need for nohup so long as you use disown.

#!/bin/bash

logfile=nohup.out            # change this to something that makes more sense.
[ -t 1 ] && exec >"$logfile" # do like nohup does: redirect stdout to logfile if TTY
[ -t 2 ] && exec 2>&1        # likewise, redirect stderr away from TTY

{ prog <&3 3<&- & } 3<&0
disown

If you really need compatibility with POSIX sh, then you'll want to capture stdin to a file (at a potentially very large cost to efficiency):

#!/bin/sh

# create a temporary file
tempfile=$(mktemp "${TMPDIR:-/tmp}/input.XXXXXX") || exit

# capture all of stdin to that temporary file
cat >"$tempfile"

# nohup a process that reads from that temporary file
tempfile="$tempfile" nohup sh -c 'prog <"$tempfile"; rm -f "$tempfile"' &
1
  • Both solutions are probably the best possible one. Thank you.
    – mvorisek
    Commented Dec 31, 2017 at 17:33
0

From what I see the following code is contained in a separate shell file:

#!/bin/sh
{ prog <&3 3<&- & } 3<&0

So, why not try just:

nohup the_file.sh &
3
  • This prints the classic "... appending output to 'nohup.out'" when nohup is used without & for backgrounding. Is any form of nohup xxx & possible?
    – mvorisek
    Commented Dec 31, 2017 at 16:42
  • @Mvorisek yes. I forgot to add the & at the end :) Commented Dec 31, 2017 at 16:43
  • 1
    @Mvorisek, nohup unconditionally redirects stdin away from the TTY -- that's part of its specification. Commented Dec 31, 2017 at 17:09

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