Ruby-on-rails Capistrano 和 Bash:忽略命令退出状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/758774/
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 21:08:54  来源:igfitidea点击:

Capistrano & Bash: ignore command exit status

ruby-on-railsrubybashcapistrano

提问by nicholaides

I'm using Capistrano run a remote task. My task looks like this:

我正在使用 Capistrano 运行远程任务。我的任务是这样的:

task :my_task do
  run "my_command"
end

My problem is that if my_commandhas an exit status != 0, then Capistrano considers it failed and exits. How can I make capistrano keep going when exit when the exit status is not 0? I've changed my_commandto my_command;echoand it works but it feels like a hack.

我的问题是,如果my_command退出状态为 != 0,则 Capistrano 认为它失败并退出。当退出状态不为 0 时,如何让 capistrano 在退出时继续运行?我已经改变了my_commandmy_command;echo和它的作品,但它的感觉就像一个黑客攻击。

回答by mthorley

The simplest way is to just append true to the end of your command.

最简单的方法是将 true 附加到命令的末尾。

  task :my_task do
    run "my_command"
  end

Becomes

成为

  task :my_task do
    run "my_command; true"
  end

回答by Ciryon

For Capistrano 3, you can (as suggested here) use the following:

对于 Capistrano 3,您可以(按照此处的建议)使用以下内容:

execute "some_command.sh", raise_on_non_zero_exit: false

回答by mrflip

The +grep+ command exits non-zero based on what it finds. In the use case where you care about the output but don't mind if it's empty, you'll discard the exit state silently:

+grep+ 命令根据它找到的内容退出非零。在您关心输出但不介意它是否为空的用例中,您将静默丢弃退出状态:

run %Q{bash -c 'grep #{escaped_grep_command_args} ; true' }

Normally, I think the first solution is just fine -- I'd make it document itself tho:

通常,我认为第一个解决方案很好——我会让它自己记录下来:

cmd = "my_command with_args escaped_correctly"
run %Q{bash -c '#{cmd} || echo "Failed: [#{cmd}] -- ignoring."'}

回答by Sarah Mei

You'll need to patch the Capistrano code if you want it to do different things with the exit codes; it's hard-coded to raise an exception if the exit status is not zero.

如果你想让 Capistrano 代码用退出代码做不同的事情,你需要修补它;如果退出状态不为零,则它是硬编码的以引发异常。

Here's the relevant portion of lib/capistrano/command.rb. The line that starts with if (failed... is the important one. Basically it says if there are any nonzero return values, raise an error.

这是 lib/capistrano/command.rb 的相关部分。以if (failed...开头的那一行很重要。基本上它说如果有任何非零返回值,则引发错误。

# Processes the command in parallel on all specified hosts. If the command
# fails (non-zero return code) on any of the hosts, this will raise a
# Capistrano::CommandError.
def process!
  loop do
    break unless process_iteration { @channels.any? { |ch| !ch[:closed] } }
  end

  logger.trace "command finished" if logger

  if (failed = @channels.select { |ch| ch[:status] != 0 }).any?
    commands = failed.inject({}) { |map, ch| (map[ch[:command]] ||= []) << ch[:server]; map }
    message = commands.map { |command, list| "#{command.inspect} on #{list.join(',')}" }.join("; ")
    error = CommandError.new("failed: #{message}")
    error.hosts = commands.values.flatten
    raise error
  end

  self
end

回答by Besi

I find the easiest option to do this:

我找到了最简单的方法来做到这一点:

run "my_command || :"

Notice: :is the NOP command so the exit code will simply be ignored.

注意::是 NOP 命令,因此退出代码将被忽略。

回答by Terry

I just redirect STDERR and STDOUT to /dev/null, so your

我只是将 STDERR 和 STDOUT 重定向到 /dev/null,所以你的

run "my_command"

becomes

变成

run "my_command > /dev/null 2> /dev/null"

this works for standard unix tools pretty well, where, say, cp or ln could fail, but you don't want to halt deployment on such a failure.

这对于标准的 unix 工具非常有效,比如 cp 或 ln 可能会失败,但您不想在这种失败时停止部署。

回答by newdark-it

I not sure what version they added this code but I like handling this problem by using raise_on_non_zero_exit

我不确定他们添加了这个代码的版本,但我喜欢通过使用来处理这个问题 raise_on_non_zero_exit

namespace :invoke do
  task :cleanup_workspace do
    on release_roles(:app), in: :parallel do
      execute 'sudo /etc/cron.daily/cleanup_workspace', raise_on_non_zero_exit: false
    end
  end
end

Here is where that feature is implemented in the gem. https://github.com/capistrano/sshkit/blob/4cfddde6a643520986ed0f66f21d1357e0cd458b/lib/sshkit/command.rb#L94

这是在 gem 中实现该功能的地方。 https://github.com/capistrano/sshkit/blob/4cfddde6a643520986ed0f66f21d1357e0cd458b/lib/sshkit/command.rb#L94