【Linux命令】《鸟哥Linux基础》第十二章 学习shell脚本

第十二章 学习shell脚本

通常利用shell脚本完成服务器的检测工作,不涉及大量运算。

12.1 简单shell脚本介绍

12.2 简单shell脚本练习

12.2.1 简单范例

范例1:永远的开端Helloworld

cat hello.sh 
输出:
#!/bin/bash   
#Program:
#	This program shows "hello world!" in your screen.
#History:
#2020/06/07	dj	First release
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "hello world! \a \n"
exit 0

#! 用来声明这个脚本使用的shell版本。
注释包括:

  1. 脚本的内容与功能;
  2. 脚本的版本信息;
  3. 脚本的作者与联系方式;
  4. 脚本的版权生命方式;
  5. 建立文件日期;
  6. 脚本的历史记录History;
  7. 脚本内较特殊的命令,使用【绝对路径】的方式执行;给与足够的注释;
  8. 脚本运行时需要的环境变量预先声明和设置。
chmod a+x hello.sh	 给3者都加上x的权限,这3者指的是文件所有者、文件所属组、其他人

范例2:与用户交互

cat showname.sh 
输出:
#!bin/bash
#Program:
#	User inputs his first name and last name. Program shows his full name.
#History:
#2020/06/08	dj	First relese
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input your first name:" firstname
read -p "Please input your last name:" lastname
echo -e "\nYour full name is: ${firstname} ${lastname}"

范例3:随日期变化的文件名

cat create_3_filename.sh 
输出:
#!/bin/bash
#Program:
#	Program create three files,which named by user's input and date command.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1.get file name from user
echo -e "I will use 'touch' command to create 3 files."
read -p "Please input your file name:" fileuser

# 2.
filename=${fileuser:-"filename"}

# 3.get file name from date
date1=$(date --date='2 days ago' +%Y%m%d)
date2=$(date --date='1 days ago' +%Y%m%d)
date3=$(date +%Y%m%d)
file1=${filename}${date1}
file2=${filename}${date2}
file3=${filename}${date3}

# 4.create file
touch "${file1}"
touch "${file2}"
touch "${file3}"

需要注意,date1=$(date --date='2 days ago' +%Y%m%d)'2 days ago'%Y%m%d之间务必要有一个空格!

[dj@study bin]$ sh create_3_filename.sh 
I will use 'touch' command to create 3 files.
Please input your file name:djTest
[dj@study bin]$ ll
总用量 12
-rw-rw-r--. 1 dj dj 674 6月   8 11:13 create_3_filename.sh
-rw-rw-r--. 1 dj dj   0 6月   8 11:10 djTest
-rw-rw-r--. 1 dj dj   0 6月   8 11:13 djTest20200606		这里可以看到新建的三个文件
-rw-rw-r--. 1 dj dj   0 6月   8 11:13 djTest20200607		这里可以看到新建的三个文件
-rw-rw-r--. 1 dj dj   0 6月   8 11:13 djTest20200608		这里可以看到新建的三个文件
-rwxrwxr-x. 1 dj dj 224 6月   7 20:14 hello.sh
-rw-rw-r--. 1 dj dj 370 6月   8 10:57 showname.sh

范例4:求两个整数的乘积(bash shell里只能算整数)

cat multiplying.sh 
输出:
#!/bin/bash
# Program:
#	User inputs 2 integer numbers;program will cross these two numbers.
# History:
# 2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo -e "You SHOULD input 2 numbers,I will multiplying them!\n"
read -p "first number:" firstnumber
read -p "second number:" secondnumber
total=$((${firstnumber}*${secondnumber}))
declare -i total1=${firstnumber}*${secondnumber}
echo -e "\nThe result of ${firstnumber} x ${secondnumber} is ==> ${total}"
echo -e "\nThe result of ${firstnumber} x ${secondnumber} is ==> ${total1}"

命令执行情况:

