Linux 实操———— Shell 远程执行命令

引言

目前,开发人员的部署方式是,将项目打包(Maven 打包) 然后将 生成的 jar 包等文件,通过Xshell 等终端工具手动传输到远程服务器上,然后再通过在终端执行远程服务器上的 shell 脚本来启动服务。

本篇博客聚焦这样一种解决方案,通过在本地(Windows或Mac 系统等)运行 Shell 脚本,使用 scp 命令传输,并通过 ssh 命令执行远程服务器上的指令或脚本,来完成这一系列各种软件切换、复制粘贴、启动运行的操作,达到 “一键部署” 的效果。这在前期频繁更新部署 jar 包到远程服务器有很大的效率提升。

一、准备条件

如果本机是 Windows 系统,那么如果希望执行 shell 脚本,至少需要安装一个类似 Xshell 的终端工具,普通的 dos 命令行肯定是不行的。

不过如果有装过 git ,那么通过Git Bash 来执行 Shell 脚本是个不错的选择。

另外,文件上传和远程执行 Shell 脚本需要对 scp 命令、 Shell 命令 、ssh 等命令有一定的了解。

二、文件上传

一般在主机之间传输文件除了使用 SFTP 等协议外,还会使用 scp 命令,这些协议都基于 ssh 安全登录协议。scp 命令在之前的文章中有简单介绍过,详情参考我的《Linux进阶之路————scp指令介绍与演示》

于是,我们可以像下面这样将打包好的 jar 文件通过 scp 命令传输到 远程主机上:

#!/bin/bash
## 通过 scp 命令上传
scp ../target/demo-0.0.1-SNAPSHOT.jar root@192.168.1.140:~/myapp/

这个格式非常简单,首先 scp 命令先行,其次是源文件,再然后就是远程主机的 ip 地址以及存放的位置,其中 ~ 代表用户的 HOME 目录,比如 root 用户的 HOME 目录就是 /root,tom用户的 HOME 目录就是 /home/tom/ 。如果希望传输多个文件,可以直接用空格隔开(多个空格没有关系),类似这样:

scp  文件1  文件2  文件3...    user@IP:目标路径

其实,完全可以在项目的 classpath 下建立一个专门管理 shell 文件的文件夹,类似这样:

这样的话,shell 和 target 下打包出来的 jar 包始终保持相对路径,就不会因为在不同开发者主机上的项目位置不同而频繁修改 shell 中的 jar 包路径。

三、远程执行 Shell 项目启动脚本

当执行完文件上传命令之后,接下来就是启动远程主机的 Shell 脚本,让服务启动。

通常,我们会在远程服务器上放置一个配置好固定参数的启动脚本,类似这样:

但每次都需要登录远程主机,切换到目标位置,再执行启动脚本有些麻烦,于是,我们可以在保留远程脚本的同时将调用执行的操作放在本地 Windows 主机上。

于是,我们可以在上面的 scp 命令之后,添加 ssh 命令用于执行远程脚本:

#!/bin/bash
## 通过 scp 命令上传
scp ../target/demo-0.0.1-SNAPSHOT.jar root@192.168.1.140:~/myapp/## 上传后执行启动脚本
ssh root@192.168.1.140 << bash
source /etc/profile
cd ~/myapp
./app.sh restart demo-0.0.1-SNAPSHOT.jar
bash

我们可以使用 ssh 命令在本地执行远程主机上的命令,包括执行 shell 脚本。

其中,"<<" 代表输入重定向,它的功能可以这样来描述:

格式:cmd << text

从命令行读取输入,直到一个与text 相同的行结束。text 是自定义的文本,可以是任何字符串,那么 text 与 text 之间的全部内容,都会被当做输入的参数,并被输入到 << 左边的指令中。

于是,红框内的部分就是我们要执行的 Shell 调用的具体命令(由于我的Eclipse安装了 shell编辑插件,<< 的部分会被灰色处理):

值得一提的是,在真正执行远程 app.sh 脚本之前,需要执行 source /etc/profile  命令,这在我的《Linux 实操———CentOS 6 安装配置 Oracle JDK 1.8》和《Linux进阶之路———Shell 编程入门》中都有说明,意思就是刷新环境变量。这是因为远程连接的情况下不会自动加载环境变量,因此,如果你调用的远程脚本中存在类似 java 的环境变量的命令,就会报 command not found 错误。因此只要在执行脚本之前刷新环境变量就可以了。

另外,远程的输出会被传回到本地的 Git Bash 窗口,如果希望将输出保存到远程的 nohup.out 文件中,需要添加 >> 重定向:

当加入输出重定向后,服务端的输出就会保留在nohup.out 中,而 Git Bash 也不会有任何输出内容,从而安静的执行完脚本并返回。下面第四节采用了非重定向的方式,可以根据实际情况酌情考虑。

本博客暂未做.log 日志文件的输出检查,如果对是否会影响每天日志保存的情况,还有待进一步验证。未来验证后会追加这个问题。 

四、远程传输并启动项目

