shell编程

一、计算机组成:

  • 内核在中间位置,连接软件与硬件(雷纳斯开发)

  • 内核功能:

    • 内存(物理、虚拟(交换空间)内存);
    • 软件管理(进程管理);
    • 硬件管理

二、 shell 编程基础

  • “;” 可以放在两个毫不相关的之间 例:date ; who

  • 脚本格式要求:脚本以 #!/Bin/bash 开头;脚本需要有可执行权限

  • 脚本的常用执行方式:

  1. 命令行进入脚本的绝对路径或相对路径
  2. ●方式1
    1)首先要chmod 744 helloworld.sh 改变权限(变绿为可执行文件)
    2)执行脚本
    ●方式2(bash/bash+脚本)
    说明:不用赋予脚本+x权限,直接执行即可。
1
2
3
4
例:输出“hello world”  
#!/bin/bash
echo "hello world"
# 注意:echo命令中想输出单引号用双引号包裹,双引号同理

三、shell的变量

  • 系统变量

    $HOME、$USER、$UID、$PWD等等

  • 用户自定义变量

    定义变量=值

1
2
3
4
5
6
7
8
9
10
例:系统变量与自定义变量的使用

#!/bin/bash
echo "当前用户信息:$USER"
var=10
var1=$var
echo "上一个值是:$var"
echo "第二个值是:$var1"

#shell命令中,在用户自定义命令时,切勿在等号两旁留空格
  • 其他内容:

    • 撤销命令 unset 变量名
    • 设置静态变量 readonly(不能unset)
1
2
3
4
5
6
7
8
#!/bin/bash
var=10
var1=$var
readonly var2=3
unset var
echo "第一个值是:$var"
echo "第二个值是:$var1"
echo "第三个值是:$var2"

四、 显示消息

1
2
3
4
5
#!/bin/bash
A=`ls -la`
echo $A
B=$(ls -la)
echo $B

五、设置环境变量

  1. 基本语法
    1) export变量名=变量值(功能描述: 将shell变量输出为环境变量)
    2) source配置文件(功能描述:让修改后的配置信息立即生效)..
    3) echo $变量名(功能描述: 查询环境变量的值)

  2. 快速入门
    1)在/etc/profile文件中定义TOMCAT HOME环境变量
    2)查看环境变量TOMCAT HOME的值
    3)在另外-一个shell程序中使用TOMCAT
    HOME
    注意:在输出TOMCAT_ HOME环境变量前,需要让其生效
    source /etc/profile

六、位置参数变量

  1. 介绍
    当我们执行一个shelI脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参
    数变量比如: ./myshell.sh 100200 ,这个就是一 个执行shell的命令行,可以在
    myshell脚本中获取到参数信息

  2. 基本语法

  • $n (功能描述: n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的
    参数,十以上的参数需要用大括号包含,如${10})
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
    echo $0 $1 $2
    #echo $* [email protected] $#

    [email protected]:~/bash$ bash test.sh 1 2
    test.sh 1 2
    [email protected]:~/bash$ bash test.sh 1 2 3
    test.sh 1 2
    [email protected]:~/bash$ bash test.sh 1
    test.sh 1
  • $* (功能描述: 这个变量代表命令行中所有的参数,$’ 把所有的参数看成一个整体)
  • [email protected] (功能描述:这个变量也代表命令行中所有的参数,不过[email protected]把每个参数区分对待)
  • $# (功能描述:这个量代表命令行中所有参数的个数)
    位置参数变量
    ●应用实例
    案例:编写一个shel脚本positionPara.sh,在脚本中获取到命 令行的各个参数信息。

七、运算符

  1. 基本介绍
    学习如何在shell中进行各种运算操作。

  1. 基本语法
    1) i “$(运算式)” 或“$[运算式]”
    2)expr m + n
    注意:expr运算符间要有空格
    3) expr m - n
    4) expr \*,/, % (乘,除,取余)

  2. 应用实例.
    案例1:计算(2+3) X4的值
    案例2:请求出命令行的两个参数[整数]的和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
expr 1 + 4
expr 1 \* 4

var1=10
var2=20
var3=$(expr $var1 + $var2)
echo $var3

var4=$[20 + 20]
echo $var4

var5=$[$var4 * 3]
echo $var5

