shell 脚本语言基础1

7.1 实验介绍

7.1.1 实验介绍

在对系统进行运维时,shell 脚本给了我们很大帮助。通过 shell 脚本,可以大大减少工作量。

本实验主要介绍 shell 脚本的概念及使用。

7.1.2 实验目标

掌握全局变量及局部变量;

掌握位置化参数使用;

掌握 shell 中的特殊字符;

掌握常用的 shell 语句。

7.2 shell 变量

7.2.1 用户变量的定义

步骤 1

执行如下命令,设置自定义局部变量。

[root@openeuler ~]# dir=/usr/tmp/

[root@openeuler ~]# echo $dir

/usr/tmp/

[root@openeuler ~]# today=Sunday

[root@openeuler ~]# echo $today

Sunday

[root@openeuler ~]# echo $Today

//无回显

[root@openeuler ~]# str=“Hapy New Year!”

[root@openeuler ~]# echo “Wish You $str”

Wish You Hapy New Year!

###作为交互式输入手段,可以利用 read 命令由标准输入(即键盘)上读取数据,然后赋给指定的变量。

其一般格式是:read 变量 1 [变量 2…]

[root@openeuler ~]# read name

openeuler

//此处输入 openeuler

[root@openeuler ~]# echo $name

openeuler

[root@openeuler ~]# read a b cHCIA-openEuler 实验指导手册

第 118 页

kunpeng 2020 huawei

#此处输入 kunpeng 2020 huawei

[root@openeuler ~]# echo $a

kunpeng

[root@openeuler ~]# echo $b

2020

[root@openeuler ~]# echo $c

huawei

步骤 2

执行如下步骤,配置用户变量。

[root@openEuler ~]# vim .bash_profile

~/.bash_profile 是用户独享的配置文件

#在文件最后新增一行,修改完成后保存退出:

a=1000

[root@openEuler ~]# echo $a

#未更新变量文件时,a 值未发生变化

kunpeng

[root@openEuler ~]# source .bash_profile #更新变量文件后,a 值发生变化

[root@openEuler ~]# echo $a

1000

[root@openEuler ~]# bash

#打开一个新的 bash

[root@openEuler ~]# echo $a #a 变量未定义

[root@openEuler ~]# exit

#退出新打开的 shell

[root@openEuler ~]# su - root#以登录的方式切换用户,此时会自动读取.bash_profile 文件

[root@openEuler ~]# echo $a #a 变量值生效

1000

[root@openEuler ~]# exit

#退出当前的登录 shell

步骤 3

执行如下步骤,配置系统环境变量。

[root@openEuler ~]# vim /etc/profile

/etc/profile 是系统的配置文件,所有用户共享

#在文件最后新增一行,输入如下信息,并保存退出:

b=2000

[root@openEuler ~]# echo $b

#变量未更新

2020

[root@openEuler ~]# source /etc/profile

#更新变量

[root@openEuler ~]# echo $b

2000

#变量值发生了变化

[root@openEuler ~]# bash

#打开一个新的 bash

[root@openEuler ~]# echo $b #b 变量未定义

[root@openEuler ~]# exit

#退出新打开的 shell

[root@openEuler ~]# su - root#以登录的方式切换用户,此时会自动读取.bash_profile 文件

[root@openEuler ~]# echo $b #a 变量值生效

2000

[root@openEuler ~]# useradd huawei

#新增一个用户

[root@openEuler ~]# su - huawei

#切换到该用户

[huawei@openEuler ~]$ echo $b

2000

#变量 b 生效

[huawei@openEuler ~]$ exit

#退出当前用户

logoutHCIA-openEuler 实验指导手册

第 119 页

7.2.2 位置参数

步骤 1

在/root 目录下新建三个文件 m1.c、m2.c、ex1.sh,内容如下:

m1.c:

main()

{

printf(“Begin \n”);

}

m2.c:

include < stdio.h >

{

printf(“OK! \n”);

}

ex1.sh:

#!/bin/bash

ex1.sh: shell script to combine files and count lines

cat $1 $2 $3 $4 $5 $6 $7 $8 $9 | wc -l

end

步骤 2

执行脚本 ex1.sh。

[root@openeuler ~]# chmod u+x ex1.sh

[root@openeuler ~]# sh ex1.sh m1.c m2.c

8

7.3 shell 中的特殊字符

步骤 1

新建脚本 ex3.sh,写入如下内容:

#!/bin/bash

echo “current directory ispwd”

echo “home directory is $HOME”

echo “file*.?”

echo " directory ‘$HOME’"

步骤 2

执行脚本 ex3.sh

[root@openeuler ~]# chmod u+x ex3.sh

[root@openeuler ~]# sh ex3.sh

current directory is ‘pwd’

home directory is /root

file*.?

directory ‘/root’

