如果我有一个提示输入 2 个或更多输入的 linux 命令,如何通过在命令行中定义这些输入将其传递给提示?您可以在命令后面添加一些东西来执行此操作吗?
在下面的示例中,如何运行命令并将用户名和密码传递给它,而无需在系统要求时输入它们?
询问用户名和密码的示例命令
git clone https://github.com/username/repo.git
只是一个例子,请不要建议使用 ssh 而不是 http 进行 git clone,或者在命令中公开密码是不安全的
“expect”包就是为这种事情而构建的。如果您安装它,请查看“autoexpect”。
例子:
autoexpect
# Output: autoexpect started, file is script.exp
# Login with user/pass with ssh - just to test
ssh -o PubkeyAuthentication=no myuser@myhost
<type-password>
<command>
<command>
exit
# Now exit once more to exit autoexpect
# Output: autoexpect done, file is script.exp
接下来是编辑 script.exp 并清理它。有大量关于此的文档。
我想要赏金,但我不能以 dup 的身份关闭,因为答案在不同的 SE 上。
引用超级用户的答案:
考虑到expect
它的手册页指出:
连接到另一个网络或 BBS(例如,MCI Mail、CompuServe)。
Compuserve,那是在法国大革命之前还是之后?反正。
spawn "git clone ssh://git@domain.com/myproject.git"
expect "Enter passphrase for key..." { send "myPassword\r" }
read -p "enter..."
也许最后一行是多余的。
Ceterum censeo:不要那样做。
注意:Git 要求您使用 git 令牌而不是密码。
empty 是一个实用程序,它提供了一个简单的接口来在伪终端会话下执行和/或与进程交互。
这个工具在 sed 与 telnet 或 FTP 等交互式程序通信的 shell 脚本编程中绝对有用。
在某些情况下,空可以替代 TCL/expect 或其他类似的编程工具。
将下面的代码复制到您的脚本文件中。
通过从命令行提供以下参数(如您所要求的那样)使其可执行并运行脚本:
例子:
假设您的脚本文件名是git_clone.sh
:
./git_clone.sh <GIT_REPO_URI> <GIT_USERNAME> <GIT_USER_TOKEN>
#!/bin/bash
git_repo="${1}"
git_user="${2}"
git_token="${3}"
empty -f -i in.fifo -o out.fifo -pempty.pid git clone
empty -w -i out.fifo -o in.fifo sername "${git_user}\n"
empty -w -i out.fifo -o in.fifo assword "${git_token}\n"
exit 0
有关更多详细信息,empty
请参阅其手册:
http: //manpages.ubuntu.com/manpages/bionic/man1/empty.1.html
注意:empty
命令需要通过安装empty-expect
包可用。
要在 Ubuntu 18.04 或 16.04 上安装,您可以运行:
add-apt-repository "deb http://archive.ubuntu.com/ubuntu $(lsb_release -sc) universe"
apt update;
apt install -y empty-expect
### 更新:要在 Ubuntu 20.04 中安装软件包,您可以通过运行以下命令empty-expect
来使用 Ubuntu 18.04(仿生)存储库:universe
echo 'deb http://archive.ubuntu.com/ubuntu bionic universe' > /etc/apt/sources.list.d/bionic-universe.list
apt update
apt install -y empty-expect
script
script
将生成一个可以在bash下与之交互的tty,使用. 这可以在不需要的情况下完成:coproc
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
这会启动一个 subshell,您可以与之交互,
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 5.1.4(1)-release
, on下运行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,准备好获取资源。
根据您想要这样做的原因,您可能想要探索在没有密码的情况下使用 github 存储库的方法:
不知道你有没有试过这个。但这在我们执行任何 sudo cmd 并需要输入密码的情况下很有用。你可以在你的情况下试试这个。
但我认为您至少必须提供用户名。
例如 :
sudo -S <<< "password" sudo yum -y update
在你的情况下,它应该是这样的:
sudo -S <<< {password} git clone https://github.com/{username}/repo.git