var6=$[$var1 * ($var3 + $var4)]
echo var6

#(2+3)*4
#error:expr需分开做
#var7=$(expr (2 + 3) \* 4)
#echo var7
var7=$(expr 2 + 3)
var8=$(expr $var7 \* 4)

  1. 只支持整数级运算

    1
    2
    3
    #!/bin/bash
    var4=$(expr1.56 + 5.69)
    echo var4
  2. bash中自带计算器,可使用bc使用(quit退出)

1
2
3
4
5
6
7
#!/bin/bash
#bc 计算器;管道传给bc ?
echo "scale=4;3.777 / 5" | bc
var1=$(echo "scale=4;3.777 / 5" | bc)
var2=3
var3=$(echo "scale=4; $var1 *$var2" | bc)
echo var3

八、判断语句

  1. 两个整数的比较
    =字符串比较
    -lt小于
    -le小于等于
    -eq等于
    -gt大于
    -ge大于等于
    -ne不等于
  2. 按照文件权限进行判断-r有读的权限
    -w有写的权限
    -x有执行的权限
  3. 按照文件类型进行判断-f 文件存在并且是一个常规的文件
    -e文件存在
    -d文件存在并是一个目录
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
#条件判断
[ qust ]
echo $? #输出上一条指令判断结果

[ "qust" = "qust"]
echo $?

[ "qust" = "gmqust"]
echo $?

九、流程控制

  1. if-then
1
2
3
4
5
#!/bin/bash
if [ "ok" = ok ] #[ commond ]即中括号内项与符号之间也要保留空格
then
echo "相等"
fi #表示if判断结束
1
2
3
4
5
#!/bin/bash
if pwd
then
echo "相等"
fi
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
#❌ 没有相应命令
if dewedawa
then
echo "相等"
fi

[email protected]:~/bash$ bash test.sh
相等
test.sh: line 1: waasdad: command not found
1
2
3
4
#!/bin/bash
if pwd;then
echo "相等"
fi

十、复习:

1.位置参数变量

$n(0-9) : $0表示其本身;10以上用大括号表示${10};$*;$#;

2.预定义变量

$$(进程号PID);$!(最后一个进程号);$?

3.运算符(不支持浮点数)

expr m + (/ - \* \) n (注:空格);

${运算式}

4.条件判断

1
2
3
4
if command
then
commands
fi

十一、if语句

example 01: if—else流程

1
2
3
4
5
6
7
8
9
10
11
example 01:if——else流程
#!/bin/bash
testuser=pi
if grep $testuser /etc/passwd
then
echo "hello"
echo "你好"
echo "有这个用户"
else
echo "用户不存在"
fi

example 02:流程控制(嵌套if)

1
2
3
4
5
6
7
8
9
10
11
12
example 02:流程控制(嵌套if)
testuser=NoSuchUser
if grep $testuser /etc/ passwd
then
echo "The user $testuser exists on this system.
else
echo "The user $testuser does not exist on this system. ”
if ls -d /home/$testuser/
then
echo "However, $testuser has a directory.'
fi
fi

example 03: if-elif

1
2
example 03:if-elif

example 04: if [ condition ]条件判断

1.注意:中括号前后需保留空格
2.常见的应用
  • 数值比较
  • 字符串比较
  • 文件比较
3.数值比较

1
2
3
4
5
6
7
8
9
10
11
example 0401:if[ condition ]
#/bin/bash

var1=5
var2=10
if [ var1 -le var2 ]
then
echo "var1小于等于var2"
else
echo "var1大于var2"
fi
4.字符串比较
  • [ $m = $n ]
  • [ $m != $n ]
  • [ $m < $n ] (根据首字母顺序比较)
  • [ $m > $n ] (根据首字母顺序比较)
  • [ -n str1 ] (判断str1长度是否非零)
  • [ -z str1 ] (判断str1长度是否为零)

1
2
3
4
5
6
7
8
9
10
example 0402:字符串比较
#!/bin/bash
str1=pi
str2=root
if [ $str1 = $str2 ]
then
echo "相同"
else
echo "不相同"
fi
1
2
3
4
5
6
7
8
9
example 0403:得到的结果永远都是sr1>str2,原因:>在此处是记录,会创建新文件
#!/bin/bash
str1=pi
str2=root
if [ $str1 > $str2 ]
then
echo"str1 大于 str2"
else
echo"str1 小于 str2"
5.文件比较

