Why is my Ruby Git script hook run with the wrong $PATH?
The reason i didn't wanted to use env
instead of a fixed path to ruby or a rvm wrapper was that this is for a Team Project and not everyone in the Team is using RVM.
My final solution was to write my own wrapper script an add it to that project.
All client-side git hooks 're living in $PROJECT/bin/hooks
, all of them ruby scripts.
Now, i've just put that mentioned wrapper in there, and created a symlink to that wrapper in $PROJECT/.git/hooks
for all the hooks.
The script check's if RVM is used and if so fixes the $PATH
var and if there are .ruby-version
and/or .ruby-gemset
files in the project root it loads the according version/gemset.
Then it'll run the according ruby script
Here's the wrapper in case you're interested:
#!/bin/bash
if [ -d "$HOME/.rvm/bin" ]; then
PATH="$HOME/.rvm/bin:$PATH"
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
if [ -f ".ruby-version" ]; then
rvm use "$(cat .ruby-version)"
fi
if [ -f ".ruby-gemset" ]; then
rvm gemset use "$(cat .ruby-gemset)"
fi
fi
ruby "bin/hooks/$(basename "$0").rb"
So, i'll get my rvm version/gemset and everybody else the ruby version they have in their PATH, and everyone is Happy.
Post-receive hook not using correct Ruby
so:
1) your shebang is /usr/bin/env sh
- this is not RVM compatible shell, either use zsh
or bash
2) you need to use RVM somehow, when you login via ssh
you already used RVM via ~/.bash_profile
but in the script you do not load RVM, try this shebang:
/home7/contenw6/.rvm/bin/rvm-shell 1.9.3-p194
PATH in post-receive hook doesn't contain PATH as set in bashrc
First, a small bit of file setup:
$ mkdir /tmp/dir1 /tmp/dir2
$ date > /tmp/dir1/foo
$ date > /tmp/dir2/bar
Now, consider a simple script:
$ chmod 755 foo.sh; cat foo.sh
#!/bin/sh
# intentionally set an inadequate PATH:
export PATH=""
# script to 'ls' two dirs, show that output, and show the diff of the two.
ls /tmp/dir1 > temp1
ls /tmp/dir2 > temp2
echo /tmp/dir1:
cat temp1
echo /tmp/dir2:
cat temp2
diff temp1 temp2
The script is well-formed syntactically, but let's see what happens:
$ ./foo.sh
./foo.sh: ls: not found
./foo.sh: ls: not found
/tmp/dir1:
./foo.sh: cat: not found
/tmp/dir2:
./foo.sh: cat: not found
./foo.sh: diff: not found
The path isn't sufficient for the script interpreter to find the executables the script wants to run. Three separate executables fail to load: ls
, cat
, and diff
. So let's help it a little. Since ls
typically resides in the /bin
directory, let's edit PATH
to become:
export PATH="/bin"
and try again:
$ ./foo.sh
/tmp/dir1:
foo
/tmp/dir2:
bar
./foo.sh: diff: not found
Well, ls
runs okay now. That's progress. And since cat
also lives in /bin, adding /bin to the path killed two birds with one stone. But diff
still isn't being found, because diff
lives in /usr/bin. So let's add that to the PATH:
export PATH="/bin:/usr/bin"
and try again:
$ ./foo.sh
/tmp/dir1:
foo
/tmp/dir2:
bar
1c1
< foo
---
> bar
Voila! No more errors, because the PATH
variable contains everything needed to allow the script interpreter to locate the executables that are called by the script.
The other way is to tell PATH
to butt out and specify your own path to executables. This method is sometimes handy when you might not trust or desire the "standard" executables, for whatever reason. When structuring a script in this fashion, I prefer to use variables for the executables I want to reference, so that if^H^Hwhen the location changes, I can just change the variables and don't have to search the entire script for all the invocations of that executable.
$ chmod 755 bar.sh; cat bar.sh
#!/bin/sh
# intentionally set an inadequate PATH:
export PATH=""
# ls lives in /bin:
LS="/bin/ls"
# so does cat:
CAT="/bin/cat"
# but diff lives in /usr/bin:
DIFF="/usr/bin/diff"
# script to 'ls' two dirs, show that output, and show the diff of the two.
$LS /tmp/dir1 > temp1
$LS /tmp/dir2 > temp2
echo /tmp/dir1:
$CAT temp1
echo /tmp/dir2:
$CAT temp2
$DIFF temp1 temp2
And the output:
$ ./bar.sh
/tmp/dir1:
foo
/tmp/dir2:
bar
1c1
< foo
---
> bar
You can mix and match these approaches, by specifying a PATH
that includes most things, and specifying absolute paths for the others, but your problem is arising because you have not done that.
You either need to specify a full and adequate PATH
in your hook script, and/or specify absolute paths to the remaining executables (if any) that reside outside whatever PATH
variable your hook script currently uses.
How can I run a virtualenv python script as a git pre-commit hook
You can check in your pre-commit script for the $VIRTUAL_ENV variable and prepend it to $PATH accordingly:
#!/bin/bash
if [ -n $VIRTUAL_ENV ]; then
PATH=$VIRTUAL_ENV/bin:$PATH
fi
for f in .git/hooks/pre-commit.d/*; do
if [ -x "$f" ]; then
if ! "$f"; then
echo "DID NOT COMMIT YOUR CHANGES!";
exit 1
fi
fi
done
RVM is not setting my PATH in `fish`, but should be
Some kind of solution
So far I have it barely working by making the change from:
grep -E '^rvm|^GEM_PATH|^GEM_HOME'
to:
grep -E '^rvm|^[^=]*PATH|^GEM_HOME'
Not sure what side effects that will cause, but from looking at the rvm.fish
code, that would seem to be missing.
Related aside
An older version had the ^[^=]*PATH\
term in it, like my system's previous version, and can also be randomly found here: GitHub Gist - ToniRib/rvm.fish
That is for escaping the pipe (|) characters, but I can't see why that is needed inside of single quotes. My fix works specifically without the backslashes, and just plain pipe characters.
Non-functional alternative
I have alternatively tried a patch without the other code such as this one:
and set -xg GEM_PATH (echo $GEM_PATH | sed 's/ /:/g')
and set -xg PATH (echo $GEM_PATH | sed 's/:/ /g') $MY_RUBY_HOME/bin $PATH
I am continuing to add lines to it, but still see various errors. First I needed the "rubies" directory for the correct version of ruby
, then both gem paths modified with spaces for fish
, and still I am having issues, so taking bash
's PATH
environment variable wholesale and letting the rvm
script do its own work is the best I have so far.
System Variable path is different in command prompt
Turned out to be an issue with a bat file that run each time I started cmd
, and it modified it's variables! Thanks to @eryksun and @ılǝ - it seems that in the registry (HKCU\Software\Microsoft\Command Processor\AutoRun
) you might have something like that. My problem was with nvmw package (https://www.npmjs.com/package/nvmw) that when installed, created this .bat file and stored my current PATH variable. Then it was setting it to the cmd every time I use it, and so it never got updated.
You can see the issue I've created here: https://github.com/nanjingboy/nvmw/issues/5
SHORT STORY: check your HKCU\Software\Microsoft\Command Processor\AutoRun
, and DO NOT USE NVMW package!
Related Topics
How to Execute 2 or More Commands in the Same Ssh Session
Ruby, Generate a Random Hex Color (Only Light Colors)
Rails Generate Controller Gives Me Load Error
Linking Two Models in a Multi-Model Form
Do I Need to Indent My Code in Ruby
Rake Test Very Slow in Windows
How to Install Rmagick Gem on Windows
When to Use Association Extensions VS Named Scopes
Bundler Could Not Find Compatible Versions for Gem "Bundler": in Gemfile:
Getting Count of Elements by 'Created_At' by Day in a Given Month
Why Does Hash#Select and Hash#Reject Pass a Key to a Unary Block
Handle Check Box Forms with an ':Has_Many :Through' Record Association
Gem Install Rails Doesn't Work Due to Openssl/Etimedout in Windows
Parsing Large Xml with Nokogiri
Ruby Enterprise Edition VS Ruby 1.9