emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to get shell source blocks to read my profile?


From: Tim Cross
Subject: Re: How to get shell source blocks to read my profile?
Date: Mon, 15 Mar 2021 14:02:04 +1100
User-agent: mu4e 1.5.10; emacs 27.1.91

comments in-line ...

George Mauer <gmauer@gmail.com> writes:

> Hey Tim, thanks for helping out. I commented inline to your response below 
> but I'll sum up and ask the outstanding questions more directly here as well.
>
> I think you might have misread what I was doing - I had 3 different variables 
> set in 3 different places precisely because I want to dissect things and 
> figure
> out which profile/rc scripts were run.
>
> Yes, this is emacs running in GUI mode so yes, it doesn't have a shell as a 
> parent. But that only explains why these environment variables aren't in
> emacs itself, not the spawned bash or zsh processes
>

To clarify, the GUI mode is unrelated. You can run in GUI mode from a
terminal and the emacs process will inherit the environment in the
terminal. If that terminal is a login terminal (i.e. terminal shell was
run as a login shell), the 'profile' file will be sourced and the 'rc'
file will have been sourced. If not a login shell, only the rc file will
have been sourced.

If on the other hand, Emacs is started from the dock, it is started in a
completely different process chain and is not a child of a login
process. This is why, if you want your emacs to have /usr/local/bin in
the path, you have to add it to /etc/paths or /etc/path.d whereas if you
start emacs from within a terminal (GUI or text mode), you only need to
add /usr/local/bin to your PATH setting in .profile (just an example to
highlight the difference between running from in a terminal and running
from the dock).

> So to sum up the specific questions. My ~shell-file-name~ is ~/bin/zsh~ which 
> seems to be what ~ob-shell~ is passing down to be run. So why on earth
> does my ~GIM_ZSHRC~ variable not show up here?
>
>   #+begin_src shell
>     env
>   #+end_src
>
> When I actually directly call bash
>
>  #+begin_src shell
>     bash -c env
>   #+end_src
>

Have a closer look on the section in the bash manual on the difference
between interactive and non-interactive shells. (also holds for zsh).
Basically, the 'rc' files are not sourced for non-interactive shells.

> Why would the output not include ~GIM_BASHRC~ - it should have been run, 
> right?
>

No. Adding the -c means it is a non-interactive shell, so no .bashrc
sourcing.


> What about when I call this? Even with explicitly selecting the rc file to 
> run, it seems to not
>
>   #+begin_src shell
>     bash --rcfile ~/.bashrc -c env
>   #+end_src
>

Same issue here. --rcfile only has effect in interactive shells.

> Finally, the outstanding question about ~ob-shell~ is if there is any way to 
> force it to run the shell processes' rc-script? I really would have expected 
> it to
> be run in the above situations already...
>

You could try sourcing it e.g.

#+begin_src shell
source ~/.bashrc
env
#+end_src

or use 'shorthand' dot

#+begin_src shell
. ~/.bashrc
env
#+end_src

there are also some options you can add at the 'shebang' line i.e.

#!/bin/bash -l

or

#!/bin/bash -i

which will change the behaviour.

There is a lot of 'meat' in the bash man page and there is a lot of
additional information in the bash info pages. However, both can be a
bit terse and because the info is very 'dense', it is very easy to miss
key points.

In order to have environment variables available inside your org source
blocks, you really need to

- have them in the environment inherited by emacs when it starts. This
  will depend how you start Emacs (i.e from within an interactive shell
  vs from the dock). Note that you typically don't see this issue under
  Linux because in most Linux setups, the X environment is started
  inside a login shell. So everything started as part of the X session,
  like a dock, is a child of the login process and therefore inherits
  the login environment. On a mac, the dock is not part of the login
  shell, so it only inherits what is in the system wide bash profile
  file.

- Ensure your source block run as interactive and/or login shells using
  shebang options like -i or -l

- explicitly source the .profile or .bashrc file using a source call

- pass the environment variable in on the command line e.g.

#+begin_src shell
FRED=barney env
#+end_src

will result in

FRED=barney

being in the output from 'env'.


> -----------
>
>  Is this perhaps on a Mac where Emacs is started from the dock?
>
> Yup like I said, its in GUI mode so I understand why those environment 
> variables aren't within emads itself
>

It is actually a little more subtle. It isn't because your running in
GUI mode those variables are not there. It is because your running from
the dock. Run it in GUI mode from within a login terminal and all those
variables will be 'in' emacs.

<snip>

> It is certainly confusing but I think I got a handle on it mostly. If it's a 
> login shell you'll run a profile, if it's not you'll run the default rc file 
> unless one of the
> options were specified. I think each is named specific to each shell name but 
> oftentimes you chain them together in practice.
>

There is also a difference between interactive and non-interactive
shells. I suspect this is the root cause of your issue. The source block
being run are non-interactive.

--
Tim Cross



reply via email to

[Prev in Thread] Current Thread [Next in Thread]