SSH 远程主机上执行本地脚本 向远程主机传递脚本和脚本需要的参数


SSH 远程主机上执行本地脚本 向远程主机传递脚本和脚本需要的参数
20180820 陈信
参考: https://www.cnblogs.com/sparkdev/p/6842805.html

示例:
预热服上执行脚本,检查其他服务器上java进程的堆栈信息(所有脚本和文件均在预热服上)
[xbzj@ip-10-0-0-200 server-ip]$ cat jvm-stack.sh

!/bin/bash

20180820,Chenxin

cd /home/xbzj/server-bin/server-ip
cat rsync-ip.txt|grep -v "codex.match" > ./rsync-ip-jvm-stack-tmp.txt #这是服务器IP列表信息
cat ./rsync-ip-jvm-stack-tmp.txt |while read line
do
if [ -z "$line" ];then
continue
fi
echo "------ 启动服务器java堆栈信息检索 ------"
echo $line |awk '{print $1 " " $3}'
ip=echo "${line}"|awk '{print $3}'
/usr/bin/ssh $ip -p 4399 -o ConnectTimeout=5 < ./jvm-stack-hotsrv.sh #-o ConnectTimeout=5为ssh连接等待5秒超时
echo "------ END ------"
done

[xbzj@ip-10-0-0-200 server-ip]$ cat jvm-stack-hotsrv.sh #相当于在本地执行的脚本内容

!/bin/bash

20180820,Chenxin

javapid=ps axf|grep java|grep -v -E "(grep|logstash)"|awk '{print $1}'
for i in echo $javapid;do
echo "--- 进程号 $i 以下是该进程的详细信息 ---"
ps $i
echo "--- 进程号 $i 以下是该进程的jmap信息 ---"
jmap -heap $i
done

以下是知识部分(可以不看)
SSH 交互tty 执行需要交互的命令
有时候我们需要远程执行一些有交互操作的命令。
$ sshnick@xxx.xxx.xxx.xxx "sudo ls /root"
$ sshnick@xxx.xxx.xxx.xxx "top"

这两条命令虽然提示的失败原因不同,但它们有一个共同点:都需要与用户交互(需要 TTY)。所以它们失败的原因也是相同的:
默认情况下,当你执行不带命令的 ssh 连接时,会为你分配一个 TTY。因为此时你应该是想要运行一个 shell 会话。
但是当你通过 ssh 在远程主机上执行命令时,并不会为这个远程会话分配 TTY。此时 ssh 会立即退出远程主机,所以需要交互的命令也随之结束。
ssh 34.238.67.156 -p 4399 "top"
TERM environment variable not set. #报错

好在我们可以通过 -t 参数显式的告诉 ssh,我们需要一个 TTY 远程 shell 进行交互!
添加 -t 参数后,ssh 会保持登录状态,直到你退出需要交互的命令。

ssh 34.238.67.156 -p 4399 -t "top"
按"q"退出

作为总结,我们看看 -t 参数的官方解释:
"Force pseudo-terminal allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty."
好吧,更强悍的是我们居然可以指定多个 -t 参数!

ssh 多行命令 多条命令(将本地脚本传递给远程主机,并在远程主机上执行传递过去的脚本)
远程执行脚本
对于要完成一些复杂功能的场景,如果是仅仅能执行几个命令的话,简直是弱爆了。我们可能需要写长篇累牍的 shell 脚本去完成某项使命!此时 SSH 依然是不辱使命的好帮手(哈哈,前面的内容仅仅是开胃菜啊!)。
执行本地的脚本
我们在本地创建一个脚本文件 test.sh,内容为:
ls
pwd
然后运行下面的命令:
$ sshnick@xxx.xxx.xxx.xxx < test.sh
通过重定向 stdin,本地的脚本 test.sh 在远程服务器上被执行。

ssh 远程 参数传递(将本地参数传递给远程主机,并在远程主机上执行传递过去的脚本和参数)
本地服务器上: vim t.sh

!/bin/bash

echo $0
echo $1
要想在这种情况下(远程执行本地的脚本)执行带有参数的脚本,需要为 bash 指定 -s 参数:
[xbzj@ip-10-0-0-200 server-ip]$ ssh 34.238.67.156 -p 4399 'bash -s' < ./t.sh 1
bash
1
输出的是 "bash" 和 "1" 分别对应 $0 和 $1.

执行远程服务器上的脚本(脚本已经在远程机器上) 参数可以直接传递过去(这个为最常用的方式)
此时在远程服务器上用户 nick 的家目录中有一个脚本 test.sh。文件的内容如下:
ls
pwd
echo $0
echo $1
然后尝试执行下面的命令:
$ ssh nick@xxx.xxx.xxx.xxx /home/nick/test.sh helloworld
能够正常输出变量.最后两行 "/home/nick/test.sh" 和 "helloworld" 分别对应 $0 和 $1。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM