1

我有用于 ssh 登录的脚本,而不是期望:

function do_auth_connect(){
    if [ -n "$SSH_ASKPASS_TMPFILE" ]; then
        cat "$SSH_ASKPASS_TMPFILE"
        exit 0
    elif [ $# -lt 1 ]; then
        echo "Usage: echo password | $0 <ssh command line options>" >&2
        exit 1
    fi

    sighandler() {
        rm "$TMP_PWD"
    }

    TMP_PWD=$(mktemp)
    chmod 600 "$TMP_PWD"
    trap 'sighandler' SIGHUP SIGINT SIGQUIT SIGABRT SIGKILL SIGALRM SIGTERM

    export SSH_ASKPASS=$0
    export SSH_ASKPASS_TMPFILE=$TMP_PWD

    [ "$DISPLAY" ] || export DISPLAY=dummydisplay:0
    read password
    echo $password >> "$TMP_PWD"

    # use setsid to detach from tty
    #exec setsid "$@"
    setsid "$@"

    rm "$TMP_PWD"
}

如果我使用如下命令:

echo "my_password" | do_auth_connect ssh use@domain "uname -a"

一切正常。但如果我使用:

read password
echo "$password" | do_auth_connect ssh use@domain "uname -a"

脚本冻结。

“set -x”表示脚本进入循环,并等待另一个“读取”参数。

我该如何解决这个问题?谢谢

---UPD---(对于@Barmar)

正常时设置 -x 输出(以 scp 为例):

+ echo 'user_password'
+ do_auth_connect scp -P 444 user@domain:/home/user/dbg.log /home/user/dbg.log
+ '[' -n '' ']'
+ '[' 5 -lt 1 ']'
++ mktemp
+ TMP_PWD=/tmp/tmp.X8TKTIchq6
+ chmod 600 /tmp/tmp.X8TKTIchq6
+ trap sighandler SIGHUP SIGINT SIGQUIT SIGABRT SIGKILL SIGALRM SIGTERM
+ export SSH_ASKPASS=./1.sh
+ SSH_ASKPASS=./1.sh
+ export SSH_ASKPASS_TMPFILE=/tmp/tmp.X8TKTIchq6
+ SSH_ASKPASS_TMPFILE=/tmp/tmp.X8TKTIchq6
+ '[' :0.0 ']'
+ read password
+ echo 'user_password'
+ setsid scp -P 444 user@domain:/home/user/dbg.log /home/user/dbg.log
+ echo 'user_password'
+ do_auth_connect scp -P 444 user@domain:/home/user/dbg.log /home/user/dbg.log
+ '[' -n /tmp/tmp.X8TKTIchq6 ']'
+ cat /tmp/tmp.X8TKTIchq6
+ exit 0
+ rm /tmp/tmp.X8TKTIchq6
+ exit

失败时:

+ read pass
> user_password
+ echo 'user_password'
+ do_auth_connect scp -P 444 user@domain:/home/user/dbg.log /home/user/dbg.log
+ '[' -n '' ']'
+ '[' 5 -lt 1 ']'
++ mktemp
+ TMP_PWD=/tmp/tmp.7usdmtHgqt
+ chmod 600 /tmp/tmp.7usdmtHgqt
+ trap sighandler SIGHUP SIGINT SIGQUIT SIGABRT SIGKILL SIGALRM SIGTERM
+ export SSH_ASKPASS=./1.sh
+ SSH_ASKPASS=./1.sh
+ export SSH_ASKPASS_TMPFILE=/tmp/tmp.7usdmtHgqt
+ SSH_ASKPASS_TMPFILE=/tmp/tmp.7usdmtHgqt
+ '[' :0.0 ']'
+ read password
+ echo 'user_password'
+ setsid scp -P 444 user@domain:/home/user/dbg.log /home/user/dbg.log
+ read -p '> ' pass

这就是全部,^C 不起作用:)

---UPD2---

我发现任何“读取”都会破坏脚本例如:

read null
echo "user_password" | do_auth_connect scp -P 444 user@domain:/home/user/dbg.log ~/dbg.log

有一些冻结问题

4

3 回答 3

0

来到这里寻找类似的情况:ssh 调用包含调用的远程脚本setsid,并且观察 ssh 永远不会终止。

ssh remotehost start-daemon.sh

在哪里启动-daemon.sh

#!/bin/bash
...
setsid $daemon $args &
exit 0

ssh 将挂起,必须给予 ^C 才能停止。修复(如https://serverfault.com/questions/364689评论中所暗示的)是重定向 setid 的标准输出:

setsid $daemon $args > /dev/null &

然后 ssh 按预期停止。在我的测试中,stderr 不需要相同的处理。

于 2015-03-20T05:24:29.633 回答
0
SSH_ASKPASS           If ssh needs a passphrase, it will read the passphrase from
                       the current terminal if it was run from a terminal.  If ssh
                       does not have a terminal associated with it but DISPLAY and
                       SSH_ASKPASS are set, it will execute the program specified by
                       SSH_ASKPASS and open an X11 window to read the passphrase.
                       This is particularly useful when calling ssh from a .xsession
                       or related script.  (Note that on some machines it may be
                       necessary to redirect the input from /dev/null to make this
                       work.)

相关:

(请注意,在某些机器上,可能需要从 /dev/null 重定向输入以使其工作。)

这是非常模糊的,尝试按照在发出 ssh 命令之前的建议将输入重定向到 /dev/null

于 2012-11-23T15:51:34.287 回答
-1

由于将评论标记为答案的功能请求仍然被拒绝,因此我在此处复制上述解决方案。

当您执行 SSH_ASKPASS=$0 时,这意味着“为了获取密码,请再次运行此脚本”。如果脚本在开始时确实读取了 pass,它将再次执行。您需要以密码是否已保存在临时文件中为条件。– 巴尔马尔

于 2013-11-19T13:45:58.173 回答