4

It seems that emacs appends a newline to the return value for shell-command-to-string. For example, the return value for (shell-command-to-string "pwd") is:

"/path/to/directory
"

While the return value for (pwd) is "/path/to/directory". In other words:

(string= (shell-command-to-string "pwd") (pwd))

will return nil.

I am wondering:

  1. What is the reason for this?
  2. What would be an idiomatic way to remove the newline from the output so that (string= (shell-command-to-string "pwd") (pwd)) would return t?
  • 5
    The newline is produced by pwd, not Emacs. Also, you should use string=, or equal for strings, not eq. – npostavs Apr 27 '16 at 19:50
  • @npostavs I used pwd as a simple example, but the newline gets added in other situations I have tested. For example, running a python script that returns a string value with no newline will have a newline added when run from shell-command-to-string. Also, cating a file with only one line of text and no trailing newline will have the newline appended in the shell-command-to-string output. – elethan Apr 27 '16 at 20:06
  • 1
    I think @npostavs is correct - can you find an example where a shell command that doesn't include a final newline in a terminal has one inserted by shell-command-to-string? Note that in a terminal the prompt following the output of most commands is on the line after the output, not on the same line as the last line of the output, indicating that there's a newline at the end. – Tyler Apr 27 '16 at 21:34
  • 1
    Further to npostavs's comment on testing equality, you cannot use eq to compare two strings -- not unless they are the same lisp object. e.g. (eq "foo" "foo") is comparing two different lisp objects, and is therefore nil. – phils Apr 28 '16 at 2:24
  • 1
    In this particular example and similar cases I'd just avoid the shell entirely and use (car (process-lines "pwd")). – lunaryorn Apr 28 '16 at 20:44
7

Shell commands usually terminate their output with a newline. shell-command-to-string doesn't add a newline, it merely stores the contents of the output of the shell command — including the final newline, if any — in a string. Compare

(shell-command-to-string "echo hello")

which contains the final newline generated by echo, and

(shell-command-to-string "echo -n hello")

which doesn't.

You can postprocess the returned string to get rid of the newline, for example with the following function:

(defun string-trim-final-newline (string)
  (let ((len (length string)))
    (cond
      ((and (> len 0) (eql (aref string (- len 1)) ?\n))
       (substring string 0 (- len 1)))
      (t string))))
  • 2
    Alternatively, you can add a newline char to the end of the other string. ;-) – Drew Apr 28 '16 at 2:11
4

As already explained, the newline is coming from the shell command output.

You can eliminate that by making the shell command format its output with printf (which is portable and reliable when it comes to displaying newlines, unlike echo).

(shell-command-to-string "printf %s \"$(pwd)\"")

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.