shell脚本基础教程

1、解释器

类型

  • Bourne Again Shell(/bin/bash)
  • Bourne Again Shell (/usr/bin/sh 或者 /bin/sh)
  • C Shell (/usr/bin/csh)
  • K Shell (/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

2、shell脚本调用方式

创建脚本:vim 脚本名.sh
脚本调用方式:
1、可以使用路径的方式,前提是需要有执行权限,如果没有权限使用
chmod a+x 路径/脚本名.sh ,赋予执行权限。

  • 绝对路径的方式:/home/sh/1.sh
  • 相对路径的方式:./1.sh

2、也可以使用sh或者bash命令调用,用这个方式,脚本没有执行权限也可以使用

  • sh 1.sh 如果使用 sh /home/sh/1.sh 即sh 绝对路径,即使脚本中有错误也会往下执行完
  • bash 1.sh

3、其他方式

  • source 1.sh
  • . 1.sh(点号+空格+脚本名)

3、变量

shell是弱类型编程语言(python,js),强类型语言(c,java,pl/sql);弱类型编程语言,声明变量,不需要指明变量的类型,shell中所有的变量默认是字符串类型;

自定义变量

命名变量
命名规则:字母、数字、下划线字符组合,第一个字符不能是数字,不许出现空格和标点符号。
赋值符号等号左右两侧不能有空格,如果有要加在双引号中
错误例子: a= www,b =1234,c=hello world
正确例子:a=www,b=1234,c=“hello world”,c=‘hello world’;

d="\t\ta string\n"      # 变量值可以使用转义字符
e=$(ls -l foo.txt)      # 变量值可以是命令的执行结果
f=$((5 * 7))            # 变量值可以是数学运算的结果

使用变量
$变量名
建议使用:${变量名} ,中括号括起来是一个整体。如果使用的$字符需要\转义。

abc=123
a=1
echo ${abc}

只读变量——readonly

readyonly abc #只读变量的值不能被改变

删除变量
unset 变量名
变量被删除后就不能使用,unset不能删除只读变量
由于不存在的bash变量一律为空字符串,索引也可以把要删除的变量设置为空。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d64b278f859c4fcea0fcfc51d64a1e65.png

环境变量

env或者printenv可以打印出所有的环境变量
在这里插入图片描述

常见的环境变量如下

  • BASHPID Bash 进程的进程ID
    在这里插入图片描述
  • HOME 用户的主目录
  • HOST 当前自主机的名称
  • IFS 词与词之间的分割符,默认为空格
  • LANG 字符集以及语言编码,比如zh_CN,UTF-8
  • PATH 由冒号分开的目录列表,当输入可执行程序名后,会搜索这个目录列表
  • PWD 当前工作目录
  • RANDOM 返回一个0到32767之间的随机数
  • UID 当前用户的ID编号
  • USER 当前用户的用户名

环境变量一般是只读,可以视为常量,变量名都是大写。注意变量名时区分大小写的。

看单个环境变量可以使用
printenv PATH
echo $PATH

特殊变量

  1. $? :上一个名令的退出码,用来判断上一个命令是否执行成功。返回值是0,表示上一个命令执行成功;如果非0,上一个命令执行失败。在这里插入图片描述

  2. $$ : 当前shell的进程ID;还可以用来命令临时变量LOGFILE=/tmp/output_log.$$在这里插入图片描述

  3. $_ : 上一个命令的最后一个参数

  4. $! :为最近一个后台执行的异步命令进程ID

  5. $0 :为当前shell脚本的名称

  6. $- :为当前shell启动的参数在这里插入图片描述

  7. $# :表示参数的总数

  8. $@ : 全部的参数,参数之间用空格隔开;使用时加引号,并在引号中返回每个参数。如 “$@” 用"“括起来的情况,以”$1" “$2” " 3 " . . . " 3" ..." 3"..."n"的形式输出所有参数

  9. $* : 全部的参数,以一个 单字符串 显示所有向脚本传递的参数。如果用""括起来 “$*” ,以 “$1 $2 $3…$n” 的形式输出所有参数

变量的默认值

bash提供四个特殊语法,跟变量默认值有关,以保证变量不为空。

  1. ${varname:-word} :如果varname存在且不为空,返回它的值,否则返回word。一般是为了返回一个默认值。
    例如${count:-0} 表示count变量不存在时返回0
  2. ${varname:=word} :如果varname存在就不为空会返回它的值,否则会将varname的值设置为word,并返回word值。一般是为了初始化变量的默认值值。
    例如count:=1 count如果不存在时,会把count设置成1,并且返回这个值
  3. ${varname:+word} :跟第一个刚好相反,如果varname变量存在并且不为空时会返回word值,否则返回空。一般用于测试变量是否存在。
    例如${count:+1} 如果count存在时会返回1(true),否则返回空
  4. ${varname:?msg} : 如果varnanme存在且不为空,就返回它的值;否则输出msg信息,并中断脚本执行。如果省略msg,默认输出"parameter null or not set"。一般是为了防止变量未定义的情况。
    例如 ${count:?"undefined"} 表示变量未定义就中断脚本执行,并抛出异常错误"undefined"

上面四种语法如果使用在脚本里,变量名的部门可以用数字1到9,表示脚本的参数
filename=${1:?"filename missing"} 1表示脚本的第一个参数。参数不存在抛出异常filename missing并中断执行

declare 命令

可以声明一些特殊类型变量,为变量设置限制,比如声明只读或者整数型变量

declare OPTION variable=value

主要参数如下

  • -a 声明数组变量
  • -f 输出所有函数的定义
  • -F 输出所有函数名
  • -i 声明整数变量
  • -l 声明变量为小写字母
  • -p 查看变量信息
  • -r 声明只读变量
  • -u 声明变量为大写字母
  • -x 该变量输出为环境变量,等同于export

declare命令如果用在函数中,声明的变量只在函数内部有效,等同于local命令。

不带任何参数时,declare命令输出当前环境的所有变量,包括函数在内,等同于不带有任何参数的set命令。
在这里插入图片描述

readonly命令

等同于declare -r 声明只读,不能改变变量的值,不能unset变量
有三个参数

  • -f:声明的变量为函数名。
  • -p:打印出所有的只读变量。
  • -a:声明的变量为数组。

let命令

该命令声明的变量,可以直接指向算术表达式

$ let foo=1+2
$ echo $foo
3

支持多个变量赋值,变量之间用空格隔开

$ let "v1 = 1" "v2 = v1++"
$ echo $v1,$v2
2,1

4、数据类型

字符串

""双引号,弱引用,引号内的特殊字符有意义
''单引号,强引用,引号内的特殊字符取消意义,原样输出

双引号

	your_name="hongshan"
	sp1="hello,"$your_name"!"
	p2="hello,$your_name!"
	$sp1 $sp2
	#输出:hello,hongshan!hello,hongshan!

单引号

	dp1='hello,'$your_name'!'
	dp2='hello,$your_name!'
	echo $dp1 $dp2
	#输出:hello,hongshan! hello,$your_name!

5、字符串操作

  • ${#varname} 获取字符串的长度
    echo ${#变量} 或者 echo $(expr length "\${变量}") ;$()功能和反引号``一样
  • 截取字符串,序号从0开始 ${变量:序号:截取个数}echo ${变量:0-3:4} 从倒数第三个开始截取,从左往右截取长度为4的字符
  • echo `expr index “$a” er ` 查找字符e或者r的位置,找不到返回0,找到返回第一次出现的位置。在这里插入图片描述

6、数组

定义数组

  • array=(value0 value1 value2 value3)
  • array1[0]=值1
    array1[1]=值2
    array1[15]=值3
    下标号 从0开始,给第一个元素赋值
    mp3s=( *.mp3 ),定义数组可以使用通配符(将当前目录的所有 MP3 文件,放进一个数组)
  • declare -a命令声明一个数组 $ declare -a ARRAYNAME

读取数组

echo ${array_name[n]}
n:下标号;读取单个元素 ;下标号从0开始

echo ${array_name[*]} :读取全部元素
echo ${array_name[@]} :读取全部元素

修改数组

 array1[0]=新值 修改
 array1[4]=值  新增
 arr+=(d e f)  使用+=在数组末尾追加成员

删除数组

  • 删除单个数组
    可用unset 数组名[n]
    n:下标号 删除元素;删除数组元素,注意序号不会往前推;
  • 删除整个数组
    unset 数组名;也可以设置成空字符串

获取数组长度

获取数组元素个数
echo ${#array_name[@]} 或者 echo ${#array_name[*]}
获取数组单个元素长度
echo ${#array_name[n]} n:下标号

7、运算符

算术运算符

  • $((运算符))
    • 对整数的进行算术运算,小数点进行运算会报错。
    • 可以是多个运算符,用逗号隔开;多个运算式返回最后一个运算式的结果;
    • 里面会自动忽略空格
    • 里面可以使用圆括号改变优先级;
    • 也可以嵌套使用$(())
    • 里面可以加上$,也可以不加,不会报错
    • 如果在里面使用字符串,不会报错,但是会当做空值处理
      $(( ))支持
      算术运算
      +:加法
      -:减法
      *:乘法
      /:除法(整除)
      %:余数
      **:指数
      ++:自增运算(前缀或后缀)
      –:自减运算(前缀或后缀)
      位运算
      <<:位左移运算,把一个数字的所有位向左移动指定的位。
      >>:位右移运算,把一个数字的所有位向右移动指定的位。
      &:位的“与”运算,对两个数字的所有位执行一个AND操作。
      |:位的“或”运算,对两个数字的所有位执行一个OR操作。
      ~:位的“否”运算,对一个数字的所有位取反。
      !:逻辑“否”运算
      ^:位的异或运算(exclusive or),对两个数字的所有位执行一个异或操作。
      逻辑运算
      <:小于
      >:大于
      <=:小于或相等
      >=:大于或相等
      ==:相等
      !=:不相等
      &&:逻辑与
      ||:逻辑或
      expr1?expr2:expr3:三元条件运算符。若表达式expr1的计算结果为非零值(算术真),则执行表达式expr2,否则执行表达式expr3。
      赋值运算
      parameter = value:简单赋值。
      parameter += value:等价于parameter = parameter + value。
      parameter -= value:等价于parameter = parameter – value。
      parameter *= value:等价于parameter = parameter * value。
      parameter /= value:等价于parameter = parameter / value。
      parameter %= value:等价于parameter = parameter % value。
      parameter <<= value:等价于parameter = parameter << value。
      parameter >>= value:等价于parameter = parameter >> value。
      parameter &= value:等价于parameter = parameter & value。
      parameter |= value:等价于parameter = parameter | value。
      parameter ^= value:等价于parameter = parameter ^ value。
      注意 表达式内部赋值需要放在圆括号内,不然会报错
      求值运算
      逗号,在$((…))内部是求值运算符,执行前后两个表达式,并返回后一个表达式的值。
$ echo $((foo = 1 + 2, 3 * 4))
12
$ echo $foo
3
  • $[运算符] 以前的语法,可以做整数使用,但是不建议使用
  • let 命令进行运算
  • expr 运算式 需要注意运算符两边空格问题;不支持非整数的运算
	    + 加法 `expr $a + $b`
		- 减法 `expr $a - $b`
		* 乘法 `expr $a \* $b`
		/ 除法 `expr $a / $b`
		% 取余 `expr $a % $b`

在这里插入图片描述
在这里插入图片描述

  • 小数计算要用外部计算器 bc
echo "$n1+$n2"|bc
echo "$n1-$n2"|bc
echo "$n1*$n2"|bc

乘积结果小数位数 取决于 n1,n2中小数位数多的那个 ;不会进行四舍五入

除法 --scale,设置保留几位小数 --不会进行四舍五入

echo "scale=2;$n1/$n2"|bc

关系运算符

-lt 小于(less than)          [ $a -lt $b ]
-le 小于等于(less equal)      [ $a -le $b ]
-gt 大于(greater than)       [ $a -gt $b ]
-ge 大于等于(greater equal)   [ $a -ge $b ]
-eq 等于(equal)              [ $a -eq $b ]
-ne 不等于(not equal)        [ $a -ne $b ]

布尔运算符

-a 与运算(且) [ $a -lt 10 -a $b -gt $a ]
-o 或运算(或) [ $a -lt 10 -o $b -lt 10 ]
! 非运算(非)  [ ! $a -ge $b ]

逻辑运算符 要在[[ ]]中

  • && 与运算
[[ $a -lt 10 && $b -gt $a ]]    或者 
[ $a -lt 10 ] && [ $b -gt $a ]
  • || 或运算
[[ $a -lt 10 || $b -lt 10 ]]   或者  
[ $a -lt 10 ] || [ $b -gt $a ] 
  • ! 非运算
 [[ ! $a -ge $b ]]  

字符串运算

  • = 检测两个字符串是否相等,相等返回true。 [ $a = $b ]
  • != 检测两个字符串是否不相等,不相等返回true。 [ $a != $b ]
  • -z 检测字符串长度是否为0,为0返回true。 [ -z $a ]
  • -n 检测字符串长度是否不为0,不为0返回true。 [ -n $a ] --空格会认为长度为1 a=" "
  • $ 检测字符串是否不为空,不为空返回true。 [ $a ] --空格会认为是空 a=“”; b=" ";

文件测试运算符

file="/home/shell.sh/1.sh"
  • -d 检查文件是否是目录,如果是,返回true。 [ -d $file ]
  • -f 检查文件是否为普通文件,如果是,返回true。 [ -f $file ]
  • -s 检查文件是否为空,如果不为空,返回true。 [ -s $file ]
  • -e 检查文件(包括目录)是否存在,如果是,返回true。 [ -e $file ]
  • -r 检查文件是否可读,如果是,返回true。 [ -r $file ] --针对文件所有者进行权限判断
  • -w 检查文件是否可写,如果是,返回true。 [ -w $file ] --针对文件所有者进行权限判断
  • -x 检查文件是否可执行,如果是,返回true。 [ -x $file ] --针对文件所有者进行权限判断

8、流程控制

if语句

	if []
		then
			echo "这里可以嵌套"
	elif []
		then
			echo "这里可以嵌套"
	else
			echo "这里可以嵌套"
	fi

case语句

 case $变量 in
		"hello")
			echo
		;;
		"world")
			echo
		;;
		*)
			echo
		;;
		esac
    结合正则  进行数字或者字母的判断
 	    a=6
        case $变量 in
			[0-3])
				echo
			;;
			[4-7])
				echo
			;;
			*)
				echo
			;;
		esac

