在Capistrano中更新文件权限导致“参数列表太长”'

时间:2014-06-07 15:55:31

标签: bash capistrano

我们的部署脚本的最后一个阶段要求所有PHP文件都是600模式,以满足我们的suphp要求。在部署脚本中,我们有:

run "find /srv/www/xyz/ -type f -name \"*.php\" -print0 | xargs -0 sudo chmod 600"

但是,当我们部署时,我们收到以下错误:

  * executing "find /srv/www/xyz/ -type f -name \"*.php\" -print0 | xargs -0 sudo chmod 600"
    servers: ["www.xyz.net"]
    [www.xyz.net] executing command
*** [err :: www.xyz.net] sudo
*** [err :: www.xyz.net] :
*** [err :: www.xyz.net] unable to execute /bin/chmod: Argument list too long
*** [err :: www.xyz.net]
    command finished in 333ms
failed: "sh -c 'find /srv/www/xyz/ -type f -name \"*.php\" -print0 | xargs -0 sudo chmod 600'" on www.xyz.net

如果我们在服务器上手动运行该命令,它可以正常工作。有没有人可能理解为什么我们在使用Capistrano运行时会出现此错误?

1 个答案:

答案 0 :(得分:1)

你的命令是:

run "find /srv/www/xyz/ -type f -name \"*.php\" -print0 | xargs -0 sudo chmod 600"

不太确定sudo在卡皮斯特拉诺这样的管道传输时是否有效。

卡皮斯特拉诺很棒,但它所做的一切都不是魔法。 Capistrano本质上是一个Ruby脚本,它打开了一个SSH连接&然后运行一堆shell脚本命令。因此,通过Capistrano启动的新SSH连接将被视为服务器的新登录。这意味着sudo需要密码& Capistrano只是不这样工作...除非你在服务器上设置无密码sudothe Capistrano documentation中的更多详细信息:

  

本主题的第二部分是我们的部署用户需要   授权在服务器上的部署目录中工作。那   意味着我们需要能够工作,理想情况下没有sudo(没有   默认的Capistrano食谱希望sudo可用,或为您的   自定义配方,您需要配置无密码的sudo。

此外,当你使用-name \"*.php\"时,你似乎不需要转义双引号,所以也许只是改变它就像这样可以工作:-name '*.php'。使用单引号,因为您似乎已经转义双引号以适合run命令的上下文。我打赌那些放在\"上下文中的双重引号(run)是这个问题的根源:

run "find /srv/www/xyz/ -type f -name '*.php' -print0 | xargs -0 sudo chmod 600"

但过去所有这些,我建议尝试这样做:

run "find /srv/www/xyz -type f -iwholename '*.php*' -print0 | xargs -0 chmod 600"

注意没有sudo,因为如果用户能够创建没有sudo开头的文件,那么没有理由相同的用户需要使用sudo之后更改文件权限。我也使用iwholename而不是name

如果您的远程主机可以处理--no-run-if-empty选项,我还建议您使用xargs

run "find /srv/www/xyz -type f -iwholename '*.php*' -print0 | xargs --no-run-if-empty -0 chmod 600"

--no-run-if-empty是一个GNU扩展,因此它不适用于Mac OS X中使用的非GNU / BSD版本的xargs,但在现代Linux安装中运行良好(Ubuntu / Debian,的CentOS / RedHat的)。