【问题标题】:Parsing .ssh/config for proxy information解析 .ssh/config 以获取代理信息
【发布时间】:2012-09-28 13:13:11
【问题描述】:

我想解析.ssh/config文件中包含的代理信息,并显示每个具有相关代理信息的主机和代理信息。应该过滤掉没有任何代理信息的主机。 .ssh/config 的手册页:http://man-wiki.net/index.php/5:ssh_config

这应该通过 Bash 下的 Unix shell 脚本来完成,因此首选 Perl、awk 或 sed 等标准工具。

示例输入文件:

Host ssh.foo.com
    User ssh
    HostName ssh.foo.com
    Port 443
    ProxyCommand /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth

Host ci
    HostName 127.0.0.2
    User ci

Host nightly
    HostName 192.168.1.1
    User goodnight

Host foobar.org
    User git
    HostName foobar.org
    Port 443
    ProxyCommand /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth

Host integration
    HostName 192.168.1.2
    User int

预期的输出应如下所示:

Host: ssh.foo.com - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
Host: foobar.org - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth

这里的困难是搜索必须覆盖多行。

【问题讨论】:

    标签: regex perl bash sed awk


    【解决方案1】:

    试试这个:

    #! /usr/bin/perl
    use strict;
    use warnings;
    open FD, "DATA" || die $!;
    my $line = do {local $/; <FD>};
    my @a = split /Host\b/, $line;
    foreach (@a) {
        if (defined $_ and /^\s*(\S+).*ProxyCommand\s+([^\n]+)/s) {
            print "$1 - Proxy: $2\n";
        }   
    }
    

    【讨论】:

      【解决方案2】:

      一种使用GNU sed的方式:

      sed -nre '/^Host/h;/ProxyCommand/{H;x;s/(Host)(.*)\n +[^ ]+ /\1:\2 - Proxy: /p}' file.txt
      

      结果:

      Host: ssh.foo.com - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
      Host: foobar.org - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
      

      【讨论】:

      • 非常好。我现在为自己的回答感到羞耻。
      【解决方案3】:

      只是为了好玩,这是一个讨厌的 sed 命令,似乎可以完成此操作。

      sed -n '/^[Hh]ost/{:r;h;:l;n;/^[Hh]ost/!{/[Pp]roxy/H;bl};/^[Hh]ost/{x;/[Pp]roxy/{s/\n\s*/ - /;s/[Cc]ommand/:/;s/[Hh]ost/\0:/;p};x;br}}' ~/.ssh/config
      

      无论如何,这更多是出于演示目的,因为其他解决方案更容易掌握。对此的评论意见:

      /^[Hh]ost/ {                # Begin on a Host line
          :restart                # Label to jump back to
          h                       # Copy the pattern space to the save space
          :loop                   # Label to jump to when we don't want to wipe out the save space
          n                       # Read in the next line
          /^[Hh]ost/!{            # For lines that aren't host definitions
              /[Pp]roxy/H         # If they are proxy configurations, append the line to the save space
              b loop              # Go to :loop
          }
          /^[Hh]ost/{             # If they are *not* host definitions
              x                   # Exchange the pattern and save spaces
              /[Pp]roxy/{         # If the new pattern space contains a proxy configuration
                  s/\n\s*/ - /    # Insert the required separator
                  s/[Cc]ommand/:/ # Change "ProxyCommand" to "Proxy:"
                  s/[Hh]ost/\0:/  # Change "Host" to "Host:"
                  p               # Print the pattern space
              }
              x                   # Exchange the pattern and save spaces
              b restart           # Go to :restart
          }
      }
      

      示例输出:

      Host: ssh.foo.com - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
      Host: foobar.org - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
      

      【讨论】:

        【解决方案4】:

        您检查过Net::SSH::Perl::Config 模块吗?它声称可以读取标准 ssh 格式的配置 - 尽管使用了一部分关键字。

        配置文件的格式应与 ssh 使用的格式相同 命令行程序;有关这方面的信息,请参见 ssh 手册页 格式。 Net::SSH::Perl::Config 理解 可以存在于这些文件中的配置指令;这个子集 与 Net::SSH::Perl 可以支持的功能相匹配。 将直接跳过未知关键字。

        【讨论】:

          【解决方案5】:

          尝试按照awk 命令:

          awk '
              $1 == "Host" { 
                  host = $1 ": " $2; 
                  next; 
              } 
              $1 == "ProxyCommand" { 
                  $1 = ""; 
                  sub( /^[[:space:]]*/, "" ); 
                  printf "%s - Proxy: %s\n", host, $0;
              }
          ' .ssh/config
          

          它产生:

          Host: ssh.foo.com - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
          Host: foobar.org - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
          

          【讨论】:

          • 谢谢 - 这正是我想要的!
          【解决方案6】:

          awk oneliner 可以满足您的要求:

          awk -v RS="" '/Proxy/{gsub(/\n/,"");gsub(/\s*User.*ProxyCommand/,"- Proxy:");print}'file
          

          测试(a.txt 是您的输入文件)

          kent$  awk -v RS="" '/Proxy/{gsub(/\n/,"");gsub(/\s*User.*ProxyCommand/,"- Proxy:");print}' a.txt                                                                  
          Host ssh.foo.com    - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
          Host foobar.org    - Proxy: /usr/local/bin/corkscrew proxy 8080 %h %p ~/.ssh/proxyauth
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多