Linux 预计在使用交互后不会将控制返回给 bash 脚本
Linux expect not returning control to bash script after using interact
我的目标是自动执行以下操作
- 从主 shell 脚本登录到远程 SSH 会话(无密码密钥已经设置)
- 然后我需要 root 访问权限,所以我使用 expect 登录,即 send "su",expect "Password:",send "" which有效。
- 然后我想将控制权从 expect 释放回调用 expect 脚本的 bash 脚本和 运行 以 root 身份登录的各种 SSH 命令。
这可能吗,还是我必须通过 expect 做所有事情?
您遇到的问题是必须保留各个层级的通信;发生的事情比你知道的要多。
您的模型是这样的:
+------+ expect +-----+ su +----------------+
| bash | ---------> | ssh | -----> | remote-context |
+------+ +-----+ +----------------+
但实际情况是这样的:
+----------------+ +----------------------+ +----------------------------+
| local terminal | | expect | | remote terminal |
| | | +------------------+ | | +------------------------+ |
| +------+ | | | virtual terminal | | | | bash | |
| | bash | -----> | | | | | | +--------------------+ | |
| +------+ | | | +-----+ | | | | | su | | |
| | | | | ssh | ---------> | | | +----------------+ | | |
+----------------+ | | +-----+ | | | | | | remote context | | | |
| +------------------+ | | | | +----------------+ | | |
+----------------------+ | | +--------------------+ | |
| +------------------------+ |
+----------------------------+
或类似的东西(例如,我省略了大部分与网络有关的位)。正在进行 很多 的分层,其中大部分您都没有意识到。但是因为 ssh
在 expect
中是 运行ning(为了利用自动化功能)这意味着 ssh
在本地虚拟机中是 运行ning expect
控制的终端; bash
无法直接控制,expect
也无法将自己切出循环(因为 bash
不知道如何成为虚拟终端的主控端;expect
和 sshd
知道)。
相反,您需要直接将代码的其余部分写入 expect 中,或者提供要成为 运行 的代码作为参数(在某种意义上;可能是从文件中提取的?)它可以通过 send
.
传递
Expect 从 argv
变量获取参数,可以使用 gets stdin
从调用者那里读取一行文本,并且 open
/read
/close
拉入文件的内容。
您是否知道 sudo
可以替代 su
?可以将其配置为允许特定请求用户完全免密码操作。这对于允许在不暴露太大安全漏洞的情况下运行系统很有用。您还应该考虑切换到一种更适合自动化的 ssh
形式,例如:
spawn ssh $remotehost sudo /usr/local/bin/DoTheWonderfulThing
这种东西,一旦起作用,就不会以意想不到的方式出错……
我的目标是自动执行以下操作
- 从主 shell 脚本登录到远程 SSH 会话(无密码密钥已经设置)
- 然后我需要 root 访问权限,所以我使用 expect 登录,即 send "su",expect "Password:",send "" which有效。
- 然后我想将控制权从 expect 释放回调用 expect 脚本的 bash 脚本和 运行 以 root 身份登录的各种 SSH 命令。
这可能吗,还是我必须通过 expect 做所有事情?
您遇到的问题是必须保留各个层级的通信;发生的事情比你知道的要多。
您的模型是这样的:
+------+ expect +-----+ su +----------------+
| bash | ---------> | ssh | -----> | remote-context |
+------+ +-----+ +----------------+
但实际情况是这样的:
+----------------+ +----------------------+ +----------------------------+
| local terminal | | expect | | remote terminal |
| | | +------------------+ | | +------------------------+ |
| +------+ | | | virtual terminal | | | | bash | |
| | bash | -----> | | | | | | +--------------------+ | |
| +------+ | | | +-----+ | | | | | su | | |
| | | | | ssh | ---------> | | | +----------------+ | | |
+----------------+ | | +-----+ | | | | | | remote context | | | |
| +------------------+ | | | | +----------------+ | | |
+----------------------+ | | +--------------------+ | |
| +------------------------+ |
+----------------------------+
或类似的东西(例如,我省略了大部分与网络有关的位)。正在进行 很多 的分层,其中大部分您都没有意识到。但是因为 ssh
在 expect
中是 运行ning(为了利用自动化功能)这意味着 ssh
在本地虚拟机中是 运行ning expect
控制的终端; bash
无法直接控制,expect
也无法将自己切出循环(因为 bash
不知道如何成为虚拟终端的主控端;expect
和 sshd
知道)。
相反,您需要直接将代码的其余部分写入 expect 中,或者提供要成为 运行 的代码作为参数(在某种意义上;可能是从文件中提取的?)它可以通过 send
.
Expect 从 argv
变量获取参数,可以使用 gets stdin
从调用者那里读取一行文本,并且 open
/read
/close
拉入文件的内容。
您是否知道 sudo
可以替代 su
?可以将其配置为允许特定请求用户完全免密码操作。这对于允许在不暴露太大安全漏洞的情况下运行系统很有用。您还应该考虑切换到一种更适合自动化的 ssh
形式,例如:
spawn ssh $remotehost sudo /usr/local/bin/DoTheWonderfulThing
这种东西,一旦起作用,就不会以意想不到的方式出错……