8

Is there a simple configuration to get org-babel to invoke cmd.exe that doesn't involve modifying the org-babel source?

Googling for ["org-babel" sh "cmd"] finds this email list discussion from 2010: Re: [Orgmode] org-babel-sh and Microsoft Windows

but that looks like a blanket solution, not one that could be applied on a per-block or per-file, as I'd want to able to run sh/bash too.

(This is for literate DevOps of windows servers, so "use sh/bash/zsh" is unfortunately not a option.)

Sam Hasler
  • 83
  • 1
  • 7
  • 1
    For one off cmd shell, I've used `(run-shell-command "cmd /c start cmd /k dir")` in the past. Perhaps you can tweak that for individual babel blocks. – Emacs User Dec 23 '15 at 17:29
  • @EmacsUser The situation is rather difficult! `run-shell-command` in `(run-shell-command "cmd /c start cmd /k dir")` uses `shell-file-name` which is set to `bash`. This cannot be let-set in a around advice of `org-babel-sh-evaluate` because `org-babel--shell-command-on-region` uses `(process-file shell-file-name input-file ... shell-command-switch command)` with `shell-command-switch` equal to "-c" and `command` set to `org-babel-sh-command`. So the shell is invoked twice. Setting the switches and command to nil does not work (error stringp). One would need a new org-babel language to avoid sh – Tobias Jan 04 '16 at 05:35
  • @Tobias perhaps the easiest solution would be to copy `ob-sh-el` to a new language `ob-cmd.el` and edit it to work with cmd. – Sam Hasler Jan 04 '16 at 15:12
  • Which emacs do you use? Cygwin-environment or mingw-environment? Could you post the `emacs-version` output? Note, a (big) problem is also process-communication with `cmd.exe` via `stdin` and `stdout`. – Tobias Jan 04 '16 at 15:26
  • @Tobias I'm using `GNU Emacs 25.0.50.1 (x86_64-w64-mingw32) of 2015-09-07` on Windows 7. Specifically, this build: http://sourceforge.net/projects/emacsbinw64/files/snapshot/emacs-bin-w64-20150907-af629df.7z/download (I also have git-bash on `%PATH%` and in emac's `exec-path`) – Sam Hasler Jan 05 '16 at 13:07

1 Answers1

8

In spite of what I wrote in the comments one can set cmd as shell in ob-sh! The only thing to be aware of is that one needs to use cmdproxy.exe instead of cmd.exe to get the output to stdout right.

You can also do this on a per-code-block basis with the following small advice (working with your version GNU Emacs 25.0.50.1 (x86_64-w64-mingw32)). It defines the new header argument :shcmd for sh-code blocks. There you set the shell you want to use, e.g., cmdproxy.exe

(require 'ob-sh)
(defadvice org-babel-sh-evaluate (around set-shell activate)
  "Add header argument :shcmd that determines the shell to be called."
  (let* ((org-babel-sh-command (or (cdr (assoc :shcmd params)) org-babel-sh-command)))
    ad-do-it
    ))

After installing this advice you can use it as in the following example:

#+BEGIN_SRC sh :shcmd "cmdproxy.exe"
dir
#+END_SRC

#+RESULTS:
#+begin_example
dir
 Datenträger in Laufwerk C: ist CRUZER
 Volumeseriennummer: CEAB-B990

 Verzeichnis von c:\temp
.
..
test.org
.
.
.
Tobias
  • 32,569
  • 1
  • 34
  • 75
  • NICE! Thanks Tobias. I had to add the dir that `cmdproxy` was in to `exec-path` and restart emacs, otherwise I needed the full path in the `BEGIN_SRC` line. – Sam Hasler Jan 06 '16 at 16:57
  • I'm having issues with cmd invoking clink because clink has set an autorun entry for itself. (It prefixes every line with "C^HL^HI^HN^HK^H") I think it would fix it if cmd was passed "/D" to supress autoruns but I'm having a hard time working out how to do that. I think it's because emacs is actually invoking bash to call cmdproxy, and bash is then effectively doing `cmd /c "cmdproxy"` and I need it to do `cmd /D /c "cmdproxy"` – Sam Hasler Jan 08 '16 at 15:33
  • No, as far as I remember from my investigations `shell-command` is used with `shell-file-name` and this is set to `cmdproxy`. Furthermore, it is using the switches in `shell-command-switch` before the actual command string. But, in the end we have seen that I do not know your exact configuration. I also have emacs 25.0.50 running but from another source. – Tobias Jan 08 '16 at 15:40
  • DOH, customising `shell-file-name` and setting it from bash to cmdproxy fixed it. Thanks for your help. (When I have more reputation on this site I'll be sending another bounty!) – Sam Hasler Jan 08 '16 at 16:50
  • I would very much like to see an update on this post. On Emacs 27 and Windows 10, there seems to be no need for any of this, as cmd seems to work "out of the box" after I set the config as specified [here](https://emacs.stackexchange.com/a/43768/23812) and created a code block `begin_src sh`. – kotchwane Mar 08 '21 at 18:20