From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nicolas Goaziou Subject: Re: Bug: org-babel-expand-src-block expands sh blocks independent of shell defined by src block [9.0.5 (9.0.5-elpaplus @ ~/.emacs.d/elpa/org-plus-contrib-20170210/)] Date: Mon, 08 May 2017 11:54:46 +0200 Message-ID: <87shkf65cp.fsf@nicolasgoaziou.fr> References: <9837c90a-ff74-443d-e585-2a4c240dd52a@psi.ch> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:58582) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d7fNS-0000L2-QW for emacs-orgmode@gnu.org; Mon, 08 May 2017 05:54:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d7fNR-0001Ia-DS for emacs-orgmode@gnu.org; Mon, 08 May 2017 05:54:50 -0400 Received: from relay4-d.mail.gandi.net ([2001:4b98:c:538::196]:47054) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d7fNR-0001IV-6f for emacs-orgmode@gnu.org; Mon, 08 May 2017 05:54:49 -0400 In-Reply-To: <9837c90a-ff74-443d-e585-2a4c240dd52a@psi.ch> (Derek Feichtinger's message of "Sun, 7 May 2017 17:47:05 +0200") List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: Derek Feichtinger Cc: emacs-orgmode@gnu.org Hello, Derek Feichtinger writes: > When using =org-babel-expand-src-block= with a shell src block one > always gets the same code expansion (in my case bash) independent of the > shell that is used while the execution of the shell block uses the > correct expansion. > > > I define the following table to illustrate the problem: > > #+NAME: tbltest > | col1 | col2 | col3 | > > | 11 | 12 | 13 | > | 21 | 22 | 23 | > | 31 | 32 | 33 | > > Now for the example source block where I read in the table > > #+BEGIN_SRC sh :results value :exports both :var tbl=tbltest :colnames yes > echo $tbl > #+END_SRC > > > When expanding the sh source block above with > =org-babel-expand-src-block= it is wrongly expanded to the > bash expansion and not to the sh expansion that is used when the block > is executed. So, instead of the > sh expansion, > > tbl='11 12 13 > 21 22 23 > 31 32 33' > > > I see the following bash related expansion in the opened buffer: > > #+BEGIN_EXAMPLE > unset tbl > declare -A tbl > tbl['11']='12 > 13' > tbl['21']='22 > 23' > tbl['31']='32 > 33' > echo $tbl > #+END_EXAMPLE > > > Reason: > > The case distinction in =org-babel-variable-assignments:shell= is > made based on the shell-file-name which is a standard emacs > variable set by emacs in C code. This is pointing to "/bin/bash" > for my installation. > > #+BEGIN_SRC elisp :exports source > (defun org-babel-variable-assignments:shell (params) > "Return list of shell statements assigning the block's variables." > (let ((sep (cdr (assq :separator params))) > (hline (when (string= "yes" (cdr (assq :hlines params))) > (or (cdr (assq :hline-string params)) > "hline")))) > (mapcar > (lambda (pair) > (if (string-suffix-p "bash" shell-file-name) > (org-babel--variable-assignments:bash > (car pair) (cdr pair) sep hline) > (org-babel--variable-assignments:sh-generic > (car pair) (cdr pair) sep hline))) > (org-babel--get-vars params)))) > #+END_SRC > > > Looking at the calls stack for the case where we execute the source > block and where we just expand it, we see > the following call stack for execution > > #+BEGIN_EXAMPLE > org-babel-variable-assignments:shell > org-babel-execute:shell > org-babel-execute:sh > org-babel-execute-src-block > #+END_EXAMPLE > > > while in the case of just expanding the source block we have > > #+BEGIN_EXAMPLE > org-babel-variable-assignments:sh > org-babel-expand-src-block > #+END_EXAMPLE > > > Note that =org-babel-variable-assignments:sh= is an alias for > =org-babel-variable-assignments:shell=. > > A bit of investigation shows that for all shell languages there > are aliases defined that finally call > =org-babel-execute:shell=. This is set up in the > =org-babel-shell-initialize= function. And it is set up in a way > that =shell-file-name= is overridden by the name of the > particular shell, and this then leads to the correct case > distinction using =shell-file-name= in > =org-babel-variable-assignments:shell=. > > #+BEGIN_SRC elisp :exports source > (defun org-babel-shell-initialize () > "Define execution functions associated to shell names. > This function has to be called whenever `org-babel-shell-names' > is modified outside the Customize interface." > (interactive) > (dolist (name org-babel-shell-names) > (eval `(defun ,(intern (concat "org-babel-execute:" name)) > (body params) > ,(format "Execute a block of %s commands with Babel." name) > (let ((shell-file-name ,name)) > (org-babel-execute:shell body params)))) > (eval `(defalias ',(intern (concat > "org-babel-variable-assignments:" name)) > 'org-babel-variable-assignments:shell > ,(format "Return list of %s statements assigning to the block's \ > variables." > name))))) > #+END_SRC > > The same kind of overriding would have to be in place when > =org-babel-expand-src-block= calls > =org-babel-variable-assignments:shell= in the simple code expansion > case. But that > would be a bit hacky since the generic =org-babel-expand-src-block= > function should > not override variables needed in just one subclass of backends. It would be > cleaner to have different functions =org-babel-variable-assignments:XXX= > for the > different shells. Thank you for the report. Since you went pretty far already into the analysis, would you want to provide a patch implementing your suggestion, i.e., have different functions =org-babel-variable-assignments:XXX= for the different shells? Regards, -- Nicolas Goaziou