您现在的位置是:首页 > 正文

Linux中的Shell编程

2024-01-30 20:30:15阅读 0

Linux中的Shell编程

shell编程快速入门

为什么要学习Shell编程?
1.Linux运维工程师在进行服务器集群管理时,需要编写Shell程序来进行服务器管理。
2.对于JavaEE和Python程序员来说,工作的需要,你的老大会要求你编写一些Shell脚本进行程序或者是服务器的维护,比如编写一个定时备份数据库的脚本。
3.对于大数据程序员来说,需要编写Shell程序来管理集群。

Shell是什么?
Shell 是一个命令解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。
在这里插入图片描述

Shell编程快速入门?
进入Linux终端,编写一个 Shell 脚本 hello.sh :

#!/bin/bash 
echo 'hello world!'

在这里插入图片描述

使用vim命令可以直接创建并编写一个文件。如下图:
在这里插入图片描述

运行:

# 方法1
sh hello.sh

# 方法2
sudo chmod +x hello.sh
./hello.sh

在这里插入图片描述
在这里插入图片描述
从上面的两张图片中可以看出,每种方式都会成功输出hello world!

说明:

  • #! 告诉系统这个脚本需要什么解释器来执行。
  • 文件扩展名 .sh 不是强制要求的。
  • 方法1 直接运行解释器,hello.sh 作为 Shell 解释器的参数。此时 Shell 脚本就不需要指定解释器信息,第一行可以去掉。
  • 方法2 hello.sh 作为可执行程序运行,Shell 脚本第一行一定要指定解释器。

Shell变量

定义
Shell 变量分为系统变量自定义变量。系统变量有$HOME, $PWD, $USER等,如下图:
在这里插入图片描述
像上面这些都是系统变量,我们可以通过set显示所有的系统变量,如下图:
在这里插入图片描述
比如我们还可以输出一下系统变量BASH的值,如下图:
在这里插入图片描述

像上面都是linux当中的系统变量,但在linux中我们用的比较多的还是自定义变量,自定义变量的基本语法

  • 定义变量:变量名=变量值,等号两侧不能有空格,变量名一般习惯用大写
  • 删除变量:unset 变量名 。
  • 设置只读变量:readonly 变量名,相当于设置了只读,其实也就是说变量值第一次设置之后后续就不能修改了。
  • 使用变量:$变量名

定义一个shell脚本test2.sh测试变量的使用,如下图:
在这里插入图片描述
执行shell脚本的结果如下图:
在这里插入图片描述
还有一个点需要注意一下,当我使用sh test2.sh执行shell脚本的时候,第二个B变量没有输出出来,如下图:
在这里插入图片描述
因此使用./test2.sh命令执行shell脚本,要比使用sh test2.sh命令执行脚本要强大的,以后尽量使用./test2.sh的方式执行shell脚本。

位置参数变量

基本语法

  • $n:$0代表的是命令本身、$1-$9代表从第1个参数到第9个参数,10以上参数用花括号 ${10}
  • $*:命令行所有参数,且把所有参数看成一个整体
  • $@:命令行中所有参数,且把每个参数区分对待
  • $#:所有参数个数

实例如下图:
在这里插入图片描述
执行test5.sh这个shell脚本的结果如下图:
在这里插入图片描述
注意$0的时候并不会把参数也输出。

运算符

基本语法

  • $((运算式))或 $[运算式]
  • expr m + n 注意expr运算符间需要有空格,如果希望将expr的结果赋值给某个变量,需要使用反引号,如TEMP=`expr 2 + 3`
  • expr \* , /, %分别代表乘,除和取余,注意这里的乘的符号比较特殊

定义一个test3.sh案例如下:
在这里插入图片描述
执行test3.sh这个shell脚本的结果,如下图:
在这里插入图片描述

条件判断

基本语法

# [ condition ] 注意condition前后要有空格。非空返回0,0为true,否则为false。
# 可能出现的情况大致如下
if [ 条件表达式 ]
then
	程序
fi

if [ 条件表达式 ]
then
	程序
else
	程序
fi

if [ 条件表达式 ]
then
	程序
elif [ 条件表达式 ]
then
	程序
else
	程序
fi

编写一个test4.sh例子,如下图:
在这里插入图片描述
运行test4.sh这个shell脚本的结果如下图:
在这里插入图片描述

