首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >脚本可以从stdin读取数据吗?

脚本可以从stdin读取数据吗?
EN

Stack Overflow用户
提问于 2019-09-08 06:25:02
回答 2查看 343关注 0票数 2

执行expect脚本时,参数在ps ax上可见,如果它们很敏感,则可能存在安全漏洞。

尝试自动打开iTerm2上的选项卡,运行ssh admin@host,并在询问Enter passphrase for key '/Users/admin/.ssh/key'时输入密码(密钥是使用该密码加密的)。

代码语言:javascript
复制
Host host
HostName 1.2.3.4
IdentityFile ~/.ssh/key

我希望使用read -sp 'Passphrase: ' passphrase将密码提供给bash,然后通过管道将其提供给expect (从OPSEC的角度来看,这并不完美,但比在ps ax上泄露密码要好得多)。

也许有更好的方法?

下面是一些可以工作的代码,但是泄漏了ps ax上的密码短语。注释掉了我所希望的(通过管道将密码短语传递给expect)。

batch.sh

代码语言:javascript
复制
#!/bin/bash

function new_tab() {
  command=${1//\"/\\\"}
  osascript \
    -e "tell application \"iTerm2\"" \
    -e "tell current window" \
    -e "create tab with default profile" \
    -e "delay 1" \
    -e "tell current session" \
    -e "write text \"$command\"" \
    -e "end tell" \
    -e "end tell" \
    -e "end tell" > /dev/null
}

hostnames=(
  "hostname-1"
  "hostname-2"
)

read -sp 'Passphrase: ' passphrase

for hostname in "${hostnames[@]}"; do
  # new_tab "echo $passphrase | expect $(pwd)/expect.exp \"$hostname\""
  new_tab "expect $(pwd)/expect.exp \"$hostname\" \"$passphrase\""
done

expect.exp

代码语言:javascript
复制
#!/usr/bin/expect

set hostname [lindex $argv 0]
set passphrase [lindex $argv 1]

spawn ssh admin@$hostname
expect "passphrase"
send "$passphrase\r"
interact
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-10 05:31:55

是的,expect可以从stdin读取数据,但需要注意的是:从stdin读取数据与interact不兼容。

请参阅https://stackoverflow.com/a/57847199/4579271

读取单个变量

代码语言:javascript
复制
#!/usr/bin/expect

set passphrase [gets stdin]

读取多个变量

代码语言:javascript
复制
#!/usr/bin/expect

set data [gets stdin]
scan $data "%s %s" hostname passphrase

另一种方法是使用环境变量(如Glenn所建议的),但还有另一个警告:环境变量只对在其中定义它们的shell及其子级可用。

因此,在batch.sh中定义的环境变量在使用osascript创建的iTerm2选项卡中不可用。

因此,我唯一安全的选择是完全删除osascript,让所有代码(batch.shexpect.exp)在同一个shell中执行,并使用环境变量在bashexpect之间传递变量。

batch.sh

代码语言:javascript
复制
#!/bin/bash

hostnames=(
  "hostname-1"
  "hostname-2"
)

read -sp 'SSH key passphrase: ' passphrase

echo ""

export PASSPHRASE=$passphrase

for hostname in "${hostnames[@]}"; do
  export HOSTNAME=$hostname
  expect "$(dirname "$0")/expect.exp"
done

expect.exp

代码语言:javascript
复制
#!/usr/bin/expect

set timeout 10

spawn ssh admin@$env(HOSTNAME)

expect {
  default {
    puts "\nCould not connect to $env(HOSTNAME)"
    exit 1
  }
  "passphrase" {
    send "$env(PASSPHRASE)\r"
  }
}

expect {
  default {
    puts "\nWrong passphrase"
    exit 1
  }
  "admin@$env(HOSTNAME)" {
    # Add automation commands here, then exit SSH session to close expect script moving on to the next hostname
    send "exit\r"
  }
}

interact
票数 1
EN

Stack Overflow用户

发布于 2019-09-08 21:08:02

在bashscript中,读取密码,然后export变量。在expect中,使用$env(passphrase)从环境中访问它

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57837869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档