[dj@study bin]$ sh multiplying.sh 
You SHOULD input 2 numbers,I will multiplying them!

first number:10
second number:6

The result of 10 x 6 is ==> 60

The result of 10 x 6 is ==> 60

说明这两种计算方式都是可以的:

total=$((${firstnumber}*${secondnumber}))
declare -i total1=${firstnumber}*${secondnumber}

推荐:

var=$((运算内容))

通过bc命令协助,计算含有小数点的数。

echo "123.123*2.3"|bc
输出:
283.182

范例5:利用bc求圆周率Pi

cat cal_pi.sh 
输出:
#!/bin/bash
#Program:
#	User input a scale number to calculate pi number.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo -e "This program will calculate pi value.\n"
echo -e "You should input a float number to calculate pi value.\n"
read -p "The scale number (10~10000) ? " checking
num=${checking:-"10"}
echo -e "Starting calculate pi value. Be paient."
time echo "scale=${num};4*a(1)" | bc -lq

其中,4*a(1)是bc提供的一个计算Pi的函数。运行情况:

[dj@study bin]$ sh cal_pi.sh 
This program will calculate pi value.

You should input a float number to calculate pi value.

The scale number (10~10000) ? 10
Starting calculate pi value. Be paient.
3.1415926532

real	0m0.004s
user	0m0.002s
sys	0m0.002s

12.2.2 脚本执行方式的差异(source、sh script、./script)

利用直接执行的方式执行脚本,绝对路径、相对路径、${PATH}内、利用bash、利用sh,该脚本都会使用一个新的bash环境来执行脚本内的命令。是在子进程中执行的。 执行完毕后,所有数据被删除,父进程中读取不到。

利用source来执行脚本,在父进程中执行。 执行完毕后,数据都保留在父进程中。因此,为了让更新后的~/.bashrc生效,需要使用source ~/.bashrc,而不能用bash ~/.bashrc

12.3 善用判断式

$? && ||

12.3.1 利用test命令的测试功能

test用来检测系统上某些文件或是相关属性。

test -e /dj			检查这个文件或目录是否存在,执行后不会显示任何信息

搭配 $?&&|| 来展现结果:

test -e /dj  &&  echo "exist" || echo "Not exist"	如果文件存在,继续执行&&右边的,否则,忽略&&直接执行||右边的

关于test的参数,书本第396页有个巨大的表格,可以参考。
常用如下:

测试的参数 意义
-e 看文件是否存在
-f 看文件是否存在且为文件
-d 看文件是否存在且为目录
cat file_perm.sh
输出:
#!/bin/bash
#Program:
#	User input a filename,program will check the following:
#	1)exist? 2)file/directory? 3)file permissions
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/.bashrc
export PATH

# 1. 检查用户输入的内容是否为空
echo -e "Please input a filename,I will check the filename's type and permission.\n\n"
read -p "Input a filename:" filename
test -z ${filename}  && echo "You MUST input a filename."  && exit 0

# 2. 判断文件是否存在,不存在就退出
test ! -e ${filename} && echo "The filename '${filename}' DO NOT EXIST" && exit 0

# 3. 判断是文件还是目录;判断权限
test -f ${filename} && filetype="regular file"
test -d ${filename} && filetype="directory"
test -r ${filename} && perm="readable"
test -w ${filename} && perm="${perm} writable"
test -x ${filename} && perm="${perm} executable"

# 4. 输出判断结果
echo "The filename: ${filename} is a ${filetype}"
echo "And the permissions for you are:${perm}"

执行结果:

[dj@study bin]$ sh file_perm.sh 
Please input a filename,I will check the filename's type and permission.


Input a filename:/home/dj
The filename: /home/dj is a directory
And the permissions for you are:readable writable executable

12.3.2 利用判断符号[]

判断变量${HOME}是否为空:
[ -z "${HOME}" ];echo $?	尤其注意,中括号[右侧有一个空格,中括号]左侧也有一个空格,否则报错
输出:
1

范例6:利用[]做判断

cat ans_yn.sh 
输出:
#!/bin/bash
#Program:
#	This program shows the user's choice
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input (Y/N):" yn
[ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK,continue" && exit 0
[ "${yn}" == "N" -o "${yn}" == "n" ] && echo "Oh,interrupt!" && exit 0
echo "I donot know what your choice is" && exit 0

执行结果:

[dj@study bin]$ sh ans_yn.sh 
Please input (Y/N):
I donot know what your choice is
[dj@study bin]$ sh ans_yn.sh 
Please input (Y/N):y
OK,continue
[dj@study bin]$ sh ans_yn.sh 
Please input (Y/N):N
Oh,interrupt!

12.3.3 shell脚本的默认变量($0、$1…)

/path/to/scriptname		opt1	opt2	opt3
		$0				 $1		 $2		 $3
特殊变量 意义
$# 后接的参数个数,此处未3
$@ “$1” “$2” “$3”,每个变量是独立的
$* “$1c$2c$3”,c为分隔字符,默认为空格

范例7:输出当前执行命令的参数信息

cat show_paras.sh 
输出:
#!/bin/bash
#Program:
#	Program shows the script name,parameters...
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "The script name is ===>  ${0}"
echo "Total parameter number is ===>  $#"
[ "$#" -lt 2 ] && echo "The number of parameters is less than 2. Stop here." && exit 0
echo "Your whole parameters is  ===>  '$@'"
echo "The 1st parameter  ===>  ${1}"
echo "The 2nd parameter  ===>  ${2}"

执行情况:

sh show_paras.sh theone thetwo thethree
The script name is ===>  show_paras.sh
Total parameter number is ===>  3
Your whole parameters is  ===>  'theone thetwo thethree'
The 1st parameter  ===>  theone
The 2nd parameter  ===>  thetwo

范例8:shift的使用,拿掉最前面几个参数

cat shift_paras.sh 
#!/bin/bash
#Program:
#	Program shows the effect of shift function.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"

shift
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"

shift 3
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"

执行情况:

[dj@study bin]$ sh shift_paras.sh theone thetwo thethree thefour thefive thesix
Total parameter number is ==> 6
Your whole parameter is ==> 'theone thetwo thethree thefour thefive thesix'
Total parameter number is ==> 5
Your whole parameter is ==> 'thetwo thethree thefour thefive thesix'
Total parameter number is ==> 2
Your whole parameter is ==> 'thefive thesix'

12.4 条件判断式

if then

12.4.1 利用if…then

简单的版本:

if [条件判断式]; then
	条件判断式成立时,进行的命令工作内容;
fi

范例9:用if…then改写范例6

cat ans_yn-2.sh 
输出:
#!/bin/bash
#Program:
#	This program shows the user's choice
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input (Y/N):" yn
if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; then
	echo "OK,continue" 
	exit 0
fi

if [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; then
	echo "Oh,interrupt!"
	exit 0
fi
echo "I donot know what your choice is" && exit 0

复杂的版本:

if [条件判断式]; then
	条件判断式成立时,进行的命令工作内容;
else
	条件判断式不成立时,进行的命令工作内容;
fi

更复杂的版本:

if [条件判断式1]; then
	条件判断式1成立时,进行的命令工作内容;
elif [条件判断式2]; then
	条件判断式2成立时,进行的命令工作内容;
else
	条件判断式1和2都不成立时,进行的命令工作内容;
fi

范例10:用if…elif…then改写范例6

cat ans_yn-3.sh 
#!/bin/bash
#Program:
#	This program shows the user's choice
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input (Y/N):" yn
if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; then
	echo "OK,continue" 
	exit 0
elif [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; then
	echo "Oh,interrupt!"
	exit 0
else
	echo "I donot know what your choice is" && exit 0
fi

范例11:判断用户输入的额外指令

cat hello-2.sh 
输出:
#!/bin/bash
#Program:
#	This program check $1 is equal to "hello"
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

if [ "${1}" == "hello" ];then
	echo "Hello,how are you?"
elif [ "${1}" == "" ];then
	echo "You MUST input parameters,ex> { ${0} someword }"
else 
	echo "The only parameter is 'hello',ex> {${0} hello}"
fi

范例12:查看自己的主机是否开启了主要的网络服务端口

命令netstat,可以查询到目前主机开启的网络服务端口。
每个端口都有其特定的网络服务,常见的端口与相关网络服务:

端口 服务
80 WWW
22 ssh
21 ftp
25 mail
111 RPC(远程过程调用)
631 CUPS(打印服务功能)
netstat -tuln
输出:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN     
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp6       0      0 ::1:631                 :::*                    LISTEN     
tcp6       0      0 ::1:25                  :::*                    LISTEN     
tcp6       0      0 :::111                  :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
udp        0      0 0.0.0.0:908             0.0.0.0:*                          
udp        0      0 0.0.0.0:44545           0.0.0.0:*                          
udp        0      0 192.168.122.1:53        0.0.0.0:*                          
udp        0      0 0.0.0.0:67              0.0.0.0:*                          
udp        0      0 0.0.0.0:111             0.0.0.0:*                          
udp        0      0 0.0.0.0:5353            0.0.0.0:*                          
udp6       0      0 :::908                  :::*                               
udp6       0      0 :::111                  :::*  
cat netstat.sh 
输出:
#!/bin/bash
#Program:
#	Using netstat and grep to detect WWW,SSH,FTP and Mail service.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1.
echo "Now,I will detect your linux server's services!"
echo -e "The www,ftp,ssh,mail(smtp) will be detect!\n"

# 2.
testfile=/dev/shm/netstat_checking.txt
netstat -tuln > ${testfile}
testing=$(grep ":80" ${testfile})
if [ "${testing}" != "" ];then				
	echo "WWW is running in your system."
fi

testing=$(grep ":22" ${testfile})
if [ "${testing}"!="" ];then
	echo "SSH is running in your system."
fi

testing=$(grep ":21" ${testfile})
if [ "${testing}"!="" ];then
	echo "FTP is running in your system."
fi

testing=$(grep ":25" ${testfile})
if [ "${testing}"!="" ];then
	echo "MAIL is running in your system."
fi

注意:if [ "${testing}" != "" ];thenif[之间有个空格,不能缺少。
执行情况:

[dj@study bin]$ sh netstat.sh 
Now,I will detect your linux server's services!
The www,ftp,ssh,mail(smtp) will be detect!

SSH is running in your system.
FTP is running in your system.
MAIL is running in your system.

12.4.2 利用case…esac判断

case $变量名称 in
 "第一个变量内容")
 	程序段
 	;;
 "第二个变量内容")
	程序段
	;;
 *)		
 	程序段
 	;;
esac

*表示其他所有情况。

12.4.3 利用function功能

function fname(){
	程序段	
}

范例13:打印用户的选择,one、two、three

cat show123.sh 
输出:
#!/bin/bash
#Program:
#	Use function to repeat information.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

function printit(){
	echo -n "Your choice is "
}
echo "This program will print your selection!"
case ${1} in
 "one")
 	printit;echo ${1} | tr 'a-z' 'A-Z'
	;;
 "two")
 	printit;echo ${1} | tr 'a-z' 'A-Z'
	;;
 "three")
 	printit;echo ${1} | tr 'a-z' 'A-Z'
	;;
 *)
 	echo "Usage ${0} {one|two|three}"
	;;
