From time to time, I need to generate a SHA-256 hash from a file hosted on some server. For me, this flow typically goes something along the lines of:
We can maybe shave some steps off by downloading directly from the browser, though that may also bring additional clicks and navigating to a download location.
Amongst the steps, shasum is the star player, and its output can be seen below.
shasum -a 256 path/to/downloaded/file
Not a huge deal. One can copy the hash from the output, but why go through multiple small manual steps when I know I can get Emacs to simplify the lot? I've expedited a similar flow in the past when cloning git repos. Let's simplify again so hashing a hosted file boils down to:
This is where I pull out dwim-shell-command (a little package I wrote) and glue the lot to get an expedited experience.
There isn't much to the function other than glueing a little elisp and a shell script via dwim-shell-command
for some buffer/error handling.
(defun dwim-shell-commands-sha-256-hash-file-at-clipboard-url ()
"Download file at clipboard URL and generate SHA-256 hash."
(interactive)
(let ((url (current-kill 0)))
(unless (string-match-p "^http[s]?://" url)
(user-error "No URL in clipboard"))
(dwim-shell-command-on-marked-files
"Generate SHA-256 hash from clipboard URL."
(format
"temp_file=$(mktemp)
function cleanup {
rm -f $temp_file
}
trap cleanup EXIT
curl --no-progress-meter --location --fail --output $temp_file %s || exit 1
shasum -a 256 $temp_file | awk '{print $1}'"
(shell-quote-argument url))
:utils '("curl" "shasum")
:on-completion
(lambda (buffer process)
(if-let ((success (= (process-exit-status process) 0))
(hash (with-current-buffer buffer
(string-trim (buffer-string)))))
(progn
(kill-buffer buffer)
(kill-new hash)
(message "Copied %s to clipboard"
(propertize hash 'face 'font-lock-string-face)))
(switch-to-buffer buffer))))))
dwim-shell-commands-sha-256-hash-file-at-clipboard-url
is now in dwim-shell-commands.el, the optional counterpart in dwim-shell-command.
There's better way. Thanks to Philip Kaludercic for suggesting curl -s example.com | sha256sum - | cut -d " " -f1
and Sacha Chua who pinged me about it.
Also note I'm now relying on the <<cb>>
template, since dwim-shell-command replaces it with the clipboard/kill ring.
(defun dwim-shell-commands-sha-256-hash-file-at-clipboard-url ()
"Download file at clipboard URL and generate SHA-256 hash."
(interactive)
(unless (string-match-p "^http[s]?://" (current-kill 0))
(user-error "No URL in clipboard"))
(dwim-shell-command-on-marked-files
"Generate SHA-256 hash from clipboard URL."
"curl -s '<<cb>>' | sha256sum - | cut -d ' ' -f1"
:utils '("curl" "sha256sum")
:on-completion
(lambda (buffer process)
(if-let ((success (= (process-exit-status process) 0))
(hash (with-current-buffer buffer
(string-trim (buffer-string)))))
(progn
(kill-buffer buffer)
(kill-new hash)
(message "Copied %s to clipboard"
(propertize hash 'face 'font-lock-string-face)))
(switch-to-buffer buffer)))))