In a bash pipe, take the output of the previous command as a variable to the next command (Eg. if statement)

Viewed 2763

I wanted to write a command to compare the hash of a file. I wrote the below single line command. Wanted to understand as to how I can take the output of the previous command as a variable for the current command, in a pipe.

Eg. below command I wanted to compare the output of 1st command "Calculated hash" to the original hash. In the last command, I wanted to refer to the output of the previous command. How do I do that in the if statement? (Instead of $0)

sha256sum abc.txt | awk '{print $1}' | if [ "$0" = "8237491082roieuwr0r9812734iur" ]; then
    echo "match"
fi
2 Answers

Following your narrow request looks like:

sha256sum abc.txt  |
  awk '{print $1}' |
  if [ "$(cat)" = "8237491082roieuwr0r9812734iur" ]; then echo "match"; fi

...as cat with no arguments reads the command's stdin, and in a pipeline, content generated from prior stages are streamed into their successors.

Alternately:

sha256sum abc.txt  |
  awk '{print $1}' |
  if read -r line && [ "$line" = "8237491082roieuwr0r9812734iur" ]; then echo "match"; fi

...wherein we read only a single line from stdin instead of using cat. (To instead loop over all lines given on stdin, see BashFAQ #1).


However, I would strongly suggest writing this instead as:

if [ "$(sha256sum abc.txt | awk '{print $1}')" = "8237491082roieuwr0r9812734iur" ]; then
  echo "match"
fi

...which, among other things, keeps your logic outside the pipeline, so your if statement can set variables that remain set after the pipeline exits. See BashFAQ #24 for more details on the problems inherent in running code in pipelines.

Consider using sha256sum's check mode. If you save the output of sha256sum to a file, you can check it with sha256sum -c.

$ echo foo > file        
$ sha256sum file > hash.txt
$ cat hash.txt
b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c  file
$ sha256sum -c hash.txt
file: OK
$ if sha256sum -c --quiet hash.txt; then echo "match"; fi

If you don't want to save the hashes to a file you could pass them in via a here-string:

if sha256sum -c --quiet <<< 'b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c  file'; then
    echo "match"
fi
Related