Recently one of my users of Jacksum reported a strange behavior if echo is used on Microsoft Windows.
For those who don't know: Jacksum is a data integrity tool which can (not only) calculate and verify hash values. For more information go to https://jacksum.net
So the report (which was sent privately to me) was this:
jacksum -q "txt:Hello World!"
d0e47486bbf4c16acac26f8b653592973c1362909f90262877089f9c8a4536af
that is correct, but if Jacksum reads from stdin and echo on Windows is used, it returns a completely different hash:
echo "Hello World!" | jacksum -
61ab266cecda9b9885aedbbb5b3d9914738cec74930301ec7b68312b6b436b8b <stdin>
Is Jacksum right?
Yes, Jacksum is right. The problem is with the echo command on Windows!
I started Jacksum with "--verbose summary" which gives us additional information:
echo "Hello
World!" | jacksum --verbose summary -
61ab266cecda9b9885aedbbb5b3d9914738cec74930301ec7b68312b6b436b8b
<stdin>
Jacksum: files read successfully: 1
Jacksum: files read with errors: 0
Jacksum: total bytes read: 17
Jacksum: total bytes read (human readable): 17 bytes
Jacksum: elapsed time: 139 ms
As you can see, Jacksum have read 17 bytes from stdin (the 3rd line of the summary). "Hello World!" (without quotes) are just 12 characters, what are the other 5 characters?
I pasted the output of echo to a file ...
echo "Hello World!" > hello.txt
and loaded the file in a hex editor (https://hexed.it will work perfectly well for that task)
As you can see, the Windows echo
- does not only transfers the Hello World! to the pipe (Hello
World! => 12 bytes), but also ...
- it appends the Windows carriage return, line feed chars (0x0D, 0x0A
=> 2 bytes) which is expected on Windows
- it doesn't strip the quotes (2x" => 2 bytes) - which is probably not known to everybody, and
- ATTENTION!: it doesn't strip the blank that is between
the 2nd quote (") and the redirection sign (>) => 1 byte
That means a
echo "Hello World!" > hello2.txt
would even add more blanks to the output.
And even if we would do this:
echo Hello World!> hello3.txt
the CR LF will always be there, because there is no -n option (which GNU/Linux and macOS have for example).
So the workaround on Microsoft Windows 10 we found is this:
echo | set /p="Hello World!"
| jacksum -
d0e47486bbf4c16acac26f8b653592973c1362909f90262877089f9c8a4536af <stdin>
which produces the expected hash.
Mission completed.
BTW, on GNU/Linux and macOS you can still use echo as expected, but you need to use single quotes rather than double quotes, because the ! has a special meaning on many *nix-shells:
$ echo -n 'Hello World!' | jacksum -
d0e47486bbf4c16acac26f8b653592973c1362909f90262877089f9c8a4536af <stdin>
Cheers,
Johann
No comments:
Post a Comment