0

As I did not find a direct way to supply the file name to the pv (man page), (except for a strange -N switch, which acts as a prefix, rather than the file name itself), I would need to manually edit the end of text which sha512sum or any other shaXsum for that matter outputs over pipe like:

pv -W "$file" | sha512sum -b

I store it in a variable sha_output, but I wanted to give you purer example, the raw code is:

sha_output=$( pv -W "$file" | sha512sum -b )

Example hash sum text output:

2a19f5852ba8f76bd5a67db18539d609baaf3888b27a57181564db01ef6c16812c60e306973edc059221f61bf2ad9f4b4ef5ff09bbcef98e74a27971c67bdc18 *-

Desired output:

2a19f5852ba8f76bd5a67db18539d609baaf3888b27a57181564db01ef6c16812c60e306973edc059221f61bf2ad9f4b4ef5ff09bbcef98e74a27971c67bdc18  linuxmint-19.2-cinnamon-64bit.iso

(Yes, 2 spaces in between the hash and the file name).

Finally, let us suppose the file name is stored in a variable called file_name.


Solutions must not include any Bashisms, only portable (POSIX) solutions, please.

With the help of this answer, I put together the following:

printf '%s\n' "${sha_output//\*-/$file_name}"

which surprisingly works (somewhat) under Bash, but Dash errors out with message:

bad substitution

Since brace expansion is not defined by POSIX, as per comment, it is by no surprise then.

1
  • dash wouldn't grok the ${variable//pattern/word} substitution as it's not POSIX. Also, brace expansion is not POSIX either.
    – Kusalananda
    Dec 1, 2019 at 8:42

2 Answers 2

2

Assuming $file is the name or pathname of the single file that you'd like to substitute into the checksum output.

pv "$file" | sha256sum | { IFS=' ' read sum junk && printf '%s  %s\n' "$sum" "$file"; }

The last part of the pipeline reads the checksum and whatever else sha256sum output on its first line, and then prints the checksum out followed by the original filename.

Note that using sha256sum -b isn't really needed as these tools make no difference between binary and text files on Unix.

0
1

Since you are capturing the command output already in a variable, you could "Capture and Correct" the var (POSIXly, yes runs in dash):

sha_output=$( pv -W "$file" | sha512sum -b)
sha_output="${sha_output%\*-} $file"

The ${...%\*-} will remove the trailing *- and then an space and the file name are appended. Actually, the -b mode is only useful in OS that diferentiate binary mode from text mode when accesing a file (namely only MS-DOS). So, no -b option is needed for shaXsum, and the asterisk (*) (signaling binary mode) will become an space (signaling text mode).

If you are not capturing but want the output printed, you can use:

$ printf '%s\n' "$(pv "$file" | sha256sum | sed 's/-$//')$file"
2a19f5852 ... a27971c67bdc18  linuxmint-19.2-cinnamon-64bit.iso

Or @Kusalananda answer.

All answers are equally valid, POSIX compatible and useful.


Note that all the above doesn't mimic the exact behaviour of shaXsum in that some file names (with newline or slash) will make the hash line start with a backslash.

If file='wo\\rds' (contains a backslash) the output is:

$ sha256sum "$file"
\f6c94d35691b9c356f7e5072f94d23f127b168cf9b04f0f5b26e0cb1f6ef4414  wo\\rds

Note that the line start with a backslash and that problematic characters in the file name are escaped with a backslash.

Your command doesn't mimic that:

$ printf '%s\n' "$(pv "$file" | sha256sum | sed 's/-$//')$file"
f6c94d35691b9c356f7e5072f94d23f127b168cf9b04f0f5b26e0cb1f6ef4414  wo\rds
3
  • At this moment I find your solution more elegant, but which one to actually use? Well, I upvoted. Waiting for you maybe to append additional information which would help me decide. Thanks. Dec 1, 2019 at 18:37
  • All answers are equally valid, POSIX compatible and useful. It is perfectly fine your present selection if that helped you, we are not competing but cooperating to help questioners. @LinuxSecurityFreak
    – user232326
    Dec 1, 2019 at 20:13
  • Good morning! I see you've updated your answer. I've read it and I am proud to be a member here. Cheers and thanks again! Dec 2, 2019 at 1:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.