我尝试通过GIT设置自动部署,但人们建议您这样做的主要方式是使用后接收脚本。如果我进入钩子并做
$ sh post-receive
,它工作正常,但如果我
$ ./post-receive
,虽然它有
,但它会抱怨权限$ chmod 777 post-receive
(您可以使用$ ls -l查看)。
这是我从支持中获得的信息: "原因是出于安全原因,SSH环境作为非可执行环境安装。这意味着您无法仅通过路径运行脚本。
例如,运行:/www/repos/webprosjekt18.git/hooks/post-receive将无效,它将给出权限错误。
运行: bash /www/repos/webprosjekt18.git/hooks/post-receive将正常工作(取决于该脚本的功能,但它至少会运行该文件)。
我们认为git默认通过调用:/www/repos/webprosjekt18.git/hooks/post-receive运行挂钩,这将失败。 "
远程脚本:
mkdir repos
cd repos
git init --bare
cat > hooks/post-receive <<END
#!/bin/sh
echo "executing post-receive hook"
END
chmod 777 hooks/post-receive
cd hooks
sh post-receive
答案 0 :(得分:1)
作为sneep noted in a comment,一旦决定运行一些钩子,Git基本上只会执行fork
后跟execve
的钩子路径。 (有关“决定运行某些挂钩”的更多信息,请参阅下文。)这意味着由内核决定是否允许exec操作。
The specific source code involved is here.请注意ENOEXEC
的测试,但不是EACCES
的测试。
如果查看the Linux mount
documentation,您将看到noexec
选项禁止对该已安装文件系统上的任何文件执行(执行操作)。 (如果托管系统是基于BSD的,则BSD的mount
有类似的选项。)此案例返回的错误是EACCES
,而不是ENOEXEC
。这意味着你的托管系统的分析,你完全不能这样做,是正确的。
有趣的是,如果Git会运行一个没有设置x
位的钩子,那么在某些情况下上面调出的代码部分可能会得到ENOEXEC
(不是这些 - 你想弄乱使用“魔术数字”来触发这个)并且在钩子上运行shell的第二个代码路径实际上可以工作。但是,the find_hook
code明确要求access(path, X_OK)
成功。这需要both the x
bits set and the file system mounted without noexec
。
您可以尝试构建更改这些测试的Git变体版本并让您的托管公司将其安装为Git版本,但如果他们愿意这样做,他们可能愿意将您的存储库放在文件中允许执行的系统。
答案 1 :(得分:1)
这不是一个真正的答案,因为它很大程度上建立在@ torek建议它可能使用NOEXEC
挂载选项的基础之上。那么这个解决方法怎么样:你可以添加一个钩子,它是/usr/bin/script
的符号链接(其他文件系统的符号链接甚至可以用NOEXEC
执行)。 script
将执行bash
,而bash
会认为它在终端中。 (如果您只是符号链接到/bin/bash
目录中的hooks
,bash
会放弃看到它不能open
/dev/tty
,但script
需要为我们照顾这个。)如果我们在~/.bashrc
中放入一些代码来确定它是否被称为git hook,我们就会执行真实的脚本。所以我们可以把它放在/.bashrc
:
pppid=$(ps -o ppid= $PPID) # determine grandparent PID
ppproc=$(ps -o comm= $pppid) # determine grandparent process name
if [ "$ppproc" == "git" ]; then # is it 'git'?
echo running from git @ `date` # call script here
exit
else
echo not running from git # you might want to remove this
fi
示例:
$ touch test15
$ git add test15
$ git commit -m "Test15"
Script started, file is typescript
running from git @ Fri Mar 23 13:19:54 JST 2018
Script done, file is typescript
[master 608083b] Test15
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test15
(这会在您的Git目录中创建一个名为typescript
的文件。)