6

如果我有一个提示输入 2 个或更多输入的 linux 命令,如何通过在命令行中定义这些输入将其传递给提示?您可以在命令后面添加一些东西来执行此操作吗?

在下面的示例中,如何运行命令并将用户名和密码传递给它,而无需在系统要求时输入它们?

询问用户名和密码的示例命令

git clone https://github.com/username/repo.git 

只是一个例子,请不要建议使用 ssh 而不是 http 进行 git clone,或者在命令中公开密码是不安全的

4

7 回答 7

4

“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 并清理它。有大量关于此的文档。

于 2013-04-16T07:19:50.690 回答
3

我想要赏金,但我不能以 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:不要那样做。

于 2021-12-16T08:17:46.733 回答
1

注意:Git 要求您使用 git 令牌而不是密码。

empty 是一个实用程序,它提供了一个简单的接口来在伪终端会话下执行和/或与进程交互。

这个工具在 sed 与 telnet 或 FTP 等交互式程序通信的 shell 脚本编程中绝对有用。

在某些情况下,空可以替代 TCL/expect 或其他类似的编程工具。

将下面的代码复制到您的脚本文件中。

通过从命令行提供以下参数(如您所要求的那样)使其可执行并运行脚本:

  • Git repo URI(作为第一个参数)
  • Git 用户名(作为第二个参数)
  • Git 用户令牌(作为第三个参数)

例子:

假设您的脚本文件名是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
于 2021-12-21T06:28:50.123 回答
1

下,您可以使用script

script将生成一个可以在tty,使用. 这可以在不需要的情况下完成:coprocexpect

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

这会启动一个 subshel​​l,您可以与之交互,

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.shexpectScr.sh.txt,准备好获取资源

于 2021-12-19T11:46:47.377 回答
0

或许这

{
  echo user
  echo pass
} | git clone https://github.com/username/repo.git

ref

于 2013-04-16T00:57:03.023 回答
0

根据您想要这样做的原因,您可能想要探索在没有密码的情况下使用 github 存储库的方法:

https://help.github.com/articles/managing-deploy-keys

于 2013-04-16T01:02:36.890 回答
0

不知道你有没有试过这个。但这在我们执行任何 sudo cmd 并需要输入密码的情况下很有用。你可以在你的情况下试试这个。

但我认为您至少必须提供用户名。

例如 :

sudo -S <<< "password" sudo yum -y update 

在你的情况下,它应该是这样的:

sudo -S <<< {password} git clone https://github.com/{username}/repo.git
于 2021-12-22T05:40:05.810 回答