简体   繁体   中英

Redirect all output in a bash script when using set -x, capture pid and all output

I'm modifying an old script and for some reason it uses a subshell. I'm not sure if maybe the subshell is what's tripping me up. What I really want is to start a service and capture all of STDOUT and STDERR to a file as well as it's PID. Additionally, however I want some debug information in the log file. Consider the script below (startFoo.sh):

#!/bin/bash
VARIABLE=$(something_dynamic)
echo "Some output"
(
   # Enable debugging
   set -x
   foo -argument1=bar \
      -argument2=$VARIABLE

   # Disable debugging
   set +x

) > /tmp/foo_service.log 2>&1 &
OUTER_PID=$!
echo $OUTER_PID > foo.pid

This seems to work in that I'm capturing most of the output to the log as well as the PID, but for some reason not all of the output is redirected. When I run the script, I see this in my terminal:

[me@home ~]$ sudo startFoo.sh
Some output
[me@home ~]$ + foo -argument1=bar -argument2=value

How can I squash the output in my prompt that says [me@home ~]$ + foo... ?

Note, this question may be related to another question: redirect all output in a bash script when using set -x , however my specific usage is different.

UPDATE : My script now looks like this, but something is still not quite right:

#!/bin/bash
VARIABLE=$(something_dynamic)
echo "Some output"
(
   # Enable debugging
   set -x
   foo -argument1=bar \
      -argument2=$VARIABLE

   # Disable debugging
   set +x

) > /tmp/foo_service.log 2>&1 &
PID=$!
echo $PID > foo.pid

However, when I do this, the PID file contains the PID for startFoo.sh , not the actual invocation of foo which is what I really want to capture and be able to kill. Ideally I could kill both startFoo.sh and foo with one PID, but I'm not sure how to do that. How is this normally handled?

UPDATE : The solution (thanks to a conversation with @konsolebox) is below:

#!/bin/bash 
VARIABLE=$(something_dynamic) 
echo "Some output" 
{ 
   # Enable debugging 
   set -x 
   foo -argument1=bar \ 
      -argument2="$VARIABLE" &
   PID=$! 
   echo $PID > foo.pid 

   # Disable debugging 
   set +x
} > /tmp/foo_service.log 2>&1

Change 2>&1> /tmp/foo_service.log to >/tmp/foo_service.log 2>&1 .

You should first redirect fd 1 to the file, then let fd 2 duplicate it. What you're doing on the former is that you first redirect fd 2 to 1 which only copies the default stdout, not the file's fd which is opened after it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM