web-dev-qa-db-ja.com

Capistrano&Bash:コマンドの終了ステータスを無視

Capistranoを使用してリモートタスクを実行しています。私の仕事は次のようになります:

task :my_task do
  run "my_command"
end

私の問題はmy_commandの終了ステータスが!= 0の場合、Capistranoは失敗と見なして終了します。終了ステータスが0でないときに、終了時にcapistranoを続行するにはどうすればよいですか?私は変わった my_commandmy_command;echoと動作しますが、ハックのように感じます。

48
nicholaides

最も簡単な方法は、コマンドの最後にtrueを追加することです。

  task :my_task do
    run "my_command"
  end

なる

  task :my_task do
    run "my_command; true"
  end
77
mthorley

Capistrano 3の場合、(推奨される ここ )以下を使用できます。

execute "some_command.sh", raise_on_non_zero_exit: false
37
Ciryon

+ grep +コマンドは、検出結果に基づいてゼロ以外の値で終了します。出力を気にしても、空でも構わないというユースケースでは、サイレントに終了状態を破棄します。

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

通常、私は最初の解決策で十分だと思います-それ自体を文書化します:

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

終了コードで別の処理を行う場合は、Capistranoコードにパッチを適用する必要があります。終了ステータスがゼロでない場合、例外を発生させるようにハードコードされています。

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
5
Sarah Mei

私はこれを行う最も簡単なオプションを見つけます:

run "my_command || :"

通知::はNOPコマンドなので、終了コードは単に無視されます。

4
Besi

STDERRとSTDOUTを/ dev/nullにリダイレクトするだけなので、

run "my_command"

なる

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

これは、たとえば、cpまたはlnが失敗する可能性がある標準のUNIXツールでうまく機能しますが、そのような失敗で展開を停止する必要はありません。

2
Terry

彼らがこのコードを追加したバージョンはわかりませんが、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

ここにその機能がgemに実装されています。 https://github.com/capistrano/sshkit/blob/4cfddde6a643520986ed0f66f21d1357e0cd458b/lib/sshkit/command.rb#L94

0
brand-it