1
2
3
4
5
6
7
8
9
10
example 0404:文件比较
#!/bin/bash
dir 1=/hone/pi
if[-e dir1]
then
echo“目录$dtr1存在
cd dir1
else
echo "不存在"
fi
1
2
3
4
5
6
7
8
#!/bin/bash
dir1=t05.sh
if [ t04.sh -nt Sdir1 ]
then
echo"t04 更新一些"
else
echo "t05 更新一些"
ft
6.复合条件测试
[ condition1 ] &&[ condition2 ]

[ condition1 ] II [ condition2 ]
if-then的高级特性
使用双括号
(( expression ))

1
2
3
4
5
6
7
8
example 0405:复合条件测试
#!/bin/bash
val1=10
if (( $val1 ** 2 > 99 ))
then
(( $val2 = val1 ++ )) #使用"++"时注意不要加"$"符号
echo $val2
fl

example 05 : case命令

1
2
3
4
5
case variable in
pattern1|pattern2)commands;;
pattern3)commands2;;
*)default commands;;
esac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
example 05:当命令行参数是 1 时,输出 "周一", 是2 时,就输出"周二", 其它情况输出 "other"
#!/bin/bash
var=$1
case $var in
1)
echo "星期一"
;;
2)
echo "星期二"
;;
*)default
echo "other"
;;
esac
1
2
3
4
5
6
7
8
结果:
[email protected]:~/bash$ . test.sh 2
星期二
[email protected]:~/bash$ . test.sh 1
星期一
[email protected]:~/bash$ . test.sh 7
bash: default: command not found
other
1
2
3
4
5
6
7
8
9
example 06:请编写一个shell程序,如果输入的参数,大于等于60,则输出 "及格了",如果小于60,则输出 "不及格
#!bin/bash
grade=$1
if [ $grade -ge 60 ]
then
echo "及格了"
else
echo "不及格"
fi
1
2
3
4
5
6
7
结果:
[email protected]:~/bash$ . test.sh 60
及格了
[email protected]:~/bash$ . test.sh 80
及格了
[email protected]:~/bash$ . test.sh 59
不及格

十二、循环语句

1、for命令

1
2
3
4
for var in list
do
commands
done

注:var若不修改,则在for循环执行后会保留列表中最后一个字符。

