Search code examples
bashscriptingpid

Get PID of a timed process, along with the output of time


I have this line of code:

{ time cp $PWD/my_file $PWD/new_file ; } 2> my_log.log

I need to know how long it takes to execute the 'cp' command and I also need to get the PID of the 'cp'. I just want to print the PID of the 'cp' process and get the following in the my_log.log file:

<output of time> 

I have tried PID=$! but this does not provide PID of the cp process.


Solution

    • First, you need to send your (timed) cp command to the background with a trailing &, so you can inspect the running processes after launching it. (I suspect you're already doing this, but it's not currently reflected in the question).

    • $!, the special variable that contains the PID of the most recently launched background job, in this case reflects the subshell that runs the time command, so we know that it is the parent process of the cp command. To get the (one and only, in this case) child process:

      • If your platform has the nonstandard pgrep utility (comes with many Linux distros and BSD/macOS platforms), use:
        pgrep -P $!

      • Otherwise, use the following POSIX-compliant approach:
        ps -o pid=,ppid= | awk -v ppid=$! '$2 == ppid { print $1 }'

    To put it all together, using prgep for convenience:

    # Send the timed `cp` command to the background with a trailing `&`
    { time cp "$PWD/my_file" "$PWD/new_file"; } 2> my_log.log &
    
    # Get the `cp` comand's PID via its parent PID, $!
    cpPid=$(pgrep -P $!)