将自己之前的shell脚本笔记搬到segmentfault,顺带复习一下shell基础。笔记大多是读<>时所记录,推荐想学shell的可以去看看。2019-1-26

系列笔记传送门:

shell脚本介绍

Shell介绍

Shell是一个命令解释器,作用是解释执行用户输入的命令程序等,用户每输入一条命令,Shell就执行解释一条。这种从键盘输入命令就可以得到回应的方式叫做交互的方式。

Shell存在于操作系统的最外层,负责与用户直接对话,把用户的输入解释给操作系统,并处理各种操作系统的输出结果,然后输出到屏幕给用户。

Shell脚本

当命令或程序语句不在命令行下执行,而是通过一个程序文件来执行,这个文件就叫做Shell脚本。

Shell脚本很适合用于处理纯文本类型的数据,而Linux系统中几乎所有的配置文件,日志文件(NFS,Rsync,Httpd,Nginx,LVS 等),以及绝大多数的启动文件都是纯文本类型的文件。因此,学好shell语言,就可以利用它在linux系统中发挥巨大的作业。

查看CentOS系统默认的Shell

[root@moli_linux1 ~]# echo $SHELL

/bin/bash

[root@moli_linux1 ~]# grep root /etc/passwd

root:x:0:0:root:/root:/bin/bash

Shell脚本的创建和执行

Shell脚本的创建

一个规范的Shell脚本在第一行会指出由那个程序(解释器)来执行脚本的内容,这一行内容在Linux bash编程中一般为:

#!/bin/bash

或者

#!/bin/sh

注意:这一行必须位于每个脚本顶端的第一行,如果不是第一行则为脚本注释行。且shell脚本文件的后缀名通常以.sh结尾。

Shell脚本的执行

1.bash script-name(脚本的路径名字)或者sh script-name:这是当脚本文件没有可执行权限时常用的放法

2.path/script-name 或者./script-name:指在当前路径下执行脚本(脚本需要有可执行权限)。即需要将脚本文件的权限先修改为可执行,chmod +xscript-name。然后通过脚本的绝对路径和相对路径就可以直接执行脚本。

shell脚本中的变量

什么是变量

变量是暂时存储数据的地方及数据标记,所存储的数据存在于内存空间中,通过正确地调用内存空间中变量的名字就可以取出与变量对应的数据。CentOS中变量的定义直接由一个赋值符号=就可以创建一个变量,而echo命令类似于其他语言的print命令,打印这个变量的值。

[root@moli_linux1 ~] name="laowan" #定义一个变量

[root@moli_linux1 ~] echo $name #打印这个变量的值

laowan

[root@moli_linux1 ~] age=14

[root@moli_linux1 ~] echo $age

14

shell变量的特性

默认情况下,在bash shell 中是不会区分变量类型的。

变量类型

变量分为:环境变量(全局变量)和普通变量(局部变量)

环境变量可以在创建它们的shell以及其派生出来的任意子进程shell中使用。环境变量又分为自定义环境变量和bash内置的环境变量。

普通变量只能在创建它们的shell函数或shell脚本中使用。

提示:有三个命令可以查看系统中变量的值:set、env、declare。

set命令输出所有的变量;

env只显示全局变量;

declare命令输出所有的变量,函数,整数和已经导出的变量。

set -o命令显示bash shell的所有参数配置信息。

环境变量的定义

上面定义一个变量是在一个shell中直接使用赋值符号对这个变量进行创建,但是当打开一个新的子shell,打印这个变量却不能打印出来。这是因为我们创建的变量是一个普通变量,若想在其他子shell中使用这个变量,需要将这个变量设置为全局变量。而定义一个全局变量的方法如下:

export 变量名=value

或者

declare -x 变量名=value

第二个方法是将变量名添加到环境变量文件/etc/profile

编辑环境配置文件

vim /etc/profile

在文件最后面添加

export name="laowan"

保存,退出。重新加载文件

source /etc/profile

打印变量的值

echo $name

laowan

而CentOS中,全局环境变量的配置文件有三个,分别是:

/etc.profile

/etc/bashrc

/etc/profile.d #这是一个目录

