在bash 下,您可以使用script
script 将生成一个tty,您可以使用coproc 在bash 下与之交互。这可以在不需要expect 的情况下完成:
NAME
script - make typescript of terminal session
SYNOPSIS
script [options] [file]
DESCRIPTION
script makes a typescript of everything on your terminal session.
The terminal data are stored in raw form to the log file and information
about timing to another (optional) structured log file. The timing
log file is necessary to replay the session later by scriptreplay(1) and to
store additional information about the session.
演示
coproc script -f /dev/null
可以返回:
[1] 2103233
这会启动一个子shell,你可以与之交互,
while read -t 0 -u ${COPROC[0]};do
read -t .02 -ru ${COPROC[0]} line
echo "$line"
done
应该产生类似的东西:
Script started, output log file is 'typescript'.
user@hostname:~$
然后
echo >&${COPROC[1]} ssh user@target
while [ ! "$line" ] || [ "${line//*password*}" ];do
read -t .02 -ru ${COPROC[0]} line
echo "$line"
done
echo >&${COPROC[1]} TheStrongPasswordInClear
while [ ! "$line" ] || [ "${line//*\$*}" ];do
read -t .02 -ru ${COPROC[0]} line
echo "$line"
done
在那里,你可以看到很多类似的行
ssh user@target
user@target's password:
Linux target 5.00.0-0-amd64 # Distro ...
issue.net content...
Last login: Sun Dec 19 12:23:37 2021 from somewhere
user@target:~$
从那里,您可以:
getres() {
while read -t 0 -u ${COPROC[0]};do
read -t .02 -ru ${COPROC[0]} line
echo "$line"
done
}
echo >&${COPROC[1]} uptime
getres
uptime
12:38:38 up 21 days, 3:52, 122 users, load average: 3.20, 2.19, 1.59
最后
echo >&${COPROC[1]} exit
getres
exit
logout
Connection to target closed.
完整的可执行bash 脚本
这在bash 5.1.4(1)-release 下运行,在GNU/Debian Linux 11.2 上运行:
#!/bin/bash
line='' Debug=false
exp1() { # Collect input by bytes, until expected string (1st arg)
local char attended="*${1}"
line=
IFS= read -d '' -ru "${COPROC[0]}" -t 2 -n 1 line
while IFS= read -d '' -ru "${COPROC[0]}" -t .02 -n 1 char;do
line+="$char"
case "$line" in
*$1 ) $Debug && echo "GOOD ${line@A} match ${attended@A}"
return 0;;
esac
done
$Debug && echo "BAD: ${line@A}"
return 1
}
expect() { # expect <Expected String after> <Command> [switches] [args]
local expectStr="$1" maxErr=5
shift
[ "$1" ] && echo >&"${COPROC[1]}" "$@"
while ! exp1 "${expectStr}" && ((maxErr--));do sleep .2;done
}
getAns() { # getAns <ResultVar> <Command> [switches] [args]
local -n res=$1
res=''
shift
local req="$*" maxErr=5
echo >&"${COPROC[1]}" "$req"
exp1 "$req"$'\r\n'
while ! exp1 "$ " && ((maxErr--));do res+="$line" ;sleep .2 ;done
res+="${line%$'\r\n'*}"
}
read -rp target:\ target
read -rsp password:\ pass
echo "${pass//?/*}"
coproc TERM=none script -f /dev/null
IFS= read -ru "${COPROC[0]}" line &&
$Debug && echo "1 >>> $line <<<"
expect '$ '
expect 'password: ' ssh "$target"
expect '$ ' "$pass"
getAns ut uptime
# shellcheck disable=SC2154 # referenced but not assigned (ut ??)
echo "${ut@A}"
expect '$ ' exit
运行示例:
target: user@target
password: ************
ut=' 11:06:20 up 5 days, 2:19, 22 users, load average: 0.74, 1.13, 1.27'
您可以在我的网站上找到此脚本:expectScr.sh 或 expectScr.sh.txt,可以获取源代码。