sbilmis sbilmis - 27 days ago 13
Bash Question

How to run org-mode commands from shell?

I want to run the org-mode command via bash script. For instance, I have several org mode files to export to html under a project I defined. Then I sync files to web server etc. For this reason, without opening the emacs and exporting the files to html files, I would like to do it from bash script.

How can I run org-mode commands like

M-x org-publish-project


Then enter the project name let us say, trial_project. How can I do it within shell script?

Answer Source

I publish a project like this:

emacs -batch --load publish-doc.el --eval '(org-publish "publish-doc")'

where publish-doc.el contains the definition of the "publish-doc" project. If you can ssh to your server, you can even have the publishing-directory be remote: org will use tramp to copy the files over.

publish-doc.el should initialize org-mode if necessary and define the project - the details might depend on whether you are using the org-mode that comes with emacs, or you are using upstream versions from MELPA or the git repo. But you should be able to mimic what you do in your normal initialization and get it going. In my case, I have to modify my load-path to find org, since I clone from the upstream git repo: you might not need that at all, but if you do need it, you will need to modify the path to where your org is loaded from. The following minimal publish-doc.el publishes a set of org file in ~/org to ~/public_html - this is adapted from an example in the manual except that I had to add the publishing function:

(add-to-list 'load-path "~/src/emacs/org/org-mode/lisp/")

(require 'org)
(require 'ox-html)

(setq org-publish-project-alist
  '(("org"
     :base-directory "~/org/"
     :publishing-directory "~/public_html"
     :publishing-function org-html-publish-to-html
     :section-numbers nil
     :with-toc nil
     :html-head "<link rel=\"stylesheet\"
             href=\"../other/mystyle.css\"
             type=\"text/css\"/>")))

The command line invocation is then

 emacs -batch -l publish-doc.el --eval '(org-publish "org")'

HTH.

EDIT: As mentioned in the comments, when using -batch, you must load an initialization file: -batch implies -q so your .emacs or equivalent is not loaded. You could use -l ~/.emacs but that generally contains a lot of extraneous stuff, so when preparing a script to run from the command line, most people prefer to use a trimmed initialization file that includes only what's necessary for the task at hand (cf. the publish-doc.el file above).