把你之前的shell脚本笔记移到segmentfault,顺便复习一下shell基础知识。大部分笔记是在看《跟老男孩学Linux运维:Shell编程实站》时记录的。推荐想学shell的可以去看看。2019-1-26系列笔记传送门:Linux运维:Shell(一)Linux运维:Shell(二)Linux运维:Shell(三)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~]#greproot/etc/passwdroot:x:0:0:root:/root:/bin/bashShell脚本shell脚本的创建和执行一个标准的shell脚本的创建会在第一行指明要执行脚本内容的程序(解释器)。在Linuxbash编程中,这一行的内容一般是:#!/bin/bash或#!/bin/sh注意:这一行必须是每个脚本开头的第一行,如果不是第一行,它是一个脚本注释行。而shell脚本文件的后缀通常以.sh结尾。Shell脚本的执行1.bashscript-name(脚本的路径名)或shscript-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$age14shellvariable特性默认情况下,bashshell中不区分变量类型。变量类型变量分为:环境变量(全局变量)和普通变量(局部变量)。环境变量可以在创建它们的shell和从它派生的任何子进程shell中使用。环境变量分为自定义环境变量和bash内置环境变量。普通变量只能在创建它们的shell函数或shell脚本中使用。提示:查看系统变量值的命令有3个:set、env、declare。set命令输出所有变量;env只显示全局变量;declare命令输出所有变量、函数、整数和导出的变量。set-o命令显示bashshell的所有参数配置信息。环境变量的定义上面的变量定义是在一个shell中直接使用赋值符号创建变量,但是当打开一个新的子shell时,这个变量是无法打印出来的。这是因为我们创建的变量是一个普通变量。如果你想在其他子shell中使用这个变量,你需要将这个变量设置为全局变量。定义全局变量的方法如下:exportvariablename=valueordeclare-xvariablename=value第二种方法是将变量名添加到环境变量文件/etc/profile编辑环境配置文件vim/etc/profile在文件末尾添加exportname="laowan"保存退出。重新加载文件source/etc/profile打印变量的值echo$namelaowan在CentOS中,全局环境变量的配置文件有3个,分别是:/etc.profile/etc/bashrc/etc/profile.d#Thisisa目录当用户登录Linux系统时,首先会加载/etc/profile全局环境变量文件,这是Linux系统默认的shell主配置文件,然后是/etc/profile下的脚本文件。d会被执行,重启Linux系统在初始化或者显示一些内容后,只需要将脚本文件放到/etc/progile.d下,最后执行bashrc文件即可。设置登录提示在Linux中,可以设置登录提示在登录后远程连接服务器打开的shell中显示。设置登录提示内容的文件是/etc/motd。编辑该文件可以设置每次登录的提示内容。例如:[root@moli_linux1~]#cat/etc/motd欢迎来到我的Linux服务器!打开一个新的shell连接到192.168.30.3:22...已建立连接。要退出到本地shell,请按“Ctrl+Alt+]”。警告!远程SSH服务器拒绝了X11转发请求。上次登录:2019年1月26日星期六19:35:54来自192.168.30.1欢迎来到我的Linux服务器!您可以看到登录提示。定义变量不加单引号和双引号、加单引号、加双引号的区别[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$a10[root@moli_linux1~]echo$b10-10[root@moli_linux1~]echo$c100-$a[root@moli_linux1~]echo$d100-10第一种定义变量b的方式,当内容是简单的连续数字、字符串或路径名时,可以这样使用。没有引号时,解析后输出的值中会有变量。第二种用单引号定义c的变量,这样输出变量的时候,单引号里面是什么就是什么,即使有变量和命令也直接输出。定义d变量的第三种方法是添加双引号。输出变量内容时,会解析引号中的变量和命令,然后输出内容。这种方法比较适用于带有变量和命令的字符串,并希望将它们转换为解析后输出的变量定义。要取消变量,请使用unset命令取消变量。请注意,不需要在要取消的变量前添加$符号。[root@moli_linux1~]a=100[root@moli_linux1~]echo$a100[root@moli_linux1~]unseta[root@moli_linux1~]echo$a#可以看到这个变量为空[root@moli_linux1~]#将命令的结果赋值给一个新的变量在脚本开发中,将命令的结果赋值给生产环境中变量的内容的方法是很常见的。有两种方法可以实现这一点。变量名=$(command)或者:变量名=`command`[root@moli_linux1~]ls192.168.229anaconda-ks.cfggit_dataservershell-100test-find[root@moli_linux1~]file=$(ls)[root@moli_linux1~]echo$file192.168.229anaconda-ks.cfggit_dataservershell-100test-find[root@moli_linux1~]file2=`ls`[root@moli_linux1~]echo$file2192.168.229anaconda-ks.cfggit_dataservershell-100test-findShellshell中的特殊位置变量shell中的特殊位置参数变量为了从命令行、函数或脚本执行等传递参数,shell脚本中使用了位置参数变量。$0:获取当前正在执行的shell脚本的文件名,如果正在执行的脚本包含路径,则包含脚本路径$1:获取当前正在执行的shell脚本的第n个参数值,n=1…….9、当n为0时,表示脚本的文件名;当n大于9时,用花括号括起来,如$(10),后面的参数用空格隔开$#:获取当前执行的如下shell脚本参数总数$*:获取所有当前shell脚本传递的参数,不带引号的和$@一样,如果给$*加上双引号,比如"$*",表示把所有的参数都当成一个String,相当于"$1$2$3"#@:获取当前shell脚本传递的所有参数,不带引号,与$*相同;如果给$@加上双引号,例如:"$@",则表示将把所有参数都当作单独的字符串处理,相当于"$1","$2","$3"......这样是将多个参数传递给其他程序的最佳方式。例1、特殊位置变量$1[root@moli_linux1script]cattest.sh#!/bin/bashecho$1#脚本的作用是打印脚本传递的第一个参数的值[root@moli_linux1script]shtest.shlaowan#输入一个字符串参数赋值给$1laowan[root@moli_linux1script]shtest.shlaowanxiaoming#输入多个参数,但是脚本不会接收多个参数,所以只输出第一个参数的值laowan[root@moli_linux1script]shtest.sh"Iamlaowan"#用双引号括起来代表一个参数Iamlaowan例2,特殊位置变量$1,$2,$3....${10}[root@moli_linux1脚本]echo\${1..15}>test2.sh[root@moli_linux1脚本]cattest2.sh#!/bin/bashecho$1$2$3$4$5$6$7$8$9$10$11$12$13$14$15[root@moli_linux1script]shtest2.sh{a..z}#传入26个字母a~z,作为26个参数abcdefghia0a1a2a3a4a5#当位置参数的个数大于9时,输出内容错误[root@moli_linux1script]vimtest2.sh[root@moli_linux1script]cattest2.sh#!/bin/bash#position参数的个数大于9时需要用大括号括起来echo$1$2$3$4$5$6$7$8$9${10}${11}${12}${13}${14}${15}[root@moli_linux1script]shtest2.sh{a..z}abcdefghijklmno#Addbraces对于大于9的数字显示正确内容例3后,特殊变量$0--获取脚本的名称和路径:[root@moli_linux1shell_test]cat05-getName.sh#!/bin/bashecho$0[root@moli_linux1shell_test]sh05-getName.sh05-getName.sh例4、$#获取脚本传递的参数个数:[root@moli_linux1shell_test]cat06-getNum.sh#!/bin/bashecho$0$1$2$3$4$5$6$7$8$9echo$##传入的参数个数[root@moli_linux1shell_test]./06-getNum.sh{a..z}#pass传递了26个字母,即26个参数./06-getNum.shabcdefghi#接受了9个参数,所以打印9个字母26#传递了26个参数,打印了26例5,$#的常见实际应用根据用户在命令行传递的参数个数判断用户的输入。如果不匹配,则给出提示并退出,如果匹配,打印出传入参数的内容。[root@moli_linux1shell_test]catt1.sh#!/bin/bashif[$#-ne2]#如果脚本传递的参数个数不等于2则echo"USAGE:/bin/sh$0arg1arg2"#会提示用户正确使用,这里$0,打印脚本名称和路径exit1#不满足要求,则退出脚本,返回值为1fiecho$1$2#满足要求,则打印$1传递的参数串$2[root@moli_linux1shell_test]sht1.sharg1agr2#满足传递的参数个数=2,打印出传入参数的内容arg1agr2[root@moli_linux1shell_test]sht1.sharg1agr2arg3#不满足传参个数=2,提示退出USAGE:/bin/sht1.sharg1特殊状态变量$?inarg2Shell:获取上一条命令的执行状态返回值(0表示成功,非0表示失败),这个变量是最常用的。$$:获取当前正在执行的shell脚本的进程号(PID),不常用。$!:获取最后一个在后台工作的进程ID(PID),不常用。$_:获取在此之前执行的命令或脚本的最后一个参数,不常用。$的做法?1[root@moli_linux1~]pwd#执行pwd获取当前路径,使用echo$?查看命令执行状态返回值/root[root@moli_linux1~]echo$?0#返回0表示前面的命令执行成功[root@moli_linux1~]rmshell_test/#删除目录shell_testrm:Unabletodelete"shell_test/":Itisadirectory#Withoutparameter-r,cannotdelete[root@moli_linux1~]echo$?1#状态码不为0,表示上次执行不成功或错误$?练习2[root@moli_linux1~]cattest1.sh#!/bin/bash[$#-ne2]&&{#如果参数个数不是=2echo"必须是两个args"。#然后输出一个提示exit119#终止程序并退出指定119状态码的程序,赋值给“$?”当前shell的变量。}echo"success!"[root@moli_linux1~]#shtest1.sh123#参数个数not=2必须是两个args。[root@moli_linux1~]#echo$?119#状态码为119“$?”注意点:判断命令、脚本或函数等程序是否执行成功。常用于从源代码编译安装软件,获取“$?”状态码。在每一步判断命令执行是否成功。如果在脚本中调用了“出口号码”,该号码将返回给“$?”多变的。如果它在函数中,则将此数字传递给“$?”通过“返回号”以函数返回值的形式。Shell变量字符串变量字符串表达式表达式描述${parameter}返回变量${parameter}的内容${#parameter}返回变量${parameter}内容的长度(按字符)${parameter:offset}在变量中${parameter}的内容,从${parameter:offset:length}的位置偏移量中提取字符串到末尾${parameter}中,从${parameter#word}的位置偏移量中提取字符串长度length删除从变量${parameter}开头的最短匹配词串${parameter##word}从变量${parameter}${parameter%word}中删除从变量开头的最长匹配词串${删除从parameter}结尾的最短匹配词串${parameter%%word}删除从变量${parameter}结尾的最短匹配词串${parameter/pattern/string}用字符串替换第一个匹配的pattern${parameter//pattern/string}使用字符串替换所有匹配的模式一个“#”:表示从头删除最短的匹配两个“##”:表示从头删除最长的匹配一个“%”:表示从末尾开始删除最短的匹配两个“%%”:表示从末尾删除最长的匹配一个“/”:表示替换前两个“//”:表示替换所有例1,打印并提取变量切片:#定义变量参数,内容为abc123ABC456[root@moli_linux1script]#parameter="abc123ABC456"#打印变量的两种方式[root@moli_linux1script]#echo$parameterabc123ABC456[root@moli_linux1script]#echo${parameter}abc123ABC456#打印变量内容的长度,一共12个字符[root@moli_linux1script]#echo${#parameter}12#从第三个变量内容开始,提取所有剩余内容[root@moli_linux1脚本]#echo${parameter:3}123ABC456#从变量内容的第三部分,提取接下来的6个字符[root@moli_linux1script]#echo${parameter:3:6}123ABC例子2,变量截取和替换:#定义variables,mori[root@moli_linux1script]#echo$moriabc123ABC456abc#deletetheshortesta*cstringfromthebeginningtoabc[root@moli_linux1script]#echo${mori#a*c}123ABC456abc#从头删除最长的a*cstringasabc123ABC456abc,全部删除[root@moli_linux1script]#echo${mori##a*c}[root@moli_linux1script]##第一次遇到从左到右用大写A替换小写a[root@moli_linux1script]#echo${mori/a/A}Abc123ABC456abc#将变量中的所有小写a替换为大写A[root@moli_linux1script]#echo${mori//a/A}Abc123ABC456Abc
