好的,所以我是Ruby的新手,并且对bash/ksh/sh有很深的了解。

我想做的是使用一个简单的for循环在多个服务器上运行命令。在bash中,我会这样做:

for SERVER in `cat etc/SERVER_LIST`
do
    ssh -q ${SERVER} "ls -l /etc"
done

etc/SERVER_LIST只是一个看起来像这样的文件:
server1
server2
server3
etc

我似乎无法在Ruby中做到这一点。这是我到目前为止的内容:
 #!/usr/bin/ruby
### SSH testing
#
#

require 'net/ssh'

File.open("etc/SERVER_LIST") do |f|
        f.each_line do |line|
                Net::SSH.start(line, 'andex') do |ssh|
                        result = ssh.exec!("ls -l")
                        puts result
                end
        end
end

我现在收到这些错误:
andex@master:~/sysauto> ./ssh2.rb
/usr/lib64/ruby/gems/1.8/gems/net-ssh-2.0.23/lib/net/ssh/transport/session.rb:65:in `initialize': newline at the end of hostname (SocketError)
        from /usr/lib64/ruby/gems/1.8/gems/net-ssh-2.0.23/lib/net/ssh/transport/session.rb:65:in `open'
        from /usr/lib64/ruby/gems/1.8/gems/net-ssh-2.0.23/lib/net/ssh/transport/session.rb:65:in `initialize'
        from /usr/lib64/ruby/1.8/timeout.rb:53:in `timeout'
        from /usr/lib64/ruby/1.8/timeout.rb:93:in `timeout'
        from /usr/lib64/ruby/gems/1.8/gems/net-ssh-2.0.23/lib/net/ssh/transport/session.rb:65:in `initialize'
        from /usr/lib64/ruby/gems/1.8/gems/net-ssh-2.0.23/lib/net/ssh.rb:179:in `new'
        from /usr/lib64/ruby/gems/1.8/gems/net-ssh-2.0.23/lib/net/ssh.rb:179:in `start'
        from ./ssh2.rb:10
        from ./ssh2.rb:9:in `each_line'
        from ./ssh2.rb:9
        from ./ssh2.rb:8:in `open'
        from ./ssh2.rb:8

该文件的来源正确,我使用的是相对路径,因为我坐在etc/下的目录中(而不是/etc,我是在脚本目录中运行该文件的目录,我将该文件保存在一个名为etc的子目录中)。

最佳答案

File.open("/etc/SERVER_LIST", "r") do |file_handle|
  file_handle.each_line do |server|
    # do stuff to server here
  end
end

第一行打开文件进行读取,并立即进入一个块。 (该块是doend之间的代码。您也可以仅用{}包围这些块。经验法则是多行块为do..end,单行块为{...}。)块在Ruby中非常常见。比whilefor循环更惯用。)对open的调用会自动接收文件句柄,并在管道中为其命名。

可以说,一旦掌握了这一点,就可以在其上调用each_line,并对其进行迭代,就好像它是一个数组一样。同样,每次迭代都会自动为您传递一条线,您称其为管道中的所需内容。

关于此方法的好处是,它可以避免您在完成文件后关闭文件的麻烦。当您离开外部块时,以这种方式打开的文件将自动关闭。

另一件事:该文件几乎可以肯定命名为/etc/SERVER_LIST。您需要使用初始/来指示文件系统的根目录(除非您有意使用相对路径表示文件路径,我对此表示怀疑)。仅此一项就可能使您无法打开文件。

更新为新错误:Net::SSH正在换行符之上。您在哪里:
 Net::SSH.start(line, 'andex') do |ssh|

做到这一点:
 Net::SSH.start(line.chomp, 'andex') do |ssh|
chomp方法从字符串中删除任何最后的换行符。

关于ruby - 从Ruby中的文件内容循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3198402/

10-12 13:09
查看更多