post-receive hook 中的 PATH 不包含 bashrc 中设置的 PATH

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

如何设置 Ubuntu 上的 PATH,使我设置的变量也在 post-接收脚本中设置?目前我正在通过 ~/.bashrc 文件这样做:

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

但如果我从钩子上打印它,则在 PATH 中看不到任何变化。因此,如果我尝试在挂钩中执行有问题的命令,我会得到

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

所以我现在看到的唯一解决方案是在 post-receive 挂钩本身中再次定义它,如下所示:

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

有没有更好的方法?

谢谢!

首先,进行一些文件设置:

$ mkdir /tmp/dir1 /tmp/dir2
$ date > /tmp/dir1/foo
$ date > /tmp/dir2/bar

现在,考虑一个简单的脚本:

$ 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

该脚本的语法格式正确,但让我们看看会发生什么:

$ ./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

路径不足以让脚本解释器找到脚本想要的可执行文件 运行。三个单独的可执行文件加载失败:lscatdiff。所以让我们帮助它一点。由于 ls 通常驻留在 /bin 目录中,让我们将 PATH 编辑为:

export PATH="/bin"

再试一次:

$ ./foo.sh
/tmp/dir1:
foo
/tmp/dir2:
bar
./foo.sh: diff: not found

嗯,ls 运行现在好了。这就是进步。由于 cat 也住在 /bin 中,因此将 /bin 添加到路径中可以一举两得。但是 diff 仍然没有被发现,因为 diff 住在 /usr/bin。所以让我们把它添加到路径中:

export PATH="/bin:/usr/bin"

再试一次:

$ ./foo.sh 
/tmp/dir1:
foo
/tmp/dir2:
bar
1c1
< foo
---
> bar

瞧!没有更多的错误,因为 PATH 变量包含允许脚本解释器定位脚本调用的可执行文件所需的一切。

另一种方法是告诉 PATH 退出并指定您自己的可执行文件路径。当您出于某种原因可能不信任或不想要 "standard" 可执行文件时,此方法有时会很方便。当以这种方式构建脚本时,我更喜欢为我想要引用的可执行文件使用变量,这样如果 ^H^H 当位置发生变化时,我可以只更改变量而不必搜索整个脚本该可执行文件的调用。

$ 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

并且输出:

$ ./bar.sh
/tmp/dir1:
foo
/tmp/dir2:
bar
1c1
< foo
---
> bar

您可以混合搭配这些方法,方法是指定包含大部分内容的 PATH,并为其他内容指定绝对路径,但您的问题出现是因为您没有这样做。

您需要在钩子脚本中指定完整且足够的 PATH,and/or 指定位于任何 PATH 变量之外的剩余可执行文件(如果有)的绝对路径您的挂钩脚本当前正在使用。