for循环语句

			((首位;末位;步长)) i+=1;i-=1;i*=1;i/=1;
		
			s=0
			for ((i=0;i<=100;i+=1))   ## i+=1也可以替换成i++
			do
				s=$[s+i] 
				或
				s=$((s+i))
				或
				s=`expr $s + $i`
			done
			echo $s

		$(seq 首位 步长 末位)
	 
			s=0
			  # seq 首位 步长 末位       --首位 步长 末位  可以是变量
			for i in $(seq 0  1 100)   
			do
				s=$[s+i] --s=$((s+i))
				或
				s=`expr $s + $i`
			done
			echo $s

for i in {首位..末位..步长}       ---此种方式  首位 步长 末位 必须是具体值 ,不可以是变量
    for i in  值1 值2 值3 值4   --循环范围直接设定为具体的一个个值
        do
       		 echo $i
        done

  -- $(ls /)  反引号 ``功能相当与$()   --循环范围是一个linux命令结果的范围
  for i  in `ls /`    
       do
        echo $i  
       done

while循环

满足条件,进入循环

		s=0
		i=0
		while [ $i -le 100 ]
		do
		  s=$((s+i))
		  i=$((i+1))  --let i++
		done
		
		echo $s

util 循环


        s=0
		i=0
		until [ $i -gt 100 ]
		do
		  s=$((s+i))
		  i=$((i+1))
		done
		
		echo $s

