Inspired by @Arek Burdach's answer and others' wrapper, I've wrote a wrapper that should be more robust which facilitated ssh own command parsing.
UPDATE 2021-04-26: Fixed wrapper when a host only matches the prefix (e.g. Host is none)
Here's how it work:
- We first dry-run the ssh with -v and a non-existent ProxyCommand, so it wouldn't make any network connection and exit at once.
- Then we extract the line like
debug1: /home/misty/.ssh/config line 42: Applying options for XXXXXX
. But the ssh output the errlog with \r, so we replaced them before passing into grep.
According to my test, ssh will only recognize the first -o ProxyCommand=XXX in commandline, even if there's second ProxyCommand option in the cmdline, or there's ProxyCommand in ~/.ssh/config, so our method will be very very stable ;)
For ssh
#!/usr/bin/env bashORISSH=/usr/bin/sshssh_dryrun=$($ORISSH -v -o "ProxyCommand=FAKE_PROXY_STUB %h %p" "$@" 2>&1 | sed -e 's/\r/\n/g')host=$( grep -oP 'Applying options for \K(.*?)$'<<< $ssh_dryrun | head -n 1 )if [[ $host == "*" ]]; then password=''else password=`awk "/#Password/ && inhost { print \\\$2 } /^Host/ { inhost=0 } /Host $host$/ { inhost=1 }" ~/.ssh/config`fiif [[ -z "$password" ]]; then $ORISSH "$@"else sshpass -p $password $ORISSH "$@"fi
For scp:
#!/usr/bin/env bashORISCP=/usr/bin/scpscp_dryrun=$($ORISCP -v -o "ProxyCommand=proxyhost %h %p" "$@" 2>&1 | sed -e 's/\r/\n/g')host=$( grep -oP 'Applying options for \K(.*?)$'<<< $scp_dryrun | head -n 1 )if [[ $host == "*" ]]; then password=""else password=`awk "/#Password/ && inhost { print \\\$2 } /^Host/ { inhost=0 } /Host $host$/ { inhost=1 }" ~/.ssh/config`fiif [[ -z "$password" ]]; then $ORISCP "$@"else sshpass -p $password $ORISCP "$@"fi