You should read the built–in help for the shell-command
function. Type C-h f shell-command
and hit enter to pull it up. Specifically, it says this:
The optional second argument OUTPUT-BUFFER, if non-nil,
says to put the output in some other buffer.
If OUTPUT-BUFFER is a buffer or buffer name, erase that buffer
and insert the output there; a non-nil value of
shell-command-dont-erase-buffer prevents the buffer from being
erased. If OUTPUT-BUFFER is not a buffer and not nil (which happens
interactively when the prefix argument is given), insert the
output in current buffer after point leaving mark after it. This
cannot be done asynchronously.
Your choices for this argument are to leave it unspecified, to specify nil, t, a string containing a buffer name, or an actual buffer object. When you specify t you are telling it to write the output to the current buffer. You want to put the result into a string instead, so you should make a temporary buffer, change to that new buffer, call shell-command
, and then get the contents of the buffer as a string and delete the temporary buffer. Thankfully this kind of situation is fairly common, so in practice you don’t have to do all of that work yourself.
The function buffer-string
gets the contents of the current buffer, and with-temporary-buffer
runs any code in a new empty buffer that will vanish as soon as the code finishes running. Here’s how to put them together:
(with-temp-buffer
(shell-command "uuidgen" t)
(buffer-string))
However, one way of doing things is not enough, so there is also a slightly different way:
(with-output-to-string
(shell-command "uuidgen" standard-output))
The difference here is that with-output-to-string
expects the commands you run to put their output in the buffer stored in the standard-output variable. shell-command
doesn’t have a short way of doing that, so we have to specify it ourselves. On the other hand, it calls buffer-string
for us. Pick whichever you prefer.
Also, I should point out that you could also use the call-process
function in place of shell-command
. call-process
doesn’t start a shell to run your command in. Since you’re not using any shell features like pipelines, loops, or variables, this is an efficiency gain. Whether that gain is minor or major depends on your exact use case. The arguments are slightly different though:
(with-output-to-string
(call-process "uuidgen" nil standard-output))
uuidgen
the result of the call is different each time so your variable will not be the same if you are using it in more than one call.