Bash:交互式远程提示

Bash:交互式远程提示

我有一个连接到远程服务器并检查是否安装了某些软件包的脚本:

ssh root@server 'bash -s' < myscript.sh

myscript.sh:

OUT=`rpm -qa | grep ntpdate`
if [ "$OUT" != "" ] ; then
    echo "ntpdate already installed"
else
    yum install $1
fi

这个例子可以简化。这是myscript2.sh有同样问题的:

read -p "Package is not installed. Do you want to install it (y/n)?" choise

我的问题是 bash 无法交互式地阅读我的答案。

有没有办法远程执行本地脚本而不失去提示用户的能力?

答案1

尝试这样的事情:

$ ssh -t yourserver "$(<your_script)"

强制-t进行 tty 分配,$(<your_script)读取整个文件,并在这种情况下将内容作为一个参数传递给ssh,这将由远程用户的 shell 执行。

如果脚本需要参数,请在脚本之后传递它们:

$ ssh -t yourserver "$(<your_script)" arg1 arg2 ...

对我有用,但不确定它是否通用。

答案2

您的问题是ssh在远程计算机上启动登录、非交互式 shell。显而易见的简单解决方案是将脚本复制到远程服务器并从那里运行它:

scp myscript.sh root@server:/tmp && ssh root@server /tmp/myscript.sh

如果出于某种原因无法进行复制,我将修改脚本以首先连接并检查是否$1已安装,然后根据需要重新连接并安装:

OUT=$(ssh root@server rpm -qa | grep "$1");
if [ "$OUT" != "" ] ; then
    echo "$1 already installed"
else
   read -p "Package $1 is not installed. Do you want to install it (y/n)?" choice
   if [ "$choice" -eq "y" ]; then
       ssh root@server yum install "$1"
   fi
fi

答案3

这里有一个好的解释

所以我将脚本改编为

hostname
echo -n "Make your choice :"
read choice
echo "You typed " ${choice}
echo done

但这不起作用。

所以我将脚本移至远程以避免 ssh 上的本地重定向。 (我的命令位于名为F

cat f | ssh [email protected] 'cat >remf'
ssh user@remotehost bash remf

这奏效了。这是输出:

christian@clafujiu:~/tmp$ ssh localhost bash tmp/f
christian@localhost's password: 
Linux clafujiu 2.6.32-52-generic #114-Ubuntu SMP Wed Sep 11 19:00:15 UTC 2013 i686 GNU/Linux
Sun Nov 10 14:58:56 GMT 2013
Make your choice :abc
You typed  abc
done

正如@terdon提到的,最初的意图是远程运行本地脚本,远程复制可以自动化,这只是一行的一个例子。

REMID=`cat f |ssh user@remotehost 'cat > remf_$$; echo $$'` ;ssh [email protected] "bash remf_${REMID} ; rm -v remf_${REMID}"

答案4

过去我曾多次寻找这个问题的解决方案,但从未找到完全令人满意的解决方案。通过管道连接到 ssh 会失去交互性。两个连接 (scp/ssh) 速度较慢,并且您的临时文件可能会散落在各处。命令行上的整个脚本通常最终会逃离地狱。

最近我遇到命令行缓冲区大小通常很大(我查看的“getconf ARG_MAX > 2MB”)。这让我思考如何使用它并减轻逃逸问题。

结果是:

ssh -t <host> /bin/bash "<(echo "$(cat my_script | base64 | tr -d '\n')" | base64 --decode)" <arg1> ...

或使用此处的文档和 cat:

ssh -t <host> /bin/bash $'<(cat<<_ | base64 --decode\n'$(cat my_script | base64)$'\n_\n)' <arg1> ...

我扩展了这个想法,生成了一个完全可用的 BASH 示例脚本sshx可以通过 ssh 运行任意脚本(不仅仅是 BASH),其中参数也可以是本地输入文件。看这里

相关内容