到此为止,通过本地的 deploy.sh ,我们就有足够的能力传输 jar 包并启动远程服务(deploy.sh—>app.sh—>启动服务),接下来我们实际演示一下,看看能否成功。

当然,Eclipse 貌似也有执行 bash 的插件。这里由于操作比较简单,我们可以通过 Eclipse 编辑完 Shell 后在系统盘中打开,然后通过 Git Bash 来执行,方法是选中文件,右键——>Show In——>System Explorer:

然后在打开的资源管理器中右键空白,选择 Git Bash:

最后执行脚本:

我们可以看到远程服务的日志输出(如果是重定向到远程文件,例如 ">> nohup.out",就会在远程服务器上保留输出),这更加方便了我们判断是否启动成功,当看到启动成功后,将Git Bash 关闭即可。这并不会影响远程服务。

我们来检查一下,服务的访问,以及远程服务器上的资源情况,应该是都没有问题的:

值得一提的是,在scp 和 ssh 执行部署工作的时候,需要两次交互式的输入密码(scp 一次,ssh 一次),密码是不可见的,如果你的密码非常长,建议复制粘贴。

虽然脚本已经足够简化文件上传和启动的操作,但是依然不能避免输入密码的痛苦。

还有一种方式是使用 rsa 公私钥来解决免密操作的方式,但是如果是多开发者的话,就需要为每台开发者机器配置公私钥,这就极大地增加了前期的部署工作和操作难度,但如果大家每次都复制粘贴密码的话好像也会使密码渐渐变得不那么安全,容易泄露。另外有一种支持非交互式免密的方式是 sshpass ,它可以在ssh 之前通过 -P "password" 指定登录密码, 不过这东西貌似在 Git Bash 上不支持,甚至在 CentOS 6 上也找不到yum 安装,比较难搞。

总之,目前我还没有找到比较好的权宜之计,所以,暂且就复制粘贴吧,其实已经足够简单了。

参考与鸣谢

Linux Shell远程执行命令(命令行与脚本方式)

linux shell 远程执行命令

linux:shell脚本中一些特殊符号

linux几种文件传输方式

ssh登录时在参数中加入密码的解决方案

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 设置 ASCII banner 艺术字

引言 无意中看到Spring boot 项目的 resources 目录下有一个 banner.txt &#xff0c;打开一看&#xff0c;居然是ASCII 字符画。于是兴起&#xff0c;简单研究了一下。 Spring boot 可以加载 resources 目录下的 banner.txt 文件&#xff0c;将字符画在启动之初输出到日志或…

MySQL 基础 ———— 分组查询

引言 承接上一篇《MySQL 基础 ————高频函数总结》&#xff0c;本篇单独针对分组查询进行简单的总结和归纳&#xff0c;并为后续更为复杂的DQL 语句做好铺垫。 查询语句&#xff1a; SELECT AVG(salary) FROM teacher; 实际上是以全表的 salary 字段来求平均值。但是在实…

MySQL 基础 ———— 连接查询

引言 本篇文章承接《数据库与SQL语句》专栏&#xff0c;进入DQL的重要环节&#xff0c;可以说&#xff0c;这一部分的内容应该占据SQL语言的大部分使用场景。 本篇的连接查询知识&#xff0c;和后面的一些重要的查询知识总结&#xff0c;共同构成了在工作中80%的MySQL应用场景…

MySQL 基础 ———— 子查询

引言 承接《MySQL 基础 ———— 连接查询》&#xff0c;本文介绍和展示SQL中子查询的使用。 子查询是出现在其他语句中的select 语句&#xff0c;也称为内查询。外部的查询语句&#xff0c;称为主查询或外查询。 一、子查询的分类和支持的子句 按照子查询出现的位置&#…

MySQL 基础 ———— SQL语句的执行顺序与 LIMIT 子句

引言 到目前为止&#xff0c;已经总结了常见的SQL子句&#xff0c;包括 SELECT 、FROM、JOIN ... ON、WHERE、GROUP BY、HAVING、ORDER BY。 虽然SQL的书写顺序是固定的&#xff0c;但在MySQL引擎中执行的顺序并不完全和书写顺序一致。除了上述这些子句&#xff0c;下面将会介…

MySQL 基础———— UNION 联合查询

引言 联合查询与连接查询不同&#xff0c;通过UNION 关键字&#xff0c;我们可以将多个查询语句一同执行并将结果集展示出来&#xff0c;不涉及到任何关联关系。 UNION 的含义是“联合&#xff0c;并集&#xff0c;结合”&#xff0c;在MySQL中可以将多个查询语句的结果合并成…

MySQL 基础————常用数据类型

引言 从第一次学习mysql开始&#xff0c;不知道为什么MySQL的数据类型始终没有像Java 一样深入脑海&#xff0c;对某些数据类型的定义和用法&#xff0c;也并不清晰&#xff0c;这篇文章&#xff0c;就好好总结一番&#xff0c;将MySQL中几个常用的数据类型归纳一下。 一、类…

MySQL 基础 ———— SAVEPOINT 的应用

