0

I'm writing a utility method in Ruby to run shell commands on a remote server.

Here's what I have so far...

def exec_remotely(command)
  remote_command = "ssh -t #{@config['remote_username']}@#{@config['target_server']} '#{command}'"
  puts "------> Executing:"
  puts "        #{remote_command}"
  output = `#{remote_command}`
  output.lines.each do |line|
    puts "        #{line}"
  end
end

The effect I want on the console is this:

------> Executing:
        ssh -t user@host.com 'ls -alh'
        Connection to host.com closed.
        total 8.7M
        drwx------ 10 username username 4.0K Sep  5 18:11 .
        drwxr-xr-x  3 root  root  4.0K Aug 26 21:18 ..
        -rw-------  1 username username 1.6K Sep  5 17:47 .bash_history
        -rw-r--r--  1 username username   18 Dec  2  2011 .bash_logout
        -rw-r--r--  1 username username   48 Aug 27 02:52 .bash_profile
        -rw-r--r--  1 username username  353 Aug 27 03:05 .bashrc

        # etc...

But what I'm getting instead is this...

------> Executing:
        ssh -t user@host.com 'ls -alh'
Connection to host.com closed.
        total 8.7M
        drwx------ 10 username username 4.0K Sep  5 18:11 .
        drwxr-xr-x  3 root  root  4.0K Aug 26 21:18 ..
        -rw-------  1 username username 1.6K Sep  5 17:47 .bash_history
        -rw-r--r--  1 username username   18 Dec  2  2011 .bash_logout
        -rw-r--r--  1 username username   48 Aug 27 02:52 .bash_profile
        -rw-r--r--  1 username username  353 Aug 27 03:05 .bashrc

        # etc...

How can I get everything to line up vertically? (Except for the "------>". That's supposed to start at the left edge.)

4

1 回答 1

3

你不能按照你的方式去做。Connection to host.com closed.由您调用的命令输出,而不是通过 STDOUT 返回,您可以使用反引号捕获。

问题是反引号的使用。他们不捕获 STDERR,这很可能是 ssh 在输出其状态时使用的内容。

解决方法是使用 Open3 的方法,例如capture3它将获取被调用程序返回的 STDOUT 和 STDERR 流,并让您以编程方式输出它们,从而允许您对齐它们:

stdout_str, stderr_str, status = Open3.capture3([env,] cmd... [, opts]) 

您还应该查看 Ruby或 String 的方法printf,它调用. 使用您可以轻松地格式化字符串以对齐:sprintf%sprintf%

format = '%7s %s'
puts format % ["------>", "Executing:"]
puts format % ["", remote_command]
output = `#{remote_command}`
output.lines.each do |line|
  puts format % ["", line]
end

将其与要使用的代码结合起来capture3,您就应该在您想去的地方。

于 2013-09-05T20:46:43.260 回答