Shell脚本基础
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell脚本基础相关的知识,希望对你有一定的参考价值。
什么是Shell在Linux操作系统中,有两个非常重要的工具:①Linux命令;②Shell。Linux命令是Linux系统对用户提供的众多系统功能接口,每一个Linux命令都能完成一个独立的系统功能;Shell是一个基于C语言开发的应用程序,它可以通过各种逻辑语法和程序控制指令把一系列的Linux命令组合在一起,形成一个面向过程的程序命令(Shell Script)。
Linux命令一般需要在特定环境中执行,我们一般的Linux命令就是在Shell中执行的,需要特定的环境变量等支持;而Shell脚本会fork一个子进程去执行,如果在脚本中涉及环境变量的改变则只会改变子进程的环境,对Shell的环境变量没有影响。
我们知道Linux的Shell是一个组合并执行Linux命令的应用程序,所以Shell的实现并不只有一种,我们常用的Shell类型包括:sh、C Shell、TCSH、bash。Linux中默认的Shell为bash,一般保存在/bin/bash
中
也就是说,Linux命令是系统提供的具备各种不同功能的命令集合、Shell是一个可以将多个Linux命令组合为Shell脚本的应用程序,相当于一个脚本解析器。
Shell脚本语法
-
在Linux中l脚本的第一行一般会向系统声明该脚本所使用的解析程序:
#!/bin/bash
,通过这条语句声明该脚本使用/bin/bash
这个应用程序解析 -
Shell脚本的基本表达式:
表达式 功能 ++、-- 自增、自减(与C语言的前后自增自减相同) +、-、*、/、% 加、减、乘、除、余运算 ** 幂运算 >、>=、<、<=、==、!= 比较运算 <<、>> 按位左移、右移运算 &、|、^ 与、或、异或运算 &&、||、! 逻辑与、或、非 exp?a:b 三目运算符 #内容 单行注释 :<<EOF 内容 EOF 代表多行注释(EOF可以使用单引号、感叹号代替) -
变量赋值:
如何给变量赋值?如何调用变量?
Shell的变量使用等于号赋值,且等号之间不允许有空格,必须要直接与等号相连v1="value"
调用变量只需要将变量名连接在美元符号$后面v2=$v1
,也可以使用大括号区分每个变量的边界v3=${v1}isgood
#直接进行变量赋值 a=12 #默认是字符串类型的"12",进行数值运算时会解析为数值型的12 b=str1 #默认是字符串类型的"str1" #使用单引号和双引号进行变量赋值,双引号会解析变量、转义字符、反引号命令;而单引号则不会解析任何上面的东西,完全按照字符串字面值赋值。 v="$a" #这时变量v的值为12 v=‘$a‘ #这时变量v的值为‘$a‘ #列表变量的赋值 list=(v1,v2,v3) #括号内为列表内容,中间使用空格分隔 echo ${list[@]} #通过${}来调用列表,[]内表示索引,[@]表示列表内的每一项
注意使用以上方式的变量赋值,是无法进行任何命令以及运算的!,只能将变量解析出来,但是无法进行命令执行和数学运算。
a=1 b=2 c="$a+$b" #c的值为"1+2"而不是3 d="ls -al" #d的值为"ls -al"而不会执行
-
代换和Shell中的括号
-
文件名代换
简单地说就是一种可以使用在文件名上的通配符:
* #表示匹配任意多个任意字符 ? #表示匹配一个任意字符 [] #表示匹配中括号内任意一个字符的第一次出现 cd ./test[123abc] #匹配test1、test2、test3、testa...
-
命令代换,单括号
单括号符功能:①命令组功能,可以执行单引号中的多个命令;②命令代换,在变量中的命令会执行并正常输出到标准输出中;③初始化Shell列表变量
注意区分变量环境和非变量的环境,只有变量的环境下需要在单括号外加美元符号#在变量中使用反引号或单括号,可以将变量解析为shell命令并执行: a=`ls -al` #反引号可以进行命令代换 b=$(ls -al) #美元括号的内容会进行命令代换 (pwd) #执行pwd命令 `pwd` #执行pwd命令
-
运算代换,双括号
双括号符功能:①数值运算功能,只要内符合C语言运算语法,即可进行数值运算;②运算代换,在变量中的数值运算会正常进行后再进行赋值;③for语句功能,双括号可以在for循环中使用;
注意区分变量环境和非变量环境,只有变量环境下需要在双括号外加美元符号#在变量中使用双引号,可以将变量解析为数值运算并执行: a=10 b=$(($a+20)) #b的值为30
-
中括号
中括号功能:①Shell的内部命令,可用于进行条件测试返回True、False,等同于test命令;②正则表达式和通配符可以使用;③作为列表的索引使用
要注意,作为条件测试的中括号是一个命令语句而不是一个符号。作为命令前中括号后需要带一个空格才能接参数,而后中括号就是作为该条件测试命令的最后一个参数,代表参数输入结束。前后中括号中间的值都作为命令的参数。
并且作为一个命令,[
在对开空格的字符串作处理时会发生问题。#if使用中括号条件测试,结果为输出yes if [ 10 -lt 20 ] && [ 1 -lt 2 ] #此处前中括号后和后中括号前都需要加一个空格 then echo yes else echo no fi #这里$name会解析为三个字符串,导致[命令参数错误 name="here and there" if [ -n $name ] #使用[ -n "$name" ]才能正常 then echo "not empty" fi #这里的结果会报错 bash: [: too many arguments
-
双中括号
双中括号功能:①bash的内部关键字,能完成
[
的加强版功能,并且因为[[
不是命令而是关键字,所以对参数的解析规则会略有不同。且与[
每次只能做一种判断不停,[[
可以使用&&、||等运算符,可以同时做多种比较。#if使用中括号条件测试,结果为输出yes if [[ 10 -lt 20 && 1 -lt 2 ]] #此处前中括号后和后中括号前都需要加一个空格 then echo yes else echo no fi #因为对参数的处理不同,可以直接处理带空格的字符串 name="this is a test" if [[ -n $name ]] then echo "not empty" fi #结果会正常显示
-
大括号
大括号功能:①可以对文件名做扩展,作用类似通配符;②执行代码块,就是C中的代码块,每条命令结束都要加分号;③分隔变量名称和使用列表变量
touch test{1..5}.txt #会创建5个文件,其实就是通配符嘛 a="${this}IsATest" #不使用大括号变量名会粘在一起 a="${list[@]}" #选择列表所有元素
-
-
Shell中的特殊字符
Shell中的字符都有许多特殊的用法:
特殊字符 功能 ; 分号,表示连续执行命令 exp & 句尾的&号,表示命令在后台执行 n&>file 重定向,将文件符n重定向到目标文件 exp1 && exp2 两个命令中间的&&,表示exp1返回0才会执行exp2 exp1 || exp2 两个命令中间的||,表示exp1返回非0才会执行exp2 ${#var} 返回列表或变量的长度 $0、$1、$2 和运行脚本的命令有关。0表示该脚本文件;1、2分别表示第1、2个参数 $*、$@、$# 和运行脚本的命令有关。*和@表示参数列表;#表示参数个数 $$、$? 和运行脚本的命令有关。$表示脚本运行PID;?表示脚本退出码
Shell流程控制
-
if语句
#可以写成正常形式 if condition1 then cmd1 elif condition2 then cmd2 else cmd3 fi #也可以写成一句话形式,中间用分号连接 if condition1; then cmd1; elif condition2; then cmd2; else cmd3; fi
-
for语句
#正常形式 for var in ${list[@]} do cmd1 cmd2 cmd3 done #一句话形式,中间用分号分隔 for var in ${list[@]}; do cmd1; cmd2; cmd3; done
-
while语句
while语句是先判断条件再执行循环,且条件为False时结束循环,同C语言
#正常形式 while condition do cmd1 cmd2 done #一句话形式,中间用分号分隔 while condition; do cmd1; cmd2; done
-
until语句
until语句是执行函数后再判断条件,且条件为True时结束循环,同C语言
until condition do cmd1 cmd2 done until condition; do cmd1; cmd2; done
-
case语句
a=2 case $a in 1) cmd1 ;; 2) cmd2 ;; *) cmd3 ;; esac #一句话形式 a=2 case $a in 1) cmd1;; 2) cmd2;; *) cmd3;; esac
-
跳出循环
可以在循环语句for、while、until以及枚举语句case中,使用
break
终止整个流程;使用continue
跳过本次流程。此处与C语言相同。
Shell函数
Shell可以定义函数,之后可以随意调用。
funName(){ #定义函数,后面不用带参数,传参方法和命令相似
(ls -al $1)
echo $2
i=$3
while [ $i -gt 0 ]
do
echo $i
i=$(($i-1))
done
}
funName /usr this 3 #调用函数,后面是参数
新手发文,欢迎大佬指正错误
以上是关于Shell脚本基础的主要内容,如果未能解决你的问题,请参考以下文章