esac

函数function内部也有$0 $1 $2...这种变量,容易与shell脚本的$0 $1 $2...搞混.

12.5 循环(loop)

12.5.1 while do done、until do done(不定循环)

while [ condition ]
do
	程序段落
done
until [ condition ]
do 
	程序段落
done

范例14:循环直到用户输入正确的字符

使用while:

cat yes_to_stop.sh 
输出:
#!/bin/bash
#Program:
#	Repeat question until user input correct answer.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

while [ "${yn}" != "yes" -a "${yn}" != "YES" ]
do
	read -p "Please input yes/YES to stop this program: " yn
done

echo "OK! you input the correct answer."

使用until:

cat yes_to_stop-2.sh 
输出:
#!/bin/bash
#Program:
#	Repeat question until user input correct answer.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

while [ "${yn}" == "yes" -a "${yn}" == "YES" ]    只需要修改这里为==即可
do
	read -p "Please input yes/YES to stop this program: " yn
done

echo "OK! you input the correct answer."

范例15:用循环计算1+2+3+…+100

cat cal_1_100.sh 
输出:
#!/bin/bash
#Program:
#	Use loop to calculate "1+2+3+4+5+...+100" result.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

s=0
i=0

while [ "${i}" !=  "100" ]
do 
	i=$(($i + 1))
	s=$(($s+$i))
