V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kuoruan
V2EX  ›  Bash

寻一段 shell 来实现自动填写 ssh 登录密码

  •  
  •   kuoruan · 2018-09-11 20:35:13 +08:00 · 7953 次点击
    这是一个创建于 2025 天前的主题,其中的信息可能已经有所发展或是发生改变。

    非私钥公钥认证方式,仅通过写一段 shell 脚本,自动获取并调用 sshpass 输入密码,实现免输密码登录

    网上找到的解决方案:

    https://askubuntu.com/a/829837 https://github.com/Shmadul/easyssh

    ssh config 文件类似于,通过注释的方式填入密码

    Host host
        User root 
        #Password passwd
        HostName localhost
        Port 2222
    

    原脚本:

    #!/bin/bash
    
    host=$1
    password=`awk "/#Password/ && inhost { print \\\$2 } /Host/ { inhost=0 } /Host $host/ { inhost=1 }" ~/.ssh/config`
    
    if [[ -z "$password" ]]; then
      /usr/bin/ssh $*
    else
      sshpass -p $password /usr/bin/ssh $*
    fi
    

    但是测试之后无法正常获取到 host 对应的 Password,应该是 awk 语句有问题

    希望各位能帮忙看看这 awk 应该怎么写,谢谢

    第 1 条附言  ·  2018-09-12 12:06:24 +08:00

    用纯 awk 实现了:

    #!/bin/sh
    
    host=$1
    
    if [ -z "$host" ]; then
            echo "Usage: $(basename $0) [host] [...params]"
            exit 128
    fi
    
    password="$(awk "/^[[:space:]]*[Hh]ost[[:space:]]+$host/ {
            while ( getline a ) {
                    if ( a ~ /^[[:space:]]*[Hh]ost[[:space:]]+/ ) {
                            break;
                    } else if ( a ~ /^[[:space:]]*#[[:space:]]*[Pp]assword[[:space:]]+/ ) {
                            gsub(/^[[:space:]]*#[[:space:]]*[Pp]assword[[:space:]]+|[[:space:]]*$/, \"\", a);
                            print a;
                            break;
                    }
            }
    }" ~/.ssh/config)"
    
    ssh_bin="$(which ssh)"
    
    if [ -z "$password" ]; then
            "$ssh_bin" $@
    else
            "$(which sshpass)" -p "$password" "$ssh_bin" $@
    fi
    

    先安装 sshpass 然后将脚本保存为任意文件,放到 PATH 下,例如:/usr/local/bin/sshp

    在 ssh config 里边加上 #Password 设置密码

    Host test-host
        Hostname ...
        User root
        # Password 123456
    

    然后 sshp test-host 就自动登录了。

    9 条回复    2018-09-12 08:21:52 +08:00
    zbinlin
        1
    zbinlin  
       2018-09-11 21:12:14 +08:00
    #Password passwd 要紧接着 Host host
    choury
        2
    choury  
       2018-09-11 21:47:36 +08:00 via Android
    这种需求我们一般都是用 expect 的
    kuoruan
        3
    kuoruan  
    OP
       2018-09-11 22:26:10 +08:00
    @zbinlin 答案的说明里边并没有说必须要密码挨着 host 写,但是挨着写的话确实就简单多了
    kuoruan
        4
    kuoruan  
    OP
       2018-09-11 23:06:59 +08:00
    自己用简单的方法,差不多实现了,就是不完美

    ```
    #!/bin/sh

    host=$1

    if [ -z "$host" ]; then
    echo "Usage: $(basename $0) [host] [...params]"
    exit 128
    fi

    password="$(awk "/^\\s*Host\\s*$host\\s*#Password/ { print \$4 }" ~/.ssh/config | head -n1)"

    ssh_path="$(which ssh)"
    sshpass_path="$(which sshpass)"

    if [ -z "$password" ]; then
    "$ssh_path" $@
    else
    "$sshpass_path" -p "$password" "$ssh_path" $@
    fi
    ```

    然后 config 这么写

    ```
    Host hostname #Password passwd
    User root
    ...
    ```
    Tink
        5
    Tink  
       2018-09-11 23:32:10 +08:00 via iPhone
    expect
    ant2017
        6
    ant2017  
       2018-09-12 00:10:39 +08:00 via Android
    配置文件没配好吧,比如 a.sh host1 参数 host1 在配置文件里配对了吗
    thedrwu
        7
    thedrwu  
       2018-09-12 01:30:26 +08:00
    ```
    pw=`grep '^\s*Host \|^\s*#\s*Password ' ~/.ssh/config | grep -1 "$hostname" | sed -n 's/^\s*#\s*Password\s*//p'`
    ````
    thedrwu
        8
    thedrwu  
       2018-09-12 01:39:20 +08:00
    @thedrwu

    修改一下:

    grep '^\s*Host\s\+\|^\s*#\s*Password\s\+' ~/.ssh/config | fgrep -1 "$host" | tail -1 | sed -n 's/^\s*#\s*Password\s\+//p'

    虽然我也喜欢用 awk,然而有时候别的工具方便
    zhangjn
        9
    zhangjn  
       2018-09-12 08:21:52 +08:00
    还直接修改 openssh 的代码
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5402 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 06:48 · PVG 14:48 · LAX 23:48 · JFK 02:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.