如何解决UNIX-提示用户在远程SSH内部输入
当我使用SSH登录到远程服务器时,我试图在执行一些任务后要求用户输入是否启动服务,同时尝试使过程自动化。这是例子
sshpass -p$password ssh -T -o StrictHostKeyChecking=no $srv <<EOF
if [cond1]
then
do task1
else
do task2
fi
some tasks to perform
## This part doesn't show up when run ##
read -p "Are you sure you want to start the service? Enter (Y/y or N/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
start the service
fi
EOF
但是,当我运行此自动化脚本时,它执行了先前的任务,但是跳过了提示用户启动服务的步骤,也跳过了该任务。
请帮助。
谢谢, 席德
解决方法
问题出在调用脚本的方式上:
sshpass -p$password ssh -T -o StrictHostKeyChecking=no $srv <<EOF
...
EOF
在这里,您正在使用stdin发送脚本本身。那么read
应该从哪里读取?我实际上没有sshpass,所以我无法直接对其进行测试,但这可以在ssh和受信任的密钥下使用:
ssh <your ssh options> '
read -p "Are you sure you want to start the service? Enter (Y/y or N/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo hi
fi
'
现在,您将以字符串形式发送脚本,而stdin可以自由使用以进行交互使用。我看不到您所有的脚本,因此如果您的脚本实际上在脚本中使用'
,则可能会导致其他问题。
更新
通过将命令保存到脚本文件中,可以避免单引号问题。假设a.sh
:
ssh <your ssh options> "$(< a.sh)"
这会将详细命令发送到ssh命令,而不必担心变量扩展或其他任何事情。
更新2
如果我们试图避免将脚本保存到文件中,则仍可以使用单引号选项。解决现有单引号的方法是将每次出现的情况都改为:'\''
。因此,从本质上讲,它将终止单引号字符串,在字符串本身添加单引号,然后重新打开单引号字符串。那里没有空格,它仍然是一个字符串。这是一个示例,如果您的读取行使用单引号而不是双引号:
ssh <your ssh options> '
read -p '\''Are you sure you want to start the service? Enter (Y/y or N/n)'\'' -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo hi
fi
'
请注意Stackoverflow的语法突出显示如何正确地解析了这一点,并举例说明了我想说的话。为了减少复杂性,我会尽可能多地将单引号转换为双引号。
您也可以使用双引号而不是单引号。现在的问题是,bash解释器可以在通过ssh之前对其进行操作。为了避免这种情况,您将需要转义所有扩展以及现有的双引号。像这样:
ssh <your ssh options> "
read -p \"Are you sure you want to start the service? Enter (Y/y or N/n)\" -n 1 -r
if [[ \$REPLY =~ ^[Yy]$ ]]
then
echo hi
fi
"
为避免这种方法的复杂性,请尽可能将双引号转换为单引号。
最终更新
您可以像使用命令替换,cat和此处文档(不带扩展名)的组合一样使用原始字符串:
ssh <your ssh options> "$(cat <<'EOF'
read -p "Are you sure you want to start the service? Enter (Y/y or N/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo hi
fi
EOF
)"
请注意,此方法实际上欺骗了Stackoverflow的语法突出显示,但它可以工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。