case分支

基本语法

case $变量名 in

值1)
程序1
;;

值2)
程序2
;;

值3)
程序3
;;

*)
如果变量值不等于上面列出的所有列,则执行此处程序
;;

esac

例子如下图:
在这里插入图片描述
测试test6.sh这个shell脚本的执行结果,如下图:
在这里插入图片描述

for循环

基本语法

# 语法1
for 变量名 in 值1 值2 值3...
do
	程序
done


# 语法2
for ((i=1;i<=100;i++)
do
	程序
done

实例如下图:
在这里插入图片描述
test7.sh这个shell脚本的运行结果如下图:
在这里插入图片描述

while循环

基本语法

while [ 条件判断式 ]
do
	程序
done

实例输出1加到100的值,如下图:
在这里插入图片描述
test8.sh这个shell脚本文件执行结果如下图:
在这里插入图片描述

函数

和其它编程语言一样,Shell 编程有系统函数和自定义函数。

系统函数
第一个系统函数是basename函数,这个函数可获取绝对路径下面最后面的文件名字;
第二个系统函数是dirname函数,这个函数可获取绝对路径下文件的路径,其实也就是去掉了后面的文件名字;
使用如下图:
在这里插入图片描述
一个是用来获取文件名,一个是用来获取文件的项目路径。

自定义函数
基本语法

function funcname(){
	Action;
	[return int;]
}

实例如下图:
在这里插入图片描述
执行test9.sh这个shell脚本的结果如下图:
在这里插入图片描述

shell编程里面的函数可以加参数吗?
与大部分编程语言不同,Shell 中函数在定义时不能指定参数,但在调用时可以传递参数。传递参数给函数:在函数名后面以空白分隔给定参数列表即可,如:testfunc arg1 arg2 … ; 在函数体中当中,可使用$1, 2 , … 调用这些参数;还可以使用 2, …调用这些参数;还可以使用 2,调用这些参数;还可以使用@, $*, $#等特殊变量。

函数后面传递参数的例子,如下图:
在这里插入图片描述
接着执行我们的test10.sh这个shell脚本,看看执行结果是什么,如下图:
在这里插入图片描述

nohup命令

基本概念

nohup 命令 用途:不挂断地运行命令。
语法:nohup Command [ Arg … ] [ & ]
描述:nohup 命令运行由Command 参数和任何相关的Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用nohup 命令运行后台中的程序。要运行后台中的nohup 命令,添加& ( 表示”and”的符号)到命令的尾部。

nohup指不断地运行,是no hup up的缩写,指不间断,不挂断。运行一个进程的时候,不想让其在你退出账号时关闭,即可用nohup。什么意思呢?就是使用nohup在linux上启动一个部署的项目之后,即便你退出重新登录linux服务器了,服务器上面的项目也是启动状态的,不用你重新启动了就。

个人理解:先理解成nohup是用来运行程序jar包的,如果我们想要在windows上面启动一个程序,那么我们直接在idea里面点运行就行了,但是在linux上面我们如果想要启动一个程序要怎么办呢?可以直接使用命令 java -jar 程序jar包,如下图:
在这里插入图片描述
可以发现我们启动的时候启动参数错了,这是为什么呢?来看一下我们启动主类中的代码,如下图:
在这里插入图片描述
那么我们启动程序的时候怎么配置启动参数呢?以及JVM的启动参数堆内存栈内存等?可以使用nohup进行启动,在命令后面直接跟上启动参数就行了,如下图:
在这里插入图片描述

当上面的shell脚本启动之后,就可以在linux上面启动我们的程序了。因此,shell脚本在linux上面可以用来启动linux上面部署的项目。

使用eval命令把其中一个文件里面的配置输出到另外一个shell脚本的变量里面

首先我们创建一个file.txt文件,内容如下图:
在这里插入图片描述
接下来我们在shell脚本里面可以通过eval命令直接把这个文件中的变量输入到shell脚本对应的变量中,我们创建一个test9.sh脚本,内容如下图:
在这里插入图片描述
当我们执行上面的shell脚本的时候,输出的三个变量值,其实就是我们在file.txt文件里面定义的三个变量值,输出结果如下图:
在这里插入图片描述
可以发现这里脚本执行的结果是和file.txt文件中配置的信息一致的。

特别注意shell脚本里面不要关闭其它web项目的进程

使用shell脚本启动一个项目的时候,如果当前项目已经启动了,那么需要先查出来当前项目的进程号id,然后把这个进程杀死;注意查询进程id的时候,要加上当前项目的特征,比如可以在grep后面直接加上当前项目的jar包,用来进行筛选,如下图:
在这里插入图片描述
使用 ps -ef | grep 你的项目特征 | grep -v grep | awk ‘{print $2}’ 命令可以筛选出来你的项目的进程号,如下图:
在这里插入图片描述

网站文章

  • 批量重命名文件、图片、去除文件名括号

    批量重命名文件、图片、去除文件名括号

    批量重命名文件、图片、去除文件名括号

    2024-01-30 20:30:10
  • Google面试问题指南:使用Python删除重复出现的字符

    Google面试问题指南:使用Python删除重复出现的字符

    来源 | 愿码(ChainDesk.CN)内容编辑愿码Slogan | 连接每个程序员的故事网站 | http://chaindesk.cn愿码愿景 | 打造全学科IT系统免费课程,助力小白用户、初级工程师0成本免费系统学习、低成本进阶,帮助BAT一线资深工程师成长并利用自身优势创造睡后收入。官方公众号 | 愿码 | 愿码服务号 | 区块链部落免费加入愿码全思维工程师社群 | 任一...

    2024-01-30 20:29:35
  • 装饰者模式

    装饰者模式

    设计模式:专门为解决某一类问题,而编写的固定格式的代码。装饰者模式一、职责1、动态的为一个对象增加新的功能2、装饰模式是一种用于替代继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。二、实现细节1、Component抽象构件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实...

    2024-01-30 20:29:29
  • JVM内存布局

    JVM内存布局

    Survivor区分为S0和S1两块内存空间,每次YGC时,它们将存活的对象复制到未使用的那块空间,然后将当前正在使用的空间完全清除,交换两块空间的使用状态。当大量本地方法出现时,势必会削弱JVM对系...

    2024-01-30 20:29:22
  • css固定定位

    css固定定位

    主要使用场景:可以在浏览器页面滚动元素时元素的位置不会改变。1、以浏览器的可视窗口作为参考点移动元素。4、不占有固定位置,浮起来了。3、不随滚动条的滚动而变化。2、和父元素没有关系。

    2024-01-30 20:28:51
  • 使用jQuery的ajax上传文件报错:Uncaught TypeError: Illegal invocation

    使用ajax上传文件,代码如下:$('#video-upload-btn').on('change', function(){ var file = this.files[0]; var data =...

    2024-01-30 20:28:44
  • Java代码审计之RCE(远程命令执行)

    Java代码审计之RCE(远程命令执行)

    Java代码审计系列课程(点我哦)漏洞原理:RCE漏洞,可让攻击者直接向后台服务器远程注入操做系统命令或者代码,从而控制后台系统。出现此类漏洞通常由于应用系统从设计上须要给用户提供指定的远程命令操做的...

    2024-01-30 20:28:37
  • Android面试题集-常见几个面试题详解

    Android面试题集-常见几个面试题详解

    跳槽,这在 IT 互联网圈是非常普遍的,也是让自己升职加薪,走上人生巅峰的重要方式。那么作为一个普通的Android程序猿,我们如何才能斩获大厂offer 呢? 疫情向好、面试在即,还在迷茫踌躇中的后...

    2024-01-30 20:28:06
  • 使用EasyExcel实现上传解析与导出下载

    使用EasyExcel实现上传解析与导出下载

    使用指南:https://www.yuque.com/easyexcel/doc/easyexcel 环境:jdk1.8、SpringBoot 2.2.2 准备工作: pom.xml 添加依赖jar包...

    2024-01-30 20:27:57
  • AF_INET 和PF_INET区别;AF_LOCAL PF_LOCAL 区别.

    从字面理解: AF_INET = Address Format, Internet = IP Addresses PF_INET = Packet Format, Internet = IP, TCP/IP or UDP 从linux的定义来看,两者无区别。 /* Supported address families. */#define AF_UNSPEC 0#define AF_UNI...

    2024-01-30 20:27:55