Skip to content

Shell编程

一、Shell概述

Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。

Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。

外层应用程序 -> Shell -> Linux内核 -> 硬件

命令行解释器 >> bash

Shell解析器:sh zsh bash dash...

查看默认解析器:echo $SHELL

二、Shell脚本入门

1、脚本格式

第一行需要指定解析器

shell
#!/bin/bash

2、第一个Shell脚本

shell
#!/bin/bash
echo "Hello world"

3、脚本的执行方式

1)bash运行

shell
$ bash test.sh

2)直接运行

需要先给定权限

shell
chmod +x test.sh

执行文件

shell
./test.sh

4、多命令执行

shell
#!/bin/bash

cd ~/Desktop
touch a.txt
echo "i love wc" >> a.txt

三、变量

1、系统变量

作用域:(系统变量)整个操作系统、(用户变量)整个用户

修改系统变量:vi /etc/profile

修改用户变量:vi ~/.bashrc

执行修改:source /etc/profile

查看系统变量的值:echo $USERecho $PWD

查看所有系统变量:printenvset

自定义用户变量:export TEST_C=300 --> 临时变量(当前bash以及子bash)

2、自定义变量

1)基本语法

作用域:当前的Shell(当前的解释器)

定义变量:A=3

删除变量:unset A

静态变量(不可被修改):readonly A=3

2)变量定义规则

变量名称可以由字母、数字和下划线组成,但是不能以数字开头

环境变量名建议全大写

等号两侧不能有空格

变量的值如果有空格,需要使用双引号或单引号括起来

3、特殊变量

1)$n

功能描述:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}

2)$#

功能描述:获取所有输入参数个数,常用于循环

3)$*$@

$*:这个交量代表命令行中所有的参数,$*把所有的参数看成一个整体 $@:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待

shell
wmh@Mac Desktop % zsh test.sh 123 456
123 456
------
123
456
------
123
456
------
123
456
shell
#!/bin/zsh

for i in "$*"; do
	echo $i
done

echo "------"

for j in "$@"; do
	echo $j
done

echo "------"

for k in $*; do
	echo $k
done

echo "------"

for l in $@; do
	echo $l
done

4)$?

功能描述:最后一次执行的命令的返回状态。如果这个交量的值为0,证明上一个命令正确执行;如果这个交量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。

四、运算符

反引号(`):作为一条完整的命令,并且保留结果

1、$((运算式))

2、$运算式

3、expr +, -, *, /, % 加,减,乘,除,取余(expr运算符间要有空格)

shell
#!/bin/bash

A=100
B=2

#第一种写法
C=$((A+B))
echo $C

#第二种写法
D=$[A+B]
echo $D

#第三种写法
E=`expr $A + $B`
echo $E

#综合运算 (2+3)*5
F=$[(2+3)*5]
echo $F
expr `expr 2 + 3` \* 5

五、条件判断

1、基本语法

[ condition ](注意condition前后要有空格)

条件非空即为true,[ rexhao ]返回true,[]返回false。

任何命令的执行状态为0则为True,否则为False

2、判断条件

1)整数比较

=:字符串比较

-lt:小于 (less than)

-le:小于等于 (less equal)

-eq:等于 (equal)

-gt: 大于 (greater than)

-ge:大于等于 (greater equal)

-ne:不等于 (Not equal)

2)文件权限判断

-r:有读的权限 (read)

-w:有写的权限 (write)

-x:有执行的权限 (execute)

3)文件类型判断

-f:文件存在并且是一个常规的文件 (file)

-e:文件存在 (existence)

-d:文件存在并是一个目录 (directory)

4)案例

shell
#!/bin/zsh

[ $## -gt 2 ] && echo "参数的个数大于2"

[ $## -le 2 ] || echo "参数的个数大于2"

六、流程控制

1、if判断

1)基本语法

shell
if [ 条件判断式 ];then
	程序
fi

或者

shell
if [ 条件判断式 ]
	then
		程序
fi
  1. 中括号和条件判断式之间必须有空格
  2. if后要有空格

2)案例

shell
#!/bin/bash

if [ $1 -eq 1 ]; then
	echo "密码正确"
elif [ $1 -ne 1 ];then
	echo "密码错误"
fi

2、case语句

shell
case $变量名 in
"值1")
    程序1
;;
"值2")
    程序2
;;

*)
    相当于default
;;
esac
  1. case行尾必须为单词in,每一个模式匹配必须以有括号)结束。
  2. 双分号;;表示命令序列结束,相当于java中的break。
  1. 最后的*)表示默认模式,相当于java中的default。

3、for循环

1)基本语法

shell
for((初始值;循环控制条件;变量变化)); do
	程序
done

1-100求和案例

shell
#!/bin/bash

ans=0
for (( i = 0; i < 10000; i++ )); do
	ans=$[$i+$ans]
done

echo $ans

2)增强for

shell
for 变量 in 值1 值2 ...; do
	程序
done

1-100求和案例

shell
#!/bin/bash

ans=0
for i in {1..100}; do
	ans=$[$i+$ans]
done

echo $ans
shell
#!/bin/bash

ans=0
for i in `seq 1 100`; do
	ans=$[$i+$ans]
done

echo $ans

4、while循环

shell
while [ condition ]; do
	程序
done

1-100求和案例

shell
#!/bin/zsh

i=1
sum=0
while [ $i -le 100 ]; do
	let sum=sum+i 	## 相当于 sum=$[$sum+$i]
	let i++
done

echo $sum

七、读取输入

read(选项)(参数)

-p:读取的提示符

-t:等待时间

shell
#!/bin/bash

i=1
sum=0
read -p "请输入n:" n
while [ $i -le $n ]; do
	let sum=sum+i 	## 相当于 sum=$[$sum+$i]
	let i++
done

echo "1到$n的和是$sum"

八、函数

1、系统函数

1)basename

功能描述:basename命令会删掉所有的前缀包括最后一个(\) 字符,然后将字符串显示出来。

2)dirname

dirname 文件绝对路径:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)

3)案例

shell
wmh@Mac Desktop % basename ~/Desktop/test.sh
test.sh
wmh@Mac Desktop % dirname ~/Desktop/test.sh
/Users/wmh/Desktop

2、自定义函数

shell
[function] funname[()] {
	程序
	[return int]
}
  1. 必须在调用西数地方之前,先声明西数,shell脚本是逐行运行。不会像其它语言一样先编译。
  2. 函数返回值,只能通过%?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)

return并不十分真正的返回值,而是函数执行状态

shell
#!/bin/bash

add(){
	sum=$[$1+$2]
	echo $sum
}

echo `add 100 200`
shell
#!/bin/bash

fact(){
	if [[ $1 -eq 1 ]]; then
		echo 1
	else
		echo $[`fact $[$1-1]`*$1]
	fi
}

echo `fact $1`

Released under the MIT License.