当用户登录Linux系统时,首先会先加载/etc/profile全局环境变量文件,这是Linux系统默认的Shell主配置文件,其次会执行/etc/profile.d下的脚本文件,要做重启Linux系统后初始化或者显示某些内容,只需要把脚本文件放在/etc/progile.d下即可,最后才会执行bashrc文件。

设置登录提示符

Linux中可以设置登录之后,或者远程连接服务器打开的shell中显示登录提示符。设置登录提示内容的文件是/etc/motd,编辑这个文件就可以设置每次登录提示的内容。例如:

[root@moli_linux1 ~]# cat /etc/motd

welcome to my Linux Server!

打开一个新的shell

Connecting to 192.168.30.3:22...

Connection established.

To escape to local shell, press 'Ctrl+Alt+]'.

WARNING! The remote SSH server rejected X11 forwarding request.

Last login: Sat Jan 26 19:35:54 2019 from 192.168.30.1

welcome to my Linux Server!

可以看到登录提示符。

定义变量不加单引号和双引号,加单引号,加双引号的区别

[root@moli_linux1 ~] a=10

[root@moli_linux1 ~] b=10-$a

[root@moli_linux1 ~] c='100-$a'

[root@moli_linux1 ~] d="100-$a"

[root@moli_linux1 ~] echo $a

10

[root@moli_linux1 ~] echo $b

10-10

[root@moli_linux1 ~] echo $c

100-$a

[root@moli_linux1 ~] echo $d

100-10

第一种定义b变量的方式,当内容为简单连续的数字,字符串,路径名时,可以这样用,不加引号时,值里有变量的会被解析后输出。

第二种定义c的变量有加单引号,这样输出变量时单引号里面内容是什么就是什么,即使有变量和命令也是直接输出。

第三种定义d变量的方式加了双引号,这种输出变量内容时引号里的变量以及命令会经过解析后再输出内容,这种方式比较适合字符串中附带有变量以及命令且想将其解析后再输出的变量定义。

取消变量

取消变量使用unset命令,注意要取消的变量之前不用添加$符号。

[root@moli_linux1 ~] a=100

[root@moli_linux1 ~] echo $a

100

[root@moli_linux1 ~] unset a

[root@moli_linux1 ~] echo $a #可以看到这个变量的为空

[root@moli_linux1 ~]#

将一个命令的结果赋值给一个新的变量

生产环境中把命令的结果作为变量的内容进行赋值的方法在脚本开发时很常见。有两个方法可以实现。

变量名=$(命令)

或者:

变量名=`命令`

[root@moli_linux1 ~] ls

192.168.229 anaconda-ks.cfg git_data server shell-100 test-find

[root@moli_linux1 ~] file=$(ls)

[root@moli_linux1 ~] echo $file

192.168.229 anaconda-ks.cfg git_data server shell-100 test-find

[root@moli_linux1 ~] file2=`ls`

[root@moli_linux1 ~] echo $file2

192.168.229 anaconda-ks.cfg git_data server shell-100 test-find

Shell中的特殊位置变量

shell中特殊位置参数变量

要从命令行,函数或脚本执行等处传递参数时,就要在shell脚本中使用位置参数变量。

$0 :获取当前执行的shell脚本的文件名,如果执行脚本包含了路径,那么就包括脚本路径

$1:获得当前执行的shell脚本的第n个参数值,n=1.......9,当n为0时表示脚本的文件名,当n大于9时,则用大括号括起来,例如$(10),接的参数以空格隔开

$# : 获取当前执行的shell脚本后面接的参数的总个数

$* :获取当前Shell脚本所有传参的参数,不加引号和$@相同,如果给$*加上双引号,例如“$*”,则表示将所有的参数视为单个字符串,相当于“$1$2$3”

#@ :获取当前shell脚本所有传参的参数,不加引号和$*相同;如果给$@加上双引号,例如:“$@”,则表示将所有的参数视为不同独立的字符串,相当于“$1","$2"."$3”....这是将多参数传递给其他程序的最佳方式。

示例1,特殊位置变量$1

[root@moli_linux1 script] cat test.sh

#!/bin/bash

