2

How can I spawn a process for a particular command and while it is running capture its output?

For example I want to perform dd on a block and while it is doing its job and producing status message , I do something else with the output of the dd progress. I tired the script below but it never stops printing:

#!/bin/bash

data=$(dd if=/dev/urandom of=/dev/null bs=4096 count=32768 status=progress)&

while [ -z "$data" ]; do
 echo "waiting for data..." "${data}"
 # Do something else while $data is not returned
 sleep 0.1
done

I have made some progress but still not the thing I want.

    #! /bin/bash
    
    varFileDone=$(mktemp)
    varFileOutput=$(mktemp)
    
    dd if=/dev/urandom of=/dev/null bs=4096 \
count=32768 status=progress 2<&1 >> $varFileOutput && echo 1 > $varFileDone &
    pid=$(pidof dd)
    
    while [[ ! -s $varFileDone ]];
    do
    
    data=$(cat $varFileOutput)
    echo "----->" "$data"
    if [[ -s $data ]];
      then
        echo "we have data"
        echo $data | cut -d"," -f3
      else
        echo "no data yet!"
      fi
      sleep 0.2
    done
5
  • This question over on Stack Overflow seems to have some answers that may be useful to you: stackoverflow.com/questions/20017805/… Oct 11, 2022 at 13:48
  • You're writing the data to /dev/null, what are you expecting to get in $data?
    – Kusalananda
    Oct 11, 2022 at 19:19
  • @Kusalananda It is just an example, I want to get the output of dd as its doing its job
    – DEKKER
    Oct 12, 2022 at 7:13
  • @DEKKER This example only outputs some summary information at the very end of processing. Had you used a command that produced a steady stream of output, what would you expected to see and get in $data? Would you expect to see a status message from your loop at regular intervals, or only when there are long pauses, and would you expect to accumulate all output in $data (even if this is gigabytes of data), or only the data since the last status output from your loop?
    – Kusalananda
    Oct 12, 2022 at 7:34
  • @Kusalananda You are right, I forgot to add status=progress at the end of dd. What I want to have is capture the progress and cut some specific field of the progress report and feed it somewhere else. I updated the question with more detail
    – DEKKER
    Oct 12, 2022 at 7:41

3 Answers 3

1

Your question is a little vague. Your use of setting a variable in the asynchronous environment does not quite work here, since the value of the variable is never available to the original environment.

The asynchronous call using ampersand & could be substituted with coproc. I suggest checking out the man page for bash, because there are a few tools with this format.

Example use:

#!/bin/bash

coproc COPROC ($(dd if=/dev/urandom of=/dev/null bs=4096 count=32768))

while [[ $COPROC ]]; do  
sleep 0.1
echo waiting!  
done

wait # unnecessary, but proves the asynchronous processes are actually complete
echo "Task done!"
1

you could try:

dd if=/dev/urandom of=/dev/null bs=4096 count=32768 & 2>&1 > /tmp/tmp
pid=$(ps|grep dd|awk '{print $1}')
while [[ ! "" = "$pid" ]]
do     
    # Do something else while dd is still writing

    grep "," /tmp/tmp | grep -v "+"|awk '{$2" "$3}'
done
2
  • 1
    I don't know why you're using grep and ps. You have the PID of the background process in $!.
    – Kusalananda
    Oct 11, 2022 at 19:20
  • I saw your edit. My advice would be pid=$!, and then use while kill -0 "$pid" to loop while the PID is valid. Note that the kill command there will only tell you that the PID is valid, but it won't tell you whether it's the correct process (but neither did your ps+grep thing).
    – Kusalananda
    Oct 11, 2022 at 19:44
-1

If you do not want to see dd command output, you can just add a redirection like this:

data=$(dd if=/dev/urandom of=/dev/null bs=4096 count=32768 2>&1 /dev/null)

2>&1 is used to redirect output AND errors.

Just modify the output you want (replace /dev/null by any other file). You can check the output generated during the process using tail command, ie tail -f /your/output/file.

2
  • Hi, sadly this does not help.... I wan to have the command inside the script itself to be in background! not the script itself
    – DEKKER
    Oct 11, 2022 at 14:16
  • Thank you for your feedback. I added a redirection of the output. I hope it will be better like that...
    – ramius
    Oct 12, 2022 at 9:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .