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’

;;

  1. echo ‘You select 2’

;;

  1. echo ‘You select 3’

;;

  1. 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 Likes