Function: org-babel-sh-evaluate

org-babel-sh-evaluate is a byte-compiled function defined in ob-shell.el.gz.

Signature

(org-babel-sh-evaluate SESSION BODY &optional PARAMS STDIN CMDLINE)

Documentation

Pass BODY to the Shell process in BUFFER.

If RESULT-TYPE equals output then return a list of the outputs of the statements in BODY, if RESULT-TYPE equals value then return the value of the last statement in BODY.

Source Code

;; Defined in /usr/src/emacs/lisp/org/ob-shell.el.gz
(defun org-babel-sh-evaluate (session body &optional params stdin cmdline)
  "Pass BODY to the Shell process in BUFFER.
If RESULT-TYPE equals `output' then return a list of the outputs
of the statements in BODY, if RESULT-TYPE equals `value' then
return the value of the last statement in BODY."
  (let* ((shebang (cdr (assq :shebang params)))
         (async (org-babel-comint-use-async params))
	 (results-params (cdr (assq :result-params params)))
	 (value-is-exit-status
	  (or (and
	       (equal '("replace") results-params)
	       (not org-babel-shell-results-defaults-to-output))
	      (member "value" results-params)))
	 (results
	  (cond
	   ((or stdin cmdline)	       ; external shell script w/STDIN
	    (let ((script-file (org-babel-temp-file "sh-script-"))
		  (stdin-file (org-babel-temp-file "sh-stdin-"))
		  (padline (not (string= "no" (cdr (assq :padline params))))))
	      (with-temp-file script-file
		(if shebang
                    (insert shebang "\n")
                  ;; Provide shell name explicitly.
                  ;; This is necessary because running, for example,
                  ;; dash script-for-dash.sh will use /bin/sh.
                  (insert (format "#!/usr/bin/env %s" shell-file-name) "\n"))
		(when padline (insert "\n"))
		(insert body))
	      (set-file-modes script-file #o755)
	      (with-temp-file stdin-file (insert (or stdin "")))
	      (with-temp-buffer
                (with-connection-local-variables
                 ;; `with-connection-local-variables' will override
                 ;; `shell-file-name' and `shell-command-swtich' as
                 ;; needed for the remote connection.
                 (apply #'process-file
                        shell-file-name
                        stdin-file
                        (current-buffer)
                        nil
                        (list shell-command-switch
                              (concat (file-local-name script-file)  " " (format "%s" cmdline)))))
		(buffer-string))))
	   (session			; session evaluation
            (if async
                (progn
                  (let ((uuid (org-id-uuid)))
                    (org-babel-comint-async-register
                     session
                     (current-buffer)
                     "ob_comint_async_shell_\\(start\\|end\\|file\\)_\\(.+\\)"
                     'ob-shell-async-chunk-callback
                     nil)
                    (org-babel-comint-async-delete-dangling-and-eval
                        session
                      (insert (format ob-shell-async-indicator "start" uuid))
                      (comint-send-input nil t)
                      (insert (org-trim body))
                      (comint-send-input nil t)
                      (insert (format ob-shell-async-indicator "end" uuid))
                      (comint-send-input nil t))
                    uuid))
	      (mapconcat
	       #'org-babel-sh-strip-weird-long-prompt
	       (mapcar
                #'org-trim
                (butlast ; Remove eoe indicator
                 (org-babel-comint-with-output
		     (session org-babel-sh-eoe-output t body)
                   (insert (org-trim body) "\n"
                           org-babel-sh-eoe-indicator)
		   (comint-send-input nil t))
                 ;; Remove `org-babel-sh-eoe-indicator' output line.
                 1))
	       "\n")))
	   ;; External shell script, with or without a predefined
	   ;; shebang.
	   ((org-string-nw-p shebang)
	    (let ((script-file (org-babel-temp-file "sh-script-"))
		  (padline (not (equal "no" (cdr (assq :padline params))))))
	      (with-temp-file script-file
		(insert shebang "\n")
		(when padline (insert "\n"))
		(insert body))
	      (set-file-modes script-file #o755)
              (if (file-remote-p script-file)
                  ;; Run remote script using its local path as COMMAND.
                  ;; The remote execution is ensured by setting
                  ;; correct `default-directory'.
                  (let ((default-directory (file-name-directory script-file)))
                    (org-babel-eval (file-local-name script-file) ""))
                (org-babel-eval script-file ""))))
	   (t (org-babel-eval shell-file-name (org-trim body))))))
    (when (and results value-is-exit-status)
      (setq results (car (reverse (split-string results "\n" t)))))
    (when results
      (let ((result-params (cdr (assq :result-params params))))
        (org-babel-result-cond result-params
          results
          (let ((tmp-file (org-babel-temp-file "sh-")))
            (with-temp-file tmp-file (insert results))
            (org-babel-import-elisp-from-file tmp-file)))))))