1
2
3
4
5
example 01:句子中包含',可通过转意和""处理操作
for var in I don\'t know if "this'll" work
do
echo $var
done
1
2
3
4
5
example 02:默认以空格划分,可以通过""进行处理操作
for var in "a apple" "a orang"
do
echo $var
done
1
2
3
4
5
6
example 03:读取变量
list="a apple ia on the desk"
for var in $list
do
echo $var
done
1
2
3
4
5
example 04:读取文档
for var in $(cat test01.txt)
do
echo $var
done
1
2
3
4
5
6
example 05:IFS问题(内部字段分隔符:空格,制表符,换行符)
IFS=$'\n' #修改指定分隔符
for var in $(cat test01.txt)
do
echo $var
done
1
2
3
4
5
6
7
8
9
10
11
example 06:遍历查看某个路径下文件
for var in /home/pi/*
do
if [ -d $var ]
then
echo "$var是一个目录"
elfi [ -f $var ]
then
echo "$var是一个文件"
fi
done
1
2
3
4
5
6
example 07:C语言的for命令-单变量

for ((i=1;i<=10;i++))
do
echo $i
done
1
2
3
4
5
6
example 08:C语言的for命令-多变量
(条件只能是一个!!)
for((a=1,b=2;a<=10;a++,b++))
do
echo [$a+$b]
done
1
2
3
4
5
6
7
8
9
example 09:[email protected] 与 $*区别
for i in "$*"
do
echo "第一种*显示的:$i"
done
for j in "[email protected]"
do
echo "第二种显示的:$j"
done
1
2
3
4
5
6
结果:
[email protected]:~/bash$ . test.sh 1 2 3
第一种*显示的:1 2 3
第二种显示的:1
第二种显示的:2
第二种显示的:3

十三、while循环

1

1
2
3
4
5
6
7
example 01:简单例子
var=10
while [ $var -gt 0 ]
do
echo $var
var=$[ $var - 1 ]
done
1
2
3
4
5
6
7
8
9
10
11
example 02:while的嵌套
var=10
while [ $var -gt 0 ]
do
for(( var2=1;$var<5;var2++ ))
do
echo "内层循环的值:$var2"
done
echo "外层循环的值:$var"
var=$[ $var - 1 ]
done
1
2
3
4
5
6
7
example 03:until(条件判断与while相反)
var=100
until { $var -eq 0 }
do
echo $var
var=$[ $var - 10 ]
done
1
example 04:控制循环:break;continue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
example 05:用while循环实现从命令行输入一个数n,统计从 1+..+ n 的值是多少
#!/bin/bash
n=$1
sum=0
i=1
while [ $i -le $n ]
do
sum=$[ $i + $sum ]
i=$[ $i + 1 ]
done
echo $i
echo $sum

结果:
[email protected]:~/bash$ . test.sh 100
101
5050
1
2
3
4
5
6
7
8
9
10
11
12
13
example 06:用for 实现从1加到100的结果,输出显示

#!/bin/bash
sum=0
for ((i=1;i<=100;i++))
do
sum=$[ $i + $sum]
done
echo $sum

结果:
[email protected]:~/bash$ . test1.sh
5050

十四、read读取控制台输入

基本语法

1
2
3
4
5
sample 01 简单例子
#! /bin/bash
echo -n "Enter your nane:"
read name
echo $name
p:指定读取值时的提示符;
1
2
3
4
sample 02 -p 参数的应用
#!/bin/bash
read -p "请输入你的姓名:"name
echo $name
1
2
3
4
5
6
sample 03 多参数输入
#!/bin/bash
read -p "请输入你的姓名年龄(空格分隔):"name age
echo "用户的姓名是$name,用户的年龄是$age"

#若用户输入变量数目大于原有变量数目,则剩余输入值全部赋给最后一个个预定变量
1
2
3
4
sample 04 若不指定变量,则会存储在默认环境变量$REPLY中
#!/bin/bash
read -p "请输入你的姓名年龄(空格分隔):"
echo $REPLY
t:指定读取值时等待的时间(秒),如果没有在指定的时间内输入,就不再等
1
2
3
4
5
sample 05 -t计时器应用
#!/bin/bash
read -t 5 -p "请输入你的姓名年龄(空格分隔):"name age
echo "用户的姓名是$name,用户的年龄是$age"

1
2
3
4
5
6
7
8
sample 06 -t与if函数的结合应用
#!/bin/bash
if read -t 5-p "请输入你的姓名,年龄(空格分割) :" name age
then
echo "欢迎你: $name"
else
echo "对不起,您登陆超时"
fi
1
2
3
4
5
6
7
8
9
10
11
sample 07 常见的case应用
#!/bin/bash
read -p "Do you want to continue?[Y/N]" answer
case $answer in
y | Y)echo
echo "continue";;
n | N)echo
echo "ok byebye"
exit;;
esac
echo "end……"
-s选项可以避免在read命令中输入的数据出现在显示器上
1
2
3
4
5
sample 08 -s选项可以避免在read命令中输入的数据出现在显示器上
#!/bin/bash
read -s -p "请输入你的密码:"passwd
echo
echo "你的密码是:"$passwd
读取文件
1
2
3
4
5
6
7
8
9
sample 09 读取文件
#!/bin/bash
count=1
cat 1og.200527 | while read line
do
echo "line $count :$line"
count=$[ $count + 1]
done
echo "end....."

十五、函数

1.系统函数:driname basename
  • dirname基本语法
    功能:返回完整路径最后的前面的部分,常用于返回路径部分
  • dirname文件绝对路径(功能描述: 从给定的包含绝对路径的文件名中去除文件名(非然后返回剩下的路径(目录的部分) )
    1
    2
    3
    4
    5
    sample : 终端
    [email protected]:~$ dirname bash/test1.sh
    bash
    [email protected]:~$ basename bash/test1.sh
    test1.sh
2.函数自定义函数
1
2
3
4
5
6
7
8
9
●基本语法
[ function ]funname{
Action;
[return int;]
}

name(){
commands
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sample 01 函数基本调用简单例子
#!/bin/bash
function func1{
echo "这是函数1"
}
count=1
while [ $count -le 5 ]
do
func1
count=$[ $count +1 ]
done

echo "结束循环"
func1
echo "结束循环"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sample 02 error
#!/bin/bash
function func1 {
echo“这是函数1”
}
count=l
whtle [ $count -le 5 ]
do
func1
count=$[ Scount + 1 ]
done
echo "结束循环"
func2
function func2 {
echo "这是函数2"
}
echo "结束脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sample 03 函数覆盖
#!/bin/bash
function func1 {
echo“这是函数1”
}
count=l
whtle [ $count -le 5 ]
do
func1
count=$[ Scount + 1 ]
done
echo“结束循环"
function func1 {
echo "这是函数2"
}
func1
echo "结束脚本

十六、函数

1.返回值

bash shell会把函数当作一个小型脚本,运行结束时会返回一个退出状态码。bash shell使用return命令来退出函数并返回特定的退出状态码。

⚠函数结束后需要立刻取回返回值⚠

1
2
3
4
5
6
7
8
9
10
sample 01
#!/bin/bash
func1(){
echo "尝试显示不存在的文件"
1s -1 badfile
}
echo "调用函数"
func1
echo "函数的状态码$?"

⚠状态码的范围0-255⚠

1
2
3
4
5
6
7
8
9
10
11
sample 02 加十器(大于255就会报错)
#!/bin/bash
func1(){
read -p "请输入一个数字:" value
echo "正在进行加十运算:"
return $[ $value + 10 ]
}
echo "调用函数"
func1
echo "运算之后的值:$?"

使用函数输出

1
2
3
4
5
6
7
8
9
10
sample 03 函数输出
#!/bin/bash
func1(){
read -p "请输入一个数字:" value
echo "正在进行加十运算:"
}
echo "调用函数"
result=$(func1)
echo "今天天气很好"
echo "运算之后的结果:$result"

2.函数中的变量

在函数中使用变量,向函数传递参数

1
2
3
4
5
6
7
sample 04 通过位置传参
#!/bin/bash
func1(){
echo $[ $1 + $2 ]
}
result=$(func1 100 200)
echo $result

在函数中处理变量

  • 全局变量

脚本任何地方定义的变量都是全局变量

1
2
3
4
5
6
7
8
sample 05
#!/bin/bash
func1(){
value=$[ $val + 2 ]
}
read -p "输入一个数字:" val
func1
echo $value
06
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sample 06 全局变量的弊端:比大小
#!/bin/bash
func1(){
temp=$[ $value + 5]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "函数结果$result"
if [ $temp -gt $value ]
then
echo "temp larger"
else
echo "value larger"
fi
  • 局部变量

局部变量 local关键字声明的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sample 07 局部变量
#!/bin/bash
func1(){
local temp=$[ $value + 5]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "函数结果$result"
if [ $temp -gt $value ]
then
echo "temp larger"
else
echo "value larger"
fi

3、数组

1
2
3
4
sample 08 简单数组输出
#!/bin/bash
array=(1 2 3 4)
echo ${array[*]}
1
2
3
4
5
6
7
8
sample 09  数组的读入
#!/bin/bash
func1(){
[email protected]
echo "数组的值为:$temparray"
}
array=(1 2 3 4)
func1 ${array[*]}
1
2
3
4
5
6
7
8
sample 10 数组的输出
#!/bin/bash
func1(){
array=(1 2 3 4 5 6)
echo ${array[*]}
}
result=$(func1)
echo $result

4.函数的递归

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
func1(){
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1 ]
local result=$(func1 $temp)
echo $[$result * $1]
}
read -p "请输入一个数字:" value
result=$(func1 $value)
echo $result

十七、创建一个菜单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
func1(){
df -hl
}
func2(){
lastlog -b 60
}
func3(){
pstree
}
clear
echo -e "\t1. Display disk space"
echo -e "\t2. Display logged information"
echo -e "\t3. Display pstree"
echo -e "\t0. exit program"
read -n 1 -p "请输入您的选项:" option

case $option in
0)
break;;
1)
func1;;
2)
func2;;
3)
func3;;
esac

参考

  1. [NULL]

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!