Reputation: 6964
How do I execute a shell command (eg, git gui
) from a specific directory? I'd prefer a cross-platform approach that doesn't depend shell operators like &&
or ;
because I need this to run on Windows and unix. (For example, calling cd /path/to/dir && git gui
won't work on Windows because &&
is not valid.)
I tried:
(async-shell-command (concat "cd \""
(replace-regexp-in-string
"/" "\\\\" (file-name-directory (buffer-file-name))) "\" ; git gui"))
That fails because for whatever reason the shell thinks ; git gui
is part of the path, and it reports: The system cannot find the path specified.
So, I'd rather not deal with shell quirks and I'm hoping there's an elisp function that sets the directory for shell-command
or async-shell-command
. I tried:
(shell-process-pushd (file-name-directory (buffer-file-name)))
(shell-command "git gui")
(shell-process-popd nil)
That had no effect: git gui
always opens in my home directory. (Also, shell-process-pushd/popd
are not documented.)
This also doesn't work:
(start-process "gitgui" nil "git" "gui")
Neither does this:
(let '(bufdir (file-name-directory (buffer-file-name)))
(with-temp-buffer
(print bufdir)
(cd bufdir)
(shell-command "git gui")))
Upvotes: 11
Views: 8228
Reputation: 6964
(shell-command)
does use the the buffer's default-directory
, which means there is no reason to cd
to the buffer's directory.
The problem in my case was that I was mistakenly running git gui
on a buffer that didn't have an associated .git/
directory.
Upvotes: 3
Reputation: 17707
Are you sure you're using the trailing slash to indicate directory name in emacs-lisp?
(let ((default-directory "~/.emacs.d"))
(shell-command-to-string "echo $PWD"))
;;; ⇒ "/Users/me"
(let ((default-directory "~/.emacs.d/"))
(shell-command-to-string "echo $PWD"))
;;; ⇒ "/Users/me/.emacs.d"
Upvotes: 12
Reputation: 2350
Try this:
(let ((default-directory "~/.emacs.d/")) (shell-command "ls"))
Upvotes: 1