Ruby-on-rails Capistrano 3 在目录中执行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19452983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:53:48  来源:igfitidea点击:

Capistrano 3 execute within a directory

ruby-on-railsrubycapistranocomposer-phpcapistrano3

提问by Rahul Sekhar

I'm trying to write a task for Capistrano 3 that involves executing 'composer install' within the directory of the current release. It looks something like this:

我正在尝试为 Capistrano 3 编写一个任务,该任务涉及在当前版本的目录中执行“composer install”。它看起来像这样:

namespace :composer do
  desc 'Install dependencies with Composer'
  task :install do
    on roles(:web) do
      within release_path do
        execute "#{fetch(:composer_command)} install"
      end
    end
  end
end

composer_commandis set in the staging and production files - in my particular case to php /home/user/composer.phar

composer_command设置在暂存和生产文件中 - 在我的特殊情况下 php /home/user/composer.phar

For some reason this command does not actually run in the current release directory, but instead runs in the parent directory (containing current, shared, releases, etc)

出于某种原因,这个命令实际上并没有在当前发布目录中运行,而是在父目录中运行(包含当前、共享、发布等)

I delved into this a bit further and found that when I ran a single word command, like:

我深入研究了一下,发现当我运行一个单词命令时,例如:

within release_path do
    execute "pwd"
end

It works just fine, and runs the command in the current release directory. But...when I run a command with spaces, like:

它工作得很好,并在当前发布目录中运行命令。但是...当我运行带有空格的命令时,例如:

within release_path do
    execute "pwd && ls"
end

It runs in the parent directory, and not the directory set by the withinblock.

它运行在父目录中,而不是within块设置的目录中。

Can someone shed some light on this? Thanks!

有人可以对此有所了解吗?谢谢!

回答by Electrawn

Smells like a Cap 3 bug.

闻起来像 Cap 3 臭虫。

I suggest just guaranteeing you are where you want to be from the shell perspective:

我建议从 shell 的角度保证你在你想要的地方:

execute "cd '#{release_path}'; #{fetch(:composer_command)} install"

回答by bricker

You can retain all the niceties of within(), with(), default_env, etc, while still keeping the natural string syntax:

你可以保留的所有细微之处within()with()default_env,等,同时仍保持自然字符串语法:

within release_path do
  execute *%w[ pip install -r requirements.txt ]
end

回答by Jasper N. Brouwer

A couple of tips:

一些提示:

1) Capistrano uses SSHKitfor a lot of things, among which command execution. In order to simplify using Composer you could configure the command map (in deploy.rbor production.rb, etc), here are 2 examples:

1) Capistrano 使用SSHKit做很多事情,其中​​包括命令执行。为了简化 Composer 的使用,您可以配置命令映射(在deploy.rbproduction.rb等中),这里有两个示例:

SSHKit.config.command_map[:composer] = "#{shared_path.join('composer.phar')}"
SSHKit.config.command_map[:composer] = '/usr/bin/env composer.phar'

Next you can execute it like so:

接下来你可以像这样执行它:

execute :composer, :install

2) From a security perspective it's wise to disable the php setting allow_url_fopen, but unfortunately Composer needs it enabled to function. You can use this trick to leave it disabled globally:

2) 从安全角度来看,禁用 php 设置是明智的allow_url_fopen,但不幸的是 Composer 需要启用它才能运行。您可以使用此技巧使其全局禁用:

SSHKit.config.command_map[:composer] = "/usr/bin/env php -d allow_url_fopen=On #{shared_path.join('composer.phar')}"

Check out iniscanfor more security advise on php settings.

查看iniscan以获取有关 php 设置的更多安全建议。

3) Composer has an option -d, --working-dir, which you can point to the directory containing the composer.jsonfile in order to run Composer from any other directory. This should solve your problem:

3) Composer 有一个选项-d, --working-dir,您可以指向包含该composer.json文件的目录,以便从任何其他目录运行 Composer。这应该可以解决您的问题:

execute :composer, '-d', release_path, :install

4) You may want to take a look at the capistrano-composerproject :)

4) 你可能想看看capistrano-composer项目:)

回答by JellicleCat

Actually, your use of the withinfunction is almostcorrect. You have supplied it an entire string as a command, but the doc points out that this results in unreliable behaviour (which I have experienced myself).

实际上,您对该within功能的使用几乎是正确的。您已将整个字符串作为命令提供给它,但文档指出这会导致不可靠的行为(我自己也经历过)。

Let the first argument to executebe a symbol instead of a string (which contains whitespace):

让第一个参数execute是一个符号而不是一个字符串(包含空格):

within release_path do
    execute fetch(:composer_command).to_sym, "install"
    execute :pwd
    execute :ls
end

回答by cdog

just for reference here is the Capistrano Docexplaining why within {}does not work with arguments with whitespace. I hope this helps.

仅供参考的是Capistrano Doc解释了为什么within {}不能使用带有空格的参数。我希望这有帮助。