引言 savepoint 关键字用于在数据库事务中设置一个存储点&#xff0c;在一个较长的事务中暂存数据&#xff0c;如果在事务末尾执行回滚&#xff0c;可选择性的回滚到 savepoint 设置的暂存点。 本文承接上一篇博客《MySQL 基础 ————事务与隔离级别总结》&#xff0c;进一…

MySQL 基础 ———— 视图的应用与总结

引言 视图是一种虚拟表&#xff0c;和普通表的使用是一样的&#xff0c;视图的一大特点就是“临时性”&#xff0c;是通过表动态生成的数据&#xff0c;只保存SQL逻辑&#xff0c;不保存查询结果。 视图在实际生产中主要有两种应用场景&#xff1a; 1、多个地方用到同样的查…

MySQL 基础 ———— 变量

一、MySQL系统变量 系统变量是由系统提供&#xff0c;属于服务器层面。 系统变量分为&#xff1a;全局变量和会话变量。 全局变量一般要加 GLOBAL 关键字&#xff0c;例如在《MySQL 基础 ————事务与隔离级别总结》中提到的 GLOBAL TRANSACTION&#xff0c;就属于全局变量…

MySQL 基础 ———— 存储过程与函数

一、存储过程介绍 存储过程是一组预先编译好的SQL语句的集合&#xff0c;可理解成批处理语句。它的优点主要有以下几点&#xff1a; 1、提高代码的重用性&#xff1b; 2、简化操作&#xff1b; 3、减少了编译次数并且减少了和数据库服务器的连接次数&#xff0c;提高了效率…

MySQL 基础 ———— 流程控制结构

引言 MySQL 中的流程控制作为基础知识的最后一块拼图&#xff0c;显得并不是特别重要&#xff0c;而且&#xff0c;在实际生产开发中&#xff0c;也往往不需要通过它来进行程序的控制&#xff0c;那么为什么还要学习它呢&#xff1f;我认为有以下几点&#xff1a; 1、知识的完…

MySQL 高级 ———— MySQL逻辑架构图简介

引言 本篇文章介绍MySQL的逻辑架构图。 MySQL并不完美&#xff0c;但足够灵活&#xff0c;能够适应高要求环境。MySQL不仅可以嵌入到应用程序中&#xff0c;同时也可以支持数据仓库、内容搜索、和部署软件、高可用的冗余系统、在线事务处理系统等各种应用类型。 一、MySQL逻…

Java正则表达式总结

引言 正则表达式&#xff08;英文&#xff1a;regular expression&#xff09;是用于描述字符串规则的工具&#xff0c;是记录文本规则的代码。 它可以用来搜索、编辑、处理文本。现有编程语言都支持正则表达式的处理&#xff0c;但每种语言都有细微的差别。 在Java 中&…

Linux 实操 —— 日志筛选操作(sed与wc命令介绍)

引言 在处理数据交互业务场景的问题时&#xff0c;经常会出现需要统计日志中出现某些指定关键字的行数&#xff0c;或者行数&#xff0c;那么如何通过Linux 命令来快速统计一段时间之内&#xff0c;某个特定关键字出现的行数呢&#xff1f;这篇文章将会给你答案。 一、快速统…

Java 注解知识总结

引言 本博客总结自《Java 编程思想》第 20 章。 一、什么是注解 注解是 Java 5 引入的一种通过反射机制实现的语法特性&#xff0c;开发者可以通过在类、域、方法等元素前面标记一个“标签”达到对程序的源码、类信息或运行时进行某种说明或处理的效果&#xff0c;尽可能地简…

Linux 实操 —— Linux 系统性能分析

引言 最近配合解决压测&#xff08;性能测试&#xff09;方面的问题&#xff0c;了解到了一些可以监控 Linux 系统性能指标&#xff0c;如CPU、IO、内存等的工具。 此篇博客主要讲解 Linux 系统监控的一些重点内容以及 sar 命令的使用。 一、Linux 性能分析聚焦 Linux 性能…

Java 动态代理解析

引言 本博客总结自《Java 编程思想》第十四章 一、实现第一个动态代理程序 代理是软件设计中重要的设计思想&#xff0c;它允许我们在调用实际操作之前或之后解耦式地编写额外的操作&#xff0c;而一旦不需要这些操作了&#xff0c;就可以轻易的移除它们。 浏览了《编程思想…

MySQL 基础 ————高频函数总结

一、MySQL函数调用方式 函数调用的基本语法&#xff1a; SELECT 函数(实参列表) [FROM 表] 其中&#xff0c;对于函数&#xff0c;需要重点关注三点&#xff1a; 1、函数的名称 2、参数列表 3、函数功能 二、函数的分类 在 MySQL中&#xff0c;函数分为两类&#xff1a;1、…

MySQL 高级 —— 复合索引简介(多列索引)

引言 复合索引是指包含多个数据列的索引&#xff0c;与之概念相对的是单列索引&#xff0c;仅包含一个数据列。在大多数情况下&#xff0c;建立多列索引的好处都要多于单列索引。另外&#xff0c;复合索引最多支持16个列&#xff0c;但请一定不要让复合索引包含太多的列&#…