bash - Redirect stdout/stderr of a background job from console to a log file?

07
2014-07
  • Daniel YC Lin

    I just run a job (assume foo.sh).

    ./foo.sh
    [Press Ctrl-Z to stop]
    bg  # enter background
    

    And it generate output to stdout and stderr. Is there any method to redirect to stdout and stderr to other file instead of current screen?

  • Answers
  • neocrow

    Apparently I misread your question the first time, so here's my updated answer:

    After you sent your program to the background, you first have to find its PID

    pgrep foo.sh
    

    Then you could use gdb to attach to that process

    gdb -p <PID>
    

    In gdb you then change where this program writes to

    p dup2(open("/path/to/file",577, 420), 1)
    p dup2(1, 2)
    

    then you detach from the process and quit gdb

    detach
    quit
    

    A little explanation

    • 577 is equivalent to O_CREAT|O_WRONLY|O_TRUNC
    • 420 is equivalent to S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
    • So the call to open opens the file and truncates it to 0 bytes if it exists or creates a new one with the right file permissions if it doesn't exist
    • The first call to dup2 duplicates the file descriptor returned by the call to open to file descriptor 1 (which is stdout)
    • The second call to dup2 duplicates the file descriptor 1 to 2 (which is stderr)

  • Related Question

    questions about bash background job
  • Tim

    (1). Since background job can still run even if the user logs out, what's the point of using nohup and screen?

    (2). What is the difference between CTRL+Z and stop to suspend a background job? There is another command "stop" which stops a background job. This doesn't kill the job, but it will not continue executing until it is restarted. I wonder what is the difference between "stop" and CTRL+Z? for "stop", see http://www.ece.osu.edu/computing/background_jobs.html#commands

    (3). to make a background job noninteractive, is this correct?

    command &lt<inputfile> &gt<outputfile>
    

    What if I want to append the output to an existing file while keep the job background?

    Thanks and regards!


  • Related Answers
  • hobodave

    Background jobs

    Normal background jobs do not survive a termination of the parent shell:

    pigpen ~: yes > /dev/null &
    

    This will not survive a logout.

    However, this will:

    pigpen ~: nohup yes &
    

    nohup prevents the process from receiving a SIGHUP signal on logout.

    Screen, on the other hand, maintains the illusion that the user is always logged in, and allows the user to reattach at any time. This has the advantage of being able to continue to interact with the program once reattached (impossible with nohup alone).

    Ctrl+C

    Ctrl+C sends a SIGINT to the process, which it may catch and ignore (uncommon).

    I suggest reading the bash man page; specifically the sections on Signals and Job Control.

    Ctrl+Z

    You edited your question to use Ctrl+Z instead. Ctrl+Z sends a SIGTSTP signal to the process, suspending it. This process can be later continued by sending it a SIGCONT signal.

    SIGTSTP signals can be caught by the program and ignored.

    SIGSTP signal

    The SIGSTP signal is different from SIGTSTP in that it cannot be caught by the running program. It's behavior is identical to the behavior of an uncaught SIGTSTP.

    Resources

  • Jeffrey Aylesworth
    1. Background jobs will only continue if you detach them (I believe), and you cannot get output or send input to them later. Screen will let you connect to it later, as though you never left it.
    2. Control+c is a keyboard interrupt, all it does is send a signal to the running program, which will normally respond by exiting, but it not forced to. Stopping it will send a different signal, where the application will generally stop what it's doing until it gets a continue signal (this can be done with control+z).
  • user31894
    1. the background job will die if you exit the shell you started it in. (eg SSH), that's why you use nohup or screen. If you have modern bash shell, there's a disown -h command. see man page of bash for more info
    2. Ctrl-C and suspend are different. Ctrl-C terminates the process.
    3. To append output to existing file : 1>>/path/existing_file
    4. ctrl-Z suspend the process, bring it into the background and give the control back to you. I don't know the exact meaning of your "stop"
    5. To append output and put in background: command 1>>/path/existing_file &