Linux 中其他特殊变量列表HCIA-openEuler 实验指导手册

第 120 页

变量

含义

$0

当前脚本的文件名

$n

传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参

数是$1,第二个参数是$2。

$#

传递给脚本或函数的参数个数。

$*

传递给脚本或函数的所有参数。

$@

传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将

会讲到。

$?

上个命令的退出状态,或函数的返回值。

当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID 7.4 条件判断与循环结构 7.4.1 if 语句 7.4.1.1 语法示例 步骤 1 新建脚本 ex4.sh,写入如下内容: #!/bin/bash a=3 b=$1 if [ $a == $b ] then echo "You win!" else echo "Please guess again." fi 步骤 2 执行脚本 ex4.sh。 [root@openeuler ~]# chmod u+x ex4.sh [root@openeuler ~]# ./ex4.sh 3 You win! [root@openeuler ~]# ./ex4.sh 4 Please guess again. 7.4.1.2 【附录】if 常用判断  文件/目录判断 [ -a FILE ] 如果 FILE 存在则为真。 [ -b FILE ] 如果 FILE 存在且是一个块文件则返回为真。 [ -c FILE ] 如果 FILE 存在且是一个字符文件则返回为真。 [ -d FILE ] 如果 FILE 存在且是一个目录则返回为真。 [ -e FILE ] 如果 指定的文件或目录存在时返回为真。HCIA-openEuler 实验指导手册 第 121 页 [ -f FILE ] 如果 FILE 存在且是一个普通文件则返回为真。 [ -g FILE ] 如果 FILE 存在且设置了 SGID 则返回为真。 [ -h FILE ] 如果 FILE 存在且是一个符号符号链接文件则返回为真。(该选项在一些老系统上 无效) [ -k FILE ] 如果 FILE 存在且已经设置了冒险位则返回为真。 [ -p FILE ] 如果 FILE 存并且是命令管道时返回为真。 [ -r FILE ] 如果 FILE 存在且是可读的则返回为真。 [ -s FILE ] 如果 FILE 存在且大小非 0 时为真则返回为真。 [ -u FILE ] 如果 FILE 存在且设置了 SUID 位时返回为真。 [ -w FILE ] 如果 FILE 存在且是可写的则返回为真。(一个目录为了它的内容被访问必然是 可执行的) [ -x FILE ] 如果 FILE 存在且是可执行的则返回为真。 [ -O FILE ] 如果 FILE 存在且属有效用户 ID 则返回为真。 [ -G FILE ] 如果 FILE 存在且默认组为当前组则返回为真。(只检查系统默认组) [ -L FILE ] 如果 FILE 存在且是一个符号连接则返回为真。 [ -N FILE ] 如果 FILE 存在 and has been mod 如果 ied since it was last read 则返回为 真。 [ -S FILE ] 如果 FILE 存在且是一个套接字则返回为真。 [ FILE1 -nt FILE2 ] 如果 FILE1 比 FILE2 新, 或者 FILE1 存在但是 FILE2 不存在则返回为 真。 [ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 老, 或者 FILE2 存在但是 FILE1 不存在则返回为 真。 [ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则返回为真。  字符串判断 [ -z STRING ] 如果 STRING 的长度为零则返回为真,即空是真 [ -n STRING ] 如果 STRING 的长度非零则返回为真,即非空是真 [ STRING1 ] 如果字符串不为空则返回为真,与-n 类似 [ STRING1 == STRING2 ] 如果两个字符串相同则返回为真 [ STRING1 != STRING2 ] 如果字符串不相同则返回为真 [ STRING1 < STRING2 ] 如果 “STRING1”字典排序在“STRING2”前面则返回为真。 [ STRING1 > STRING2 ] 如果 “STRING1”字典排序在“STRING2”后面则返回为真。  数值判断 [ INT1 -eq INT2 ] INT1 和 INT2 两数相等返回为真,= [ INT1 -ne INT2 ] INT1 和 INT2 两数不等返回为真,<> [ INT1 -gt INT2 ] INT1 大于 INT2 返回为真,> [ INT1 -ge INT2 ] INT1 大于等于 INT2 返回为真,>= [ INT1 -lt INT2 ] INT1 小于 INT2 返回为真,< [ INT1 -le INT2 ] INT1 小于等于 INT2 返回为真,<=HCIA-openEuler 实验指导手册 第 122 页  逻辑判断 [ ! EXPR ] 逻辑非,如果 EXPR 是 false 则返回为真。 [ EXPR1 -a EXPR2 ] 逻辑与,如果 EXPR1 and EXPR2 全真则返回为真。 [ EXPR1 -o EXPR2 ] 逻辑或,如果 EXPR1 或者 EXPR2 为真则返回为真。 [ ] || [ ] 用 OR 来合并两个条件 [ ] && [ ] 用 AND 来合并两个条件 7.4.1.3 作业  编写一个脚本,该脚本可以判断当前用户是否为 root。  编写一个脚本,该脚本可以判断今天是否为休息日。 7.4.2 测试语句 步骤 1 新建脚本 ex5.sh,写入如下内容: #!/bin/bash echo "Please enter your filename:" read filename if [ -f "$filename" ] then cat $filename elif [ -d "$filename" ] then cd $filename pwd ls -l -a else echo "$filename:bad filename" fi 步骤 2 执行脚本 ex5.sh。 [root@openeuler ~]# chmod u+x ex5.sh [root@openeuler ~]# mkdir test [root@openeuler ~]# sh ex5.sh Please enter your filename: test /root/test total 8 drwx------. 2 root root 4096 Feb 18 11:29 . dr-xr-x---. 3 root root 4096 Feb 18 11:30 .. [root@openeuler ~]# sh ex5.sh Please enter your filename: ex3.sh echo "current directory is 'pwd'" echo "home directory is $HOME" echo "file*.?" echo "directory '$HOME'" 7.4.3 while 语句 步骤 1 新建脚本 ex6.sh,写入如下内容:HCIA-openEuler 实验指导手册 第 123 页 #!/bin/bash while [ $1 ] do if [ -f $1 ] then echo "display:$1" cat $1 else echo "$1 is not a file name" fi shift done 步骤 2 执行脚本 ex6.sh [root@openeuler ~]# sh ex6.sh ex3.sh display:ex3.sh echo "current directory is 'pwd'" echo "home directory is $HOME" echo "file*.?" echo "directory '$HOME'" [root@openeuler ~]# sh ex6.sh a a is not a file name 7.4.4 for 语句 步骤 1 新建脚本 ex7.sh,写入如下内容: #!/bin/bash for Num in {1..10} do echo $Num done 步骤 2 执行脚本 ex7.sh [root@openeuler ~]# sh ex7.sh 1 2 3 4 5 6 7 8 9 10 步骤 3 新建一个 namefile 文件,写入如下内容: user1 user2 user3HCIA-openEuler 实验指导手册 第 124 页 user4 步骤 4 新建脚本 ex8.sh,写入如下内容: #!/bin/bash for Name in $(cat ./namefile) do echo $Name done 步骤 5 执行脚本 ex8.sh。 [root@openeuler ~]# sh ex8.sh user1 user2 user3 user4 7.4.5 case 语句 步骤 1 新建脚本 ex9.sh,写入如下内容: #!/bin/bash echo 'Input a number between 1 to 4' printf 'Your number is:\n' read aNum case $aNum in 1) echo 'You select 1' ;; 2) echo 'You select 2' ;; 3) echo 'You select 3' ;; 4) echo 'You select 4' ;; *) echo 'You do not select a number between 1 to 4' ;; esac 步骤 2 执行脚本 ex9.sh。 [root@openEuler ~]# sh ex9.sh Input a number between 1 to 4 Your number is: 1 You select 1 7.5 作业  1 反向输出HCIA-openEuler 实验指导手册 第 125 页 - 当用户输入 yes,显示 no - 当用户输入 no,显示 yes - 当用户输入其它,提示用户输入 yes/no - 忽略大小写  新建用户 - 新建一个用户名列表 namefile - 新建一个脚本,该脚本能够实现根据 namefile 自动创建用户,且密码随机生成。用户创 建后将用户名和密码导入到/root/loginname.txt 中。 - 随机密码生成可以使用:openssl rand -base64 6  脚本实现输出机器信息 - 将本机的网卡的 IP 地址和 MAC 地址截取出来,输出到/root/nic - 将本机的磁盘使用情况截取出来 输出到 /root/disk - 判断系统空间使用的情况,如果 / 使用率大于 30% 则删除 /tmp 的内容  测试用户是否存在,并判断是否是超级用户 - 写一个脚本:如果指定的用户存在,先说明其已经存在,并显示其 ID 号和 SHELL,并判 断是否是超级用户;否则,就创建用户,并显示其 ID 号  创建或目录文件 - 该脚本应当有交互功能 - 该脚本用于备份系统目录 - 需要给予用户提示,提示用户应当输入目录或者文件名 - 判断用户要备份的文件是否存在,如果不存在则告知用户,并输出相应错误 - 判断用户要备份的目标目录是否存在,如果该目录不存在,则需要问用户是否创建,如果 该目录已经存在,则需要问用户是否重命名该目录  测试 IP 是否可达 - 根据 iplist.txt 文件中列举的 IP 地址,判断 IP 地址是否可达。 - 只显示可达的 IP 地址。(不可达的可以使用 >> /dev/null)  输出名片 - 交互式输入自己信息,提示信息输入; - 输入完成所有个人信息后,一次性打印出个人所有信息,并要求输出格式美观。
4 个赞