Search code examples
rubycapistranotail

Executing 'tail -f' with Capistrano 3 pipes nothing into output


I have a Capistrano task that looks like this:

desc "tail log file"
task :tail do
  on roles(:app) do
    execute "tail -f #{shared_path}/log/#{fetch(:log_file)}.log"
  end
end

When I run the task, it proceeds with the blocking tail -f request, but it shows up nothing. I am one hundred percent sure that it simply does not pipe the data somehow (I've verified it - the log file gets updated on the remote) thus it shows nothing. Did I miss something? The app role is included in the stage config.


Solution

  • I have found a workaround/solution to my problem. I don't remember where I did found the solution, but executing the command rawly by instantiating an ssh connection with a pseudo-tty forced allocation (that's the -t) got it working. That will get the blocking requests like tail -f working. As the man pages say on the -t option:

    This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful...

    def execute_interactively(command)
      user = fetch(:user)
      port = fetch(:port)
      cmd = "ssh -l #{user} #{host} -p #{port} -t 'cd #{deploy_to}/current && #{command}'"
      exec cmd
    end