PATH in post-receive hook doesn't contain PATH as set in bashrc

匆匆过客 提交于 2021-01-28 14:08:51

问题


How can I set the PATH on Ubuntu in a way where its variables that I set are also set in a post-receive script? Currently I'm doing it via the ~/.bashrc file like this:

export PATH="$PATH:/opt/mssql-tools/bin"

but can't see any change in the PATH if I print it from the hook. Therefore, if I try to execute the command in question in the hook, I get

remote: FileNotFoundError: [Errno 2] No such file or directory: 'sqlcmd': 'sqlcmd'

So the only solution I see right now is defining it again in the post-receive hook itself, like this:

export PATH="$PATH:/opt/mssql-tools/bin"

Is there a better way?

Thank you!


回答1:


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.



来源:https://stackoverflow.com/questions/54870771/path-in-post-receive-hook-doesnt-contain-path-as-set-in-bashrc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!