done
echo "The result of '1+2+3+...+100' is ==> $s"

执行情况:

sh cal_1_100.sh 
输出:
The result of '1+2+3+...+100' is ==> 5050

范例16:范例15中最大数n由用户指定,1+2+3+…+user_input

cat cal_1_100.sh 
输出:
#!/bin/bash
#Program:
#	User input n,I will use loop to calculate "1+2+3+4+5+...+n" result.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input n:" n
s=0
i=0
while [ "${i}" != "${n}" ]
do 
	i=$(($i + 1))
	s=$(($s+$i))
done
echo "The result of '1+2+3+...+ '${n} is ==> $s"

执行情况:

sh cal_1_100.sh 
Please input n:10
The result of '1+2+3+...+ '10 is ==> 55

12.5.2 for…do…done(固定循环)

前面while和until都是必须要符合某个条件,而for是已知要进行几次循环。

for var in con1 con2 con3...
do 
	程序段
done

范例17:检查用户的标识符和特殊参数

通过管道命令的cut识别出单纯的账号名称,以id分别检查用户的标识符与特殊参数。

cat userid.sh 
输出:
#!/bin/bash
#Program:
#	Use id,finger command to check system account's information.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

users=$(cut -d ':' -f1 /etc/passwd)
for username in ${users}
do 
	id ${username}
done
sh userid.sh
输出:
uid=0(root) gid=0(root)=0(root)
uid=1(bin) gid=1(bin)=1(bin)
uid=2(daemon) gid=2(daemon)=2(daemon)
uid=3(adm) gid=4(adm)=4(adm)
...
uid=38(ntp) gid=38(ntp)=38(ntp)
uid=72(tcpdump) gid=72(tcpdump)=72(tcpdump)
uid=1000(dj) gid=1000(dj)=1000(dj),10(wheel)

范例18:检查192.168.1.1~192.168.1.100共100台主机目前是否与自己的主机连通

cat pingip.sh 
输出:
#!/bin/bash
#Program:
#	Use ping command to check the network's PC state.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

network="192.168.1"
for sitenu in $(seq 1 100)
do
	ping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1
	if [ "${result}" == 0 ];then
		echo "Server ${network}.${sitenu} is UP."
	else 
		echo "Server ${network}.${sitenu} is DOWN."
	fi
done

此处, $(seq 1 100)可以用{1..100}替换。类似的,连续输出a-g的字符,echo {a..g}

范例19:用户输入一个目录,程序找出目录内所有文件名的权限

cat dir_perm.sh 
输出:
#!/bin/bash
#Program:
#	User input dir name,I find the permission of files.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1.
read -p "Please input a directory: " dir
if [ "${dir}" == "" -o ! -d "${dir}" ];then
	echo "The ${dir} is NOT exist in your system."
	exit 1
