请参见 https://stackoverflow.com/a/57847199/4579271 读取单个变量#!/usr/bin/expectset passphrase [gets stdin]读取多个变量#!/usr/bin/expectset data [gets stdin]scan $data "%s %s" hostname passphrase另一种方法是使用环境变量(如Glenn所建议的),但还有一个警告:环境变量仅可用于定义它们的外壳及其子对象.因此,在batch.sh中定义的环境变量在使用osascript创建的iTerm2选项卡中将不可用.因此,我唯一安全的选择是完全删除osascript并使所有代码(batch.sh和expect.exp)在同一外壳中执行,并使用环境变量在bash和. batch.sh #!/bin/bashhostnames=( "hostname-1" "hostname-2")read -sp 'SSH key passphrase: ' passphraseecho ""export PASSPHRASE=$passphrasefor hostname in "${hostnames[@]}"; do export HOSTNAME=$hostname expect "$(dirname "$0")/expect.exp"done expect.exp #!/usr/bin/expectset timeout 10spawn 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" }}interactWhen executing expect scripts, arguments are visible on ps ax which can be a security vulnerability if they are sensitive.Trying to automate opening a tab on iTerm2, running ssh admin@host and entering the passphrase when asked Enter passphrase for key '/Users/admin/.ssh/key' (the key is encrypted using that passphrase).Host hostHostName 1.2.3.4IdentityFile ~/.ssh/keyI would like to supply the passphrase to bash using read -sp 'Passphrase: ' passphrase and then pipe it to expect (which isn’t perfect at all from an OPSEC perspective but much better than having the passphrase leaked on ps ax).Perhaps there is a better way?Bellow is some code that works but leaks the passphrase on ps ax. Commented out is what I wish was possible (piping the passphrase to expect).batch.sh#!/bin/bashfunction 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: ' passphrasefor hostname in "${hostnames[@]}"; do # new_tab "echo $passphrase | expect $(pwd)/expect.exp \"$hostname\"" new_tab "expect $(pwd)/expect.exp \"$hostname\" \"$passphrase\""doneexpect.exp#!/usr/bin/expectset hostname [lindex $argv 0]set passphrase [lindex $argv 1]spawn ssh admin@$hostnameexpect "passphrase"send "$passphrase\r"interact 解决方案 Yes, expect can read from stdin but there is a caveat: reading from stdin isn’t compatible with interact.See https://stackoverflow.com/a/57847199/4579271Reading a single variable#!/usr/bin/expectset passphrase [gets stdin]Reading multiple variables#!/usr/bin/expectset data [gets stdin]scan $data "%s %s" hostname passphraseAnother approach is to use environment variables (as suggested by Glenn) but there is another caveat: environment variables are only available to the shell in which they are defined and its children.Environment variables defined in batch.sh would therefore not be available in the iTerm2 tabs created using osascript.So the only secure option I have is to drop osascript altogether and have all the code (batch.sh and expect.exp) execute in the same shell and use environment variables to pass variables between bash and expect.batch.sh#!/bin/bashhostnames=( "hostname-1" "hostname-2")read -sp 'SSH key passphrase: ' passphraseecho ""export PASSPHRASE=$passphrasefor hostname in "${hostnames[@]}"; do export HOSTNAME=$hostname expect "$(dirname "$0")/expect.exp"doneexpect.exp#!/usr/bin/expectset timeout 10spawn 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 这篇关于可以期望脚本从stdin读取数据吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 09-17 18:22