如何让shell命令输出排队?

时间:2021-09-05 23:51:48

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

我正在Ruby中编写一个实用程序方法来在远程服务器上运行shell命令。

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.)

如何让所有内容垂直排列? (除了“------>”。那应该从左边开始。)

1 个解决方案

#1


3  

You can't do it the way you're going about it. Connection to host.com closed. is output by the command you called, and not returned via STDOUT, which you could capture with backticks.

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

The problem is the use of backticks. They don't capture STDERR, which is most likely what ssh is using when it outputs its status.

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

The fix is to use Open3's methods, such as capture3 which will grab the STDOUT and STDERR streams returned by the called program, and let you output them programmatically, allowing you to align them:

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

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

You should also look at Ruby's printf, sprintf or String's % method, which calls sprintf. Using % you can easily format your strings to align:

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

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

Combine that with the code to use capture3 and you should be where you want to be.

将它与代码结合使用capture3,你应该在你想要的位置。

#1


3  

You can't do it the way you're going about it. Connection to host.com closed. is output by the command you called, and not returned via STDOUT, which you could capture with backticks.

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

The problem is the use of backticks. They don't capture STDERR, which is most likely what ssh is using when it outputs its status.

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

The fix is to use Open3's methods, such as capture3 which will grab the STDOUT and STDERR streams returned by the called program, and let you output them programmatically, allowing you to align them:

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

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

You should also look at Ruby's printf, sprintf or String's % method, which calls sprintf. Using % you can easily format your strings to align:

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

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

Combine that with the code to use capture3 and you should be where you want to be.

将它与代码结合使用capture3,你应该在你想要的位置。