Friday, October 31, 2014

zsh - Why is my $PATH different in the executed script?


echo $PATH inside gnome terminal:



/home/pc/less.js/bin:/home/pc/local/bin:/home/pc/local/bin:/home/pc/.rvm/gems/ruby-1.9.2-head/bin:/home/pc/.rvm/gems/ruby-1.9.2-head@global/bin:/home/pc/.rvm/rubies/ruby-1.9.2-head/bin:/home/pc/.rvm/bin:/usr/local/bin:/home/pc/local/bin:/usr/lib64/mpi/gcc/openmpi/bin:/home/pc/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/usr/lib64/jvm/jre/bin:/home/pc/Programming/Software/tup:/home/pc/Programming/Libraries/depottools:/home/pc/Programming/Libraries/apache-maven-3.0.4/bin



From inside this script:


#!/bin/zsh
echo $PATH
while inotifywait -e modify /home/pc/vbox-shared/less; do
lessc custom.less > /home/pc/vbox-shared/less/custom.css
done


/usr/lib64/mpi/gcc/openmpi/bin:/home/pc/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/usr/lib64/jvm/jre/bin



As you can see, I modified my .zshrc file with this:



export PATH=/home/pc/less.js/bin:$PATH



Why does it not work in the script when executed as a file? The problem is that the lessc command is not being found.


Answer



The script is run using /bin/zsh, which is not an interactive or login shell and doesn't load this file. From man zsh, emphasis mine:



Commands are first read from /etc/zshenv; this cannot be overridden. Subsequent behaviour is modified by the RCS and GLOBAL_RCS options; the former affects all startup files, while the second only affects global startup files (those shown here with an path starting with a /). If one of the options is unset at any point, any subsequent startup file(s) of the corresponding type will not be read. It is also possible for a file in $ZDOTDIR to re-enable GLOBAL_RCS. Both RCS and GLOBAL_RCS are set by default.


Commands are then read from $ZDOTDIR/.zshenv. If the shell is a login shell, commands are read from /etc/zprofile and then $ZDOTDIR/.zprofile. Then, if the shell is interactive, commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc. Finally, if the shell is a login shell, /etc/zlogin and $ZDOTDIR/.zlogin are read.



The script inherits the environment from where it's called, and if this isn't another (interactive) shell, it won't contain the preferences you set in .zshrc.


You can set the PATH where it applies globally (e.g. /etc/zshenv), set it explicitly in the script directly, or change the shebang script header to run /bin/zsh -i instead, making it load .zshrc (quoting man zsh: Force shell to be interactive. It is still possible to specify a script to execute.).


Alternatively, just specify the full path to the program that isn't on the default PATH, e.g. /home/pc/less.js/bin/lessc.


No comments:

Post a Comment

linux - How to SSH to ec2 instance in VPC private subnet via NAT server

I have created a VPC in aws with a public subnet and a private subnet. The private subnet does not have direct access to external network. S...