echo $1 #脚本的功能是打印脚本传递的第一个参数的值

[root@moli_linux1 script] sh test.sh laowan #传入一个字符串参数,赋值给$1

laowan

[root@moli_linux1 script] sh test.sh laowan xiaoming #传入多个参数,但脚本不会接收多个参数,因此只输出第一个参数的值

laowan

[root@moli_linux1 script] sh test.sh "I am laowan" #用双引号括起来代表一个参数

I am laowan

示例2,特殊位置变量$1,$2,$3....${10}

[root@moli_linux1 script] echo \${1..15} > test2.sh

[root@moli_linux1 script] cat test2.sh

#!/bin/bash

echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15

[root@moli_linux1 script] sh test2.sh {a..z} #传入26个字母a~z,作为26个参数

a b c d e f g h i a0 a1 a2 a3 a4 a5 #位置参数的数字大于9后,输出内容就不对了

[root@moli_linux1 script] vim test2.sh

[root@moli_linux1 script] cat test2.sh

#!/bin/bash

#位置参数的数字大于9时,需要用大括号将数字括起来

echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}

[root@moli_linux1 script] sh test2.sh {a..z}

a b c d e f g h i j k l m n o #大于9的数字加上大括号后显示正确的内容

示例3,特殊变量$0--获取脚本的名称以及路径:

[root@moli_linux1 shell_test] cat 05-getName.sh

#!/bin/bash

echo $0

[root@moli_linux1 shell_test] sh 05-getName.sh

05-getName.sh

示例4,$#获取脚本传递参数个数:

[root@moli_linux1 shell_test] cat 06-getNum.sh

#!/bin/bash

echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9

echo $# #传递的参数个数

[root@moli_linux1 shell_test] ./06-getNum.sh {a..z} #传递了26个字母,即26个参数

./06-getNum.sh a b c d e f g h i #接受了9个参数,因此打印9个字母

26 #传递了26个参数,打印出26

示例5,$#的常见实际应用

根据用户在命令行传参的个数判断用户的输入,不符合的给出提示并退出,符合的打印出传入的参数内容。

[root@moli_linux1 shell_test] cat t1.sh

#!/bin/bash

