I was trying to compute sha256 for a simple string, namely "abc". I found out that using sha256sum utility like this:
sha256sum file_with_string
gives results identical to:
sha256sum # enter, to read input from stdin
abc
^D
namely:
edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb
Note, that before the end-of-input signal another newline was fed to stdin.
What bugged me at first was that when I decided to verify it with an online checksum calculator, the result was different:
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
I figured it might have had something to do with the second newline I fed to stdin, so I tried inserting ^D twice this time (instead of using newline) with the following result:
abcba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
Now, this is of course poorly formatted (due to the lack of a newline character), but that aside, it matches the one above.
After that, I realized I clearly fail to understand something about input parsing in the shell. I double-checked and there's no redundant newline in the file I specified initially, so why am I experiencing this behavior?
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
different fromprintf abc | sha256sum
? – Arkadiusz Drabczyk Oct 10 '20 at 13:25sha256sum file
where file contains the actualabc
- very much is. And that's the method I used - with an actual file. – mdx Oct 10 '20 at 13:29printf abc > file; sha256sum file
– Arkadiusz Drabczyk Oct 10 '20 at 13:30vim
behaves well and terminates the line. – Kamil Maciorowski Oct 10 '20 at 14:15vim
,vim
will automatically add a terminating newline if there isn't already one. You can check withprintf abc > foo; cp foo bar; vim bar
, then invim
simply enter:wq
without doing any other modification. Then compare the two files withdiff foo bar
. – Oct 10 '20 at 14:57^D
works (my explanation is probably not the best, and there's a lot of stupid misinformation online -- that^D
sends a "signal", etc), try the following: open two terminal windows, and in the first runtty
, and take the path printed by it (eg./dev/pts/7
) and runwhile :; do printf NEWCAT:; cat -v; done >/dev/pts/7
in the second terminal. Then experiment with entering^D
after either a newline or some other text. – Oct 10 '20 at 15:25^D
is not actually sent, it just ends the stream. – jcaron Oct 10 '20 at 21:54sha256
command (which they also explicitly mentioned in the code block). – ilkkachu Oct 10 '20 at 21:58sha256sum file_with_string
orsha256sum
. Usestrace sha256sum
to see theread
system call it makes, and see what input you submit when you hit control-D on an empty line (creating a read()=0 meaning EOF) vs. a non-empty line (just submitting the line). (You can do this withstrace cat > /dev/null
as well. Similar to @user414777) Anyway, is that what this question is about? – Peter Cordes Oct 11 '20 at 13:20\004
), and 10 is newline (LF, line feed,\012
,\n
). With the typical stty settings, the terminal converts a Ctrl-D (EOT) at the beginning of line to an end-of-file indication for the process reading from that TTY device, as indicated byread(0, "abc\n", 32768) = 4
on the stderr ofstrace -e read sha256sum
. Thus it's the same asprintf 'abc\n' | strace -e read sha256sum
. – pts Oct 12 '20 at 15:07