2009-04-17 8 views
46

Tôi đang sử dụng Capistrano chạy tác vụ từ xa. Nhiệm vụ của tôi trông như thế này:Capistrano & Bash: bỏ qua trạng thái thoát lệnh

task :my_task do 
    run "my_command" 
end 

Vấn đề của tôi là nếu my_command có một trạng thái thoát = 0, sau đó Capistrano coi nó thất bại và lối thoát hiểm!. Làm thế nào tôi có thể làm cho capistrano tiếp tục đi khi thoát khi trạng thái thoát không phải là 0? Tôi đã thay đổi my_command thành my_command;echo và nó hoạt động nhưng nó giống như một hack.

Trả lời

75

Cách đơn giản nhất là chỉ nối thêm đúng vào cuối lệnh của bạn.

task :my_task do 
    run "my_command" 
    end 

trở thành

task :my_task do 
    run "my_command; true" 
    end 
+12

Không chắc chắn những gì capistano là nhưng tôi tìm thấy con đường của tôi ở đây do cùng một vấn đề với bash. Và sau đó bạn có thể sử dụng "my_command || true" thay vì "my_command; true" – Zitrax

5

Bạn sẽ cần vá mã Capistrano nếu bạn muốn nó làm những việc khác nhau với mã thoát; nó được mã hóa cứng để tăng ngoại lệ nếu trạng thái thoát không phải là số không.

Đây là phần có liên quan của lib/capistrano/command.rb. Dòng bắt đầu bằng if (failed ... là dòng quan trọng nhất. Về cơ bản nó nói rằng nếu có bất kỳ giá trị trả lại không phải là không, hãy nêu ra một lỗi.

# 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 
+0

Tôi đoán đây chỉ dành cho Capistrano 2, cho Capistrano 3, bạn có thể sử dụng [Câu trả lời của Ciryon] (http: // stackoverflow.com/a/23424213/345959) – Smar

2

Tôi chỉ chuyển hướng stderr và stdout vào/dev/null, vì vậy bạn

run "my_command" 

trở thành

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

này làm việc cho các công cụ unix tiêu chuẩn khá tốt, ở đâu, tiếng nói, cp hoặc ln có thể thất bại, nhưng bạn không muốn ngừng triển khai trên một thất bại như vậy.

7

Lệnh + grep + thoát khỏi số không dựa trên nội dung tìm thấy. Trong trường hợp sử dụng nơi bạn quan tâm đến đầu ra nhưng không quan tâm nếu nó trống, bạn sẽ loại bỏ trạng thái thoát âm thầm:

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

Thông thường, tôi nghĩ giải pháp đầu tiên là tốt - tôi muốn làm cho tài liệu chính nó tho:

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

tôi tìm ra lựa chọn đơn giản nhất để làm điều này:

run "my_command || :" 

Chú ý: : là lệnh NOP để mã lối ra sẽ chỉ đơn giản là bỏ qua.

30

Đối Capistrano 3, bạn có thể (như đề xuất here) sử dụng như sau:

execute "some_command.sh", raise_on_non_zero_exit: false 
+1

làm việc cho tôi tốt nhất. – khelll

+0

tùy chọn rất đẹp! – Aleksey

0

Tôi không chắc chắn những gì phiên bản mà họ thêm mã này nhưng tôi thích xử lý vấn đề này bằng cách sử dụng 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 

Đây là nơi tính năng được thực hiện trong đá quý. https://github.com/capistrano/sshkit/blob/4cfddde6a643520986ed0f66f21d1357e0cd458b/lib/sshkit/command.rb#L94