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.)

5
  • 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, 2015 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 4, 2016 at 5: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 4, 2016 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 4, 2016 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: sourceforge.net/projects/emacsbinw64/files/snapshot/… (I also have git-bash on %PATH% and in emac's exec-path)
    – Sam Hasler
    Jan 5, 2016 at 13:07

1 Answer 1

8
+100

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
.
.
.
5
  • 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 6, 2016 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 8, 2016 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 8, 2016 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 8, 2016 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 and created a code block begin_src sh.
    – kotchwane
    Mar 8, 2021 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.