fi

# 2.
filelist=$(ls ${dir})
for filename in ${filelist}
do 
	perm=""
	test -r "${dir}/${filename}" && perm="${perm} readable"
	test -w "${dir}/${filename}" && perm="${perm} writable"
	test -x "${dir}/${filename}" && perm="${perm} executable"
	echo "The file ${dir}/${filename}'s permission is ${perm}"
done

执行情况:

sh dir_perm.sh 
输出:
Please input a directory: /home/dj
The file /home/dj/a2's permission is  readable writable executable
The file /home/dj/bin's permission is  readable writable executable
The file /home/dj/catfile's permission is  readable writable
The file /home/dj/homefile's permission is  readable writable
The file /home/dj/last.list's permission is  readable writable
The file /home/dj/list_error's permission is  readable writable
The file /home/dj/list_right's permission is  readable writable
The file /home/dj/regular_express.txt's permission is  readable writable
The file /home/dj/公共's permission is  readable writable executable
The file /home/dj/模板's permission is  readable writable executable
The file /home/dj/视频's permission is  readable writable executable
The file /home/dj/图片's permission is  readable writable executable
The file /home/dj/文档's permission is  readable writable executable
The file /home/dj/下载's permission is  readable writable executable
The file /home/dj/音乐's permission is  readable writable executable
The file /home/dj/桌面's permission is  readable writable executable

12.5.3 for…do…done的数值处理

for (( 初始值;限制值;赋值运算 ))
do
	程序段
done

范例20:同范例16,范例15中最大数n由用户指定,1+2+3+…+user_input

cat cal_1_100-2.sh 
输出:
#!/bin/bash
#Program:
#	Try to calculate 1+2+3+...+${your_input}
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input a number, I will count for 1+2+3+...+your_input:" nu
s=0
for (( i=1;i<=${nu};i=i+1 ))
do	
	s=$((${s}+${i}))
done
echo "The result of '1+2+3+...+${nu}' is ==> ${s}"

执行情况:

sh cal_1_100-2.sh 
输出:
Please input a number, I will count for 1+2+3+...+your_input:10
The result of '1+2+3+...+10' is ==> 55

12.5.4 搭配随机数与数组的实验

这里面的逻辑有些理不顺,后续继续学习。

cat what_to_eat.sh 
输出:
#!/bin/bash
#Program:
#	Try do tell you what you may eat.
#History:
#2020/06/08	dj	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

eat[1]="maidangdanghanbao1"
eat[2]="maidangdanghanbao2"
eat[3]="maidangdanghanbao3"
eat[4]="maidangdanghanbao4"
eat[5]="maidangdanghanbao5"
eat[6]="maidangdanghanbao6"

eatnum=6
eated=0
while [ "${eated}" -lt 3 ];do
	check=$(( ${RANDOM} * ${eatnum} / 32767 + 1))
	mycheck=0
	if [ "${eated}" -ge 1 ];then
		for i in  $(seq 1 ${eated})
		do 
			if [ ${eatedcon[$i]} == $check ];then
				mycheck=1
			fi
		done
	fi
	if [ ${mycheck} == 0 ];then
		echo "you may eat ${eat[${check}]}"
		eated=$(( ${eated} + 1 ))
		eatedcon[${eated}]=${check}
	fi
done

运行情况:

sh what_to_eat.sh 
you may eat maidangdanghanbao1
you may eat maidangdanghanbao4
you may eat maidangdanghanbao5

12.6 脚本的跟踪与调试

sh [-nvx] scripts.sh
	  -n  不要执行脚本,仅检查语法问题
	  -v  在执行脚本前,现将脚本文件内容输出到屏幕上
	  -x  将使用到的脚本内容显示到屏幕上(相当有用)

sh -x scripts.sh   进行程序的debug

你可能感兴趣的:(Linux基础,脚本语言)