解析代理信息的.ssh / config

时间:2012-10-08 09:45:11

标签: regex perl bash sed awk

我想解析.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

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

6 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

只是为了踢,这是一个令人讨厌的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

答案 3 :(得分:1)

您是否检查过Net::SSH::Perl::Config模块?它声称以标准ssh格式阅读配置 - 虽然有一部分关键字。

  

配置文件应采用与ssh相同的格式   命令行程序;有关此信息,请参阅ssh联机帮助页   格式。 Net :: SSH :: Perl :: Config了解其中的一个子集   可以存在于这些文件中的配置指令;这个子集   与Net :: SSH :: Perl可以支持的功能相匹配。   只会跳过未知的关键字。

答案 4 :(得分:1)

使用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

答案 5 :(得分:0)

试试这个:

#! /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";
    }   
}