if [ $# -ne 2 ] #如果执行脚本传参的个数不等于2

then

echo "USAGE:/bin/sh $0 arg1 arg2" #则给用户提示正确的用法,此处$0,打印脚本名字和路径

exit 1 #不满要求,则退出脚本,返回值为1

fi

echo $1 $2 #符合要求,则打印$1 $2所获取到的传参的字符串

[root@moli_linux1 shell_test] sh t1.sh arg1 agr2 #符合传参个数=2,打印出传入参数的内容

arg1 agr2

[root@moli_linux1 shell_test] sh t1.sh arg1 agr2 arg3 #不符合传参个数=2,给出提示并退出

USAGE:/bin/sh t1.sh arg1 arg2

Shell中特殊状态变量

$? : 获取执行上一个指令的执行状态返回值(0为成功,非0为失败),这个变量最常用。

$$ : 获取当前执行的shell脚本的进程号(PID),不常用。

$! : 获取上一个在后台工作的进程号(PID),不常用。

$_ : 获取在此之前执行的命令或脚本的最后一个参数,不常用。

$?的实践1

[root@moli_linux1 ~] pwd #执行pwd获取当前路径,用echo $?查看执行命令的状态返回值

/root

[root@moli_linux1 ~] echo $?

0 #返回0表示上一条命令执行成功

[root@moli_linux1 ~] rm shell_test/ #删除目录shell_test

rm: 无法删除"shell_test/": 是一个目录 #没加参数-r ,无法删除

[root@moli_linux1 ~] echo $?

1 #状态码非0,表示上一条执行不成功或者错误

$?的实践2

[root@moli_linux1 ~] cat test1.sh

#!/bin/bash

[ $# -ne 2 ] && { #如果参数个数不=2

echo "must be two args." #则输出提示

exit 119 #终止程序并以指定的119状态码退出程序,赋值给当前shell的“$?”变量。

}

echo "success!"

[root@moli_linux1 ~]# sh test1.sh 1 2 3 #参数个数不=2

must be two args.

[root@moli_linux1 ~]# echo $?

119 #状态码为119

"$?"的注意点:

判断命令,脚本或函数等程序是否执行成功。常用于源码编译安装软件,在每个步骤获 取“$?”的状态码来判断命令执行是否成功。

若是在脚本中调用执行"exit 数字",则会返回这个数字给"$?"变量。

如果是在函数里,通过"return 数字"把这个数字以函数返回值的形式传给"$?"。

Shell变量字串

变量字串表达式

表达式

说明

${parameter}

返回变量${parameter}的内容

${#parameter}

返回变量${parameter}内容的长度(按字符)

${parameter:offset}

在变量${parameter}的内容中,从位置offset之后开始提取字串到结尾

${parameter:offset:length}

在变量${parameter}中,从位置offset之后开始提取长度为length的字串

${parameter#word}

从变量${parameter}开头开始删除最短匹配的word字串

${parameter##word}

从变量${parameter}开头开始删除最长匹配的word字串

${parameter%word}

从变量${parameter}结尾开始删除最短匹配的word字串

${parameter%%word}

从变量${parameter}结尾开始删除最短匹配的word字串

${parameter/pattern/string}

使用string替换第一个匹配的pattern

${parameter//pattern/string}

使用string替换所有匹配的pattern

单独一个“#”:表示从开头删除最短匹配

两个“##”:表示从开头删除最长匹配

一个“%”:表示从结尾开始删除最短匹配

两个“%%”:表示从结尾开始删除最长匹配

一个“/”:表示替换第一个

两个“//”:表示替换所有

示例1,变量的打印和提取切片:

# 定义变量parameter,内容为abc123ABC456

[root@moli_linux1 script]# parameter="abc123ABC456"

# 变量的两种打印方式

[root@moli_linux1 script]# echo $parameter

abc123ABC456

[root@moli_linux1 script]# echo ${parameter}

abc123ABC456

# 打印这个变量内容的长度,一共12个字符

[root@moli_linux1 script]# echo ${#parameter}

12

# 从变量内容的第三个开始,提取剩下的所有内容

[root@moli_linux1 script]# echo ${parameter:3}

123ABC456

# 从变量内容的第三个开始,提取接下来的6个字符

[root@moli_linux1 script]# echo ${parameter:3:6}

123ABC

示例2,变量的截取与替换:

# 定义变量,mori

[root@moli_linux1 script]# echo $mori

abc123ABC456abc

# 从开头删除了最短的a*c字串为abc

[root@moli_linux1 script]# echo ${mori#a*c}

123ABC456abc

# 从开头删除了最长的a*c字串为abc123ABC456abc,全部删除了

[root@moli_linux1 script]# echo ${mori##a*c}

[root@moli_linux1 script]#

# 从左到右将第一个遇到的小写a替换为大写A

[root@moli_linux1 script]# echo ${mori/a/A}

Abc123ABC456abc

# 将变量里所有的小写a替换为大写A

[root@moli_linux1 script]# echo ${mori//a/A}

Abc123ABC456Abc

linux shc shell脚本_Linux运维 | Shell脚本(1)相关推荐

  1. linux yum自动挂载_Linux运维——升级系统相关漏洞

    说明:最近公司漏扫部门扫出来一大批的漏洞,包括系统层.中间件层.以及应用层漏洞,今天先给大家分享下Linux系统层漏洞修复方案(OpenSSL.ssh.NTP等),请看下面! 一.上传升级包: 二.配 ...

  2. linux ssh yum升级_Linux 运维必备的 13 款实用工具,拿好了

    作者丨Erstickt http://blog.51cto.com/13740508/2114819 本文介绍几款 Linux 运维比较实用的工具,希望对 Linux 运维人员有所帮助. 1. 查看进 ...

  3. linux jdk安装_linux运维 - 用脚本快速安装jdk

    安装 jdk 需要先到 oracle 官网下载对应的压缩包,放到跟脚本同一个目录,然后执行脚本即可. jdk 归档版本 直接到oracle官网直接查找,一般都是展示最新版本的JDK,如果需要之前的版本 ...

  4. linux运维脚本编写,最强Linux自动化运维 Shell高级脚本编程实战 带习题+项目实战案例+全套配置脚本...

    最强Linux自动化运维 Shell高级脚本编程实战 带习题+项目实战案例+全套配置脚本 大家可以通过参考下面的课程学习目录,就会发现单单只从目录上来分析就知道这是一部非常系统的Shell自动化脚本运 ...

  5. linux运维自动化脚本,linux运维自动化shell脚本小工具

    linux运维shell 脚本小工具,如要分享此文章,请注明文章出处,以下脚本仅供参考,若放置在服务器上出错,后果请自负 1.检测cpu剩余百分比 #!/bin/bash #Inspect CPU # ...

  6. 整理全网Shell脚本合集,Java脚本,运维脚本,告警脚本,监控脚本,日志脚本,docker脚本等---------持续更新!

    整理全网Shell脚本合集,Java脚本,运维脚本,告警脚本,监控脚本,日志脚本,docker脚本等---------持续更新! 一.ffmpeg脚本 1.1 打开进程,并判断进程数量 1.2 关闭进 ...

  7. 自动化运维Shell课堂笔记

    1.课程回顾 2.课程大纲 1.shell编程 开发和运维 shell基础知识 shell变量 shell表达式 shell流程控制语句 2.代码发布 项目周期 代码部署的方式 代码部署流程 服务器环 ...

  8. shell编程与运维

    shell编程与运维 一.Shell脚本概述 通过shell中的各种命令,开发者和运维人员可以对服务器进行维护工作. 但每次都手动输入命令,工作效率太低,而且很容易出错,尤其是需要维护大量服务器时. ...

  9. python linux运维教程 推荐_Linux 运维入门到跑路书单推荐

    一.基础入门 <鸟哥的Linux私房菜基础学习篇>:最具知名度的Linux入门书<鸟哥的Linux私房菜基础学习篇>,全面而详细地介绍了Linux操作系统.鸟哥的Linux私房 ...

最新文章

  1. ​脑机技术可以应用于军事领域,有助于评估士兵的认知状态
  2. 如何安全设置无线路由
  3. GraphPad轻松绘制配对比较图和双向柱状图
  4. Android 开发笔记——通过 Intent 传递类对象
  5. 【渝粤教育】国家开放大学2018年秋季 1320T关系营销 参考试题
  6. MySQl Got a packet bigger than ' max_allowed_packet' bytes
  7. java websocket ie8_websocket兼容IE8
  8. 论述计算机与外设的访问控制方法,试论述计算机与外设访问控制的方法有多少种各有什么优缺点...
  9. magento2 常用代码
  10. C# 缓存学习第一天
  11. 长焦拍照对比:小米10至尊纪念版和一加8 Pro、vivo X50 Pro+~~~~
  12. 论文阅读——基于语法语义融合学习的功能代码克隆检测
  13. Vivado中FIFO遇到【Common17-55】警告总结
  14. 职业作秀V1.7.9更新公告
  15. 分享Qt多工程多目录的编译案例,subdirs
  16. jbpm 历史查询笔记
  17. ORA-10458 ORA-01157 ORA-01111
  18. Windows窗体应用程序~随机数字抽奖系统
  19. 史上最简单笔记本选购攻略(给对笔记本配置完全不懂的小白,建议收藏)
  20. 测试人生 | 从底薪助理4.5k转行到软件测试工程师月薪13k,妹子成功逆袭

热门文章

  1. C语言实验指导 P20 齿轮啮合
  2. Axure如何制作app底部弹框,固定在底部
  3. Java实现GTA5自动抽车,提高中奖概率
  4. maxpermsize java_关于java:-XX:MaxPermSize带有或不带有-XX:PermSize
  5. 前端拼音检索-【pinyin-match】
  6. 树莓派SSH无法连接——22号端口能ping通,但不能连接
  7. 微信小程序中bindtap和catchtap
  8. Redis锁简单实现
  9. 洁净工程无尘车间设计方案
  10. 删除个人空间动态(哔哩哔哩)