shell - 从标准输入读取程序输出而不是使用 spawn
问题描述
我正在尝试编写一个生成 ssh 进程并使用密码进行身份验证的 shell 函数。然后,我想使用生成的进程来做更多的事情。
这是我到目前为止的功能:
ssh_cmd() {
ssh $USER@$HOST 2>&1 | expect -c "
log_user 0
set timeout 5
expect password: {
send \"$PASS\n\"
sleep 2
log_user 1
}
"
}
然后我想在其他地方使用给定的函数来与 ssh 进程进行交互,如下所示:
ssh_cmd | expect -c "
expect '#' {
send pwd\n
send exit\n
}
expect eof
"
但是,使用 expect 选项运行该ssh_cmd
函数-d
会得到以下结果:
expect version 5.45.4
expect: does "" (spawn_id exp0) match glob pattern "password:"? no
ubnt@ui1's password: expect: timed out
据我了解,输出ssh
没有正确传输。我知道执行此操作的常用方法是使用spawn
,但这意味着进程将在期望退出后被终止,并且我无法拥有一个通用函数来验证 ssh 会话并保持进程处于活动状态以供进一步使用。
解决方案
你设计的东西是行不通的。Expect 需要使用命令从expect
解释器中生成进程。spawn
将命令的标准输出传递给期望是不够的。
你可以试试这个:
ssh_cmd() {
# a default bit of code if user does not provide one.
# you probably want some checking and emit an error message.
local user_code=${1:-set timeout 1; send "exit\r"; expect eof}
expect -c "
log_user 0
set timeout 5
spawn ssh -l $USER $HOST
expect password: {
send \"$PASS\n\"
sleep 2
log_user 1
}
$user_code
"
}
然后像这样调用它:
ssh_cmd '
expect "#" {
send pwd\r
send exit\r
}
expect eof
'
请注意,单引号在期望中没有特殊含义,它们只是普通字符:您可能不希望提示是 3 字符模式'#'
推荐阅读
- python-3.x - Tkinter在Button1中捕获两个不同按钮的位置单击并释放
- java - 如何检查二维数组是否为拉丁文
- vba - 无法使用 VBA 在 Solver 中设置整数约束
- r - 将 xts 转换为 tibble 的最佳方法是什么
- java - HTML 内容损坏
- apache-kafka - 为什么 Apache Kafka 不支持临时主题?
- javascript - Javascript querySelector 获取值条件
- php - Laravel Route::current() 返回 null
- perl - Perl 语法(替换 'defined(@array')
- javascript - 使用 javascript、PHP、MySQl 上传多张图片