select in循环 可以与用户进行交互

echo "请选择以下的一种水果"
select i in "apple" "pear" "orange"
do
case $i in
  "apple")
   echo "你选的是苹果"
   ;;
   "pear")
   echo "你选的是梨"
   ;;
   *)
   echo "你选的是橘子"
   ;;
esac

done

跳出循环 continue与break

continue跳出单次循环

			s=0
			i=0
			while [ $i -lt 100 ]
			do
					i=$[$i+1]  --i=$((i+1))
					
					yu=`expr $i % 2` --yu=$((i%2))
					
					if [ $yu -gt 0 ]
					then
					continue
					fi
					s=$[$s+$i]
			done
			echo "1到100偶数相加等于$s"

break跳出全部循环
exit 可以直接跳出脚本

			s=0
			i=0
			while [ $i -lt 100 ]
			do
					i=$[$i+1]   --i=$((i+1))
					if [ $i -gt 10 ]
					then
							break
					fi
					s=$[$s+$i]  --s=$((s+i))
			done
			echo "1到10相加等于$s"


9、函数

能够实现特定功能的一段代码, 能够实现代码的复用
两种定义方式

# 第一种
fn() {
  # codes
}
# 第二种
function fn() {
  # codes
}
	先定义函数,再调用函数。
	function fun_name()
	{
		f_a=$1
		f_b=$2
		f_c=`expr $f_a + $f_b`
		echo "${f_a}+${f_b}=$f_c"
	}
	fun_name 66 77
	
	read -t 10 -p "Enter your name in 10 seconds" NAME
	echo "hello $NAME"

shell函数也可以拥有return返回值 ,只能返回0-255的值,若大于255,是返回 该值%256 取余 的 结果值
若要得到return返回值结果,要结合使用 echo $?;

#!/bin/bash
function sum_002()
{
a=255
b=2
let c=a+b
return $c
}
sum_002
echo $?

----细节再补充吧,真累…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值