第十二章 学习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 PATHecho -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:6The result of 10 x 6 is ==> 60The 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 PATHecho -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.1415926532real    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 PATHread -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 PATHecho "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 PATHecho "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 PATHread -p "Please input (Y/N):" yn
if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; thenecho "OK,continue" exit 0
fiif [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; thenecho "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 PATHread -p "Please input (Y/N):" yn
if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; thenecho "OK,continue" exit 0
elif [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; thenecho "Oh,interrupt!"exit 0
elseecho "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 PATHif [ "${1}" == "hello" ];thenecho "Hello,how are you?"
elif [ "${1}" == "" ];thenecho "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."
fitesting=$(grep ":22" ${testfile})
if [ "${testing}"!="" ];thenecho "SSH is running in your system."
fitesting=$(grep ":21" ${testfile})
if [ "${testing}"!="" ];thenecho "FTP is running in your system."
fitesting=$(grep ":25" ${testfile})
if [ "${testing}"!="" ];thenecho "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 PATHfunction 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 PATHwhile [ "${yn}" != "yes" -a "${yn}" != "YES" ]
doread -p "Please input yes/YES to stop this program: " yn
doneecho "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 PATHwhile [ "${yn}" == "yes" -a "${yn}" == "YES" ]    只需要修改这里为==即可
doread -p "Please input yes/YES to stop this program: " yn
doneecho "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 PATHs=0
i=0while [ "${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 PATHread -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 PATHusers=$(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 PATHnetwork="192.168.1"
for sitenu in $(seq 1 100)
doping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1if [ "${result}" == 0 ];thenecho "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}" ];thenecho "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 PATHread -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 PATHeat[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 ];docheck=$(( ${RANDOM} * ${eatnum} / 32767 + 1))mycheck=0if [ "${eated}" -ge 1 ];thenfor i in  $(seq 1 ${eated})do if [ ${eatedcon[$i]} == $check ];thenmycheck=1fidonefiif [ ${mycheck} == 0 ];thenecho "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命令】《鸟哥Linux基础》第十二章 学习shell脚本相关推荐

  1. Linux随笔-鸟哥Linux基础篇学习总结(全)

    Linux随笔-鸟哥Linux基础篇学习总结(全) 修改Linux系统语系:LANG-en_US,如果我们想让系统默认的语系变成英文的话我们可以修改系统配置文件:/etc/sysconfig/i18n ...

  2. linux脚本求命令行上整数和,《Linux命令行与shell脚本编程大全》 第二十二章 学习札记...

    <Linux命令行与shell脚本编程大全> 第二十二章 学习笔记 第二十二章:使用其他shell 什么是dash shell Debian的dash shell是ash shell的直系 ...

  3. 工程伦理第十二章学习笔记2020最新

    工程伦理第十二章学习笔记2020最新 继续更新

  4. Linux云计算【第一阶段】第十二章:网络管理、进制及SSH管理与攻防

    第十二章:网络管理及SSH管理与攻防 [重难点] 一.网络发展概述 局域网 城域网 广域网 基本网络协议 客户端与服务器的概念 从客户端到服务器的经过 No.1 客户端与服务器的概念 客户端: 即表示 ...

  5. 《构建之法》第十一、十二章学习总结

    第十一章的内容是软件设计与实现. 在第一节中,讲的是关于分析和设计方法,向我们介绍在"需求分析"."设计与实现"阶段."测试""发 ...

  6. 财务管理基础 第十二章 现金流量估算与风险分析

    1. 现金流量分析的其他因素 现金流量与会计收入:与资本预算相关的是项目的现金流量,而非会计收入.净收入的计算是依据会计人员选择的折旧率以及利息费用.但折旧不算入现金流量中. 现金流量的时间分布:理论 ...

  7. dx12 龙书第十二章学习笔记 -- 几何着色器

    如果不启用曲面细分(tessellation)这一环节,那么几何着色器(geometry shader)这个可选阶段便会位于顶点着色器与像素着色器之间.顶点着色器以顶点作为输入数据,而几何着色器的输入 ...

  8. 鸟哥的Linux私房菜(服务器)- 第十二章、网络参数控管者: DHCP 服务器

    第十二章.网络参数控管者: DHCP 服务器 最近更新日期:2011/07/27 想象两种情况:(1)如果你在工作单位使用的是笔记本电脑,而且常常要带着你的笔记本电脑到处跑, 那么由第四章.连上 In ...

  9. 鸟哥的Linux私房菜(服务器)- 第二十二章、邮件服务器: Postfix

    第二十二章.邮件服务器: Postfix 最近更新日期:2011/08/10 在这个邮件服务器的架设中,我们首先谈论 Mail 与 DNS 的重要相关性,然后依序介绍 Mail Server 的相关名 ...

最新文章

  1. vc++ 将可执行文件链接到 DLL
  2. 普中科技开发板使用说明书_百度大脑加持,米尔科技FZ3深度学习计算卡评测
  3. C++学习之路 | PTA(天梯赛)—— L2-007 家庭房产 (25分)(带注释)(并查集)(精简)
  4. php gis,对php代码混淆的研究
  5. 疫情风向标?苹果宣布将暂时关闭大中华区以外的所有苹果零售店!
  6. Python入门学习笔记(3)
  7. Objective-C GCD深入理解
  8. Spring Boot内嵌的tomcat日志
  9. 风尚云网学习-vue后台管理之金额大小写转换实例【精准到分0.01】保姆级教程
  10. Scintilla教程(4): 复制粘贴以及撤销回退
  11. android程序设计学习,android编程入门很简单 android编程入门自学
  12. 北疆游记 - 照片在左边相册
  13. java连接打印机_JAVA连接打印机详解(有驱动,无驱动两种方式)
  14. 重庆ETC学员“食神大赛”
  15. 视频会议让教育培训插上腾飞的翅膀!
  16. mac 安装问题汇总
  17. java win7 管理员权限_win7系统一键取得管理员权限的操作方法
  18. 记Elsevier上Latex投稿
  19. 微信引流推广:美拍视频简单的引流方法分享
  20. html怎么显示一个点赞的心形,jquery心形点赞关注效果的简单实现

热门文章

  1. 千鸟配送获1000万元天使轮融资,同城货运烧钱大战之后的冷静思考?
  2. mysqlinstaller安装教程80
  3. msu后缀文件的脚本安装
  4. sumo之加入货运车辆
  5. 2021WSB-day2-1 - Anil Jain教授讲述了生物特征识别的定义,为何用生物特征识别,以及过去,现在和将来
  6. 修改jupyter notebook中的字体
  7. 将一个图片切割成多个图片
  8. Java基础之在窗口中绘图——使用模型/视图体系结构在视图中绘图(Sketcher 1 drawing a 3D rectangle)...
  9. 图片转文字怎么转换?这个方法不能错过
  10. PlutoSDR + SoapySdr