【13.1】什么是shell script?
1)shell script 是利用 shell 的功能所写的一个『程序 (program)』,这个程序是使用纯文字档,将一些 shell 的语法与命令(含外部命令)写在里面, 搭配正规表示法、管线命令与数据流重导向等功能,以达到我们所想要的处理目的。

  • 1.1)简单的说, shell script 就像是早期 DOS 年代的批量档 (.bat) ,最简单的功能就是将许多命令汇整写在一起, 让使用者很轻易的就能够 one touch 的方法去处理复杂的动作 (运行一个文件 "shell script" ,就能够一次运行多个命令)。 而且 shell script 更提供阵列、回圈、条件与逻辑判断等重要功能,让使用者也可以直接以 shell 来撰写程序,而不必使用类似 C 程序语言等传统程序撰写的语法呢!
  • 1.2)shell script 可以简单的被看成是批量档, 也可以被说成是一个程序语言,且这个程序语言由於都是利用 shell 与相关工具命令, 所以不需要编译即可运行,且拥有不错的除错 (debug) 工具,所以,他可以帮助系统管理员快速的管理好主机。

2)shell script 用在系统管理上面是很好的一项工具,但是用在处理大量数值运算上, 就不够好了,因为 Shell scripts 的速度较慢,且使用的 CPU 资源较多,造成主机资源的分配不良。还好, 我们通常利用 shell script 来处理服务器的侦测,倒是没有进行大量运算的需求啊!所以不必担心的啦!

【13.1.2】第一个 script 的编写与执行
1)shell编写规则:在 shell script 的撰写中还需要用到底下的注意事项:

  • 1. 命令的运行是从上而下、从左而右的分析与运行;
  • 2. 命令的下达就如同第五章内提到的: 命令、选项与参数间的多个空白都会被忽略掉;
  • 3. 空白行也将被忽略掉,并且 [tab] 按键所推开的空白同样视为空白键;
  • 4. 如果读取到一个 Enter 符号 (CR) ,就尝试开始运行该行 (或该串) 命令;
  • 5. 至於如果一行的内容太多,则可以使用『 \[Enter] 』来延伸至下一行;
  • 6. 『 # 』可做为注解!任何加在 # 后面的数据将全部被视为注解文字而被忽略!

2)shell执行方式:假设你写的这个程序档名是 /home/dmtsai/shell.sh 好了,那如何运行这个文件?很简单,可以有底下几个方法:
  ● 直接命令下达: shell.sh 文件必须要具备可读与可运行 (rx) 的权限,然后:
      ○ 绝对路径:使用 /home/dmtsai/shell.sh 来下达命令;
      ○ 相对路径:假设工作目录在 /home/dmtsai/ ,则使用 ./shell.sh 来运行
      ○ 变量『PATH』功能:将 shell.sh 放在 PATH 指定的目录内,例如: ~/bin/

● 以 bash 程序来运行:透过『 bash shell.sh 』或『 sh shell.sh 』来运行
补充:那为何『 sh shell.sh 』也可以运行呢?这是因为 /bin/sh 其实就是 /bin/bash (连结档),使用 sh shell.sh 亦即告诉系统,我想要直接以 bash 的功能来运行 shell.sh 这个文件内的相关命令的意思,所以此时你的 shell.sh 只要有 r 的权限即可被运行喔!

3)编写第1个shell script

#!/bin/bash
# Program:
#       This program shows "Hello World!" in your screen.
# History:
# 2005/08/23    VBird   First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Hello World! \a \n"
exit 0 

(1)
【13.1.3】编写shell script的良好习惯
1)建议你一定要养成良好的 script 撰写习惯,在每个 script 的档头处记录好:
  ● script 的功能;
  ● script 的版本资讯;
  ● script 的作者与联络方式;
  ● script 的版权宣告方式;
  ● script 的 History (历史纪录);
  ● script 内较特殊的命令,使用『绝对路径』的方式来下达;
  ● script 运行时需要的环境变量预先声明与设置。

【13.2】简单的shell script练习
【13.2.1】简单范例

1)交互式脚本:变量内容由用户决定
请你以 read 命令的用途,撰写一个 script ,他可以让使用者输入:1. first name 与 2. last name, 最后并且在萤幕上显示:『Your full name is: 』的内容:
(2)

#!/bin/bash
# Program:
#       User inputs his first name and last name.  Program shows his full name.
# History:
# 2005/08/23    VBird   First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATHread -p "Please input your first name: " firstname  # 提示使用者输入
read -p "Please input your last name:  " lastname   # 提示使用者输入
echo -e "\nYour full name is: $firstname $lastname" # 结果由萤幕输出

2)随日期变化:利用日期进行文件的创建:
假设我想要创建三个空文件(透过touch) ,档名最开头由使用者输入决定,假设使用者输入 filename 好了,那今天的日期是 2009/02/14 , 我想要以前天、昨天、今天的日期来创建这些文件,亦即 filename_20090212, filename_20090213, filename_20090214 ,该如何是好?

[root@localhost scripts]# vim sh03.sh
#!/bin/bash
# Program:
#       Program creates three files, which named by user's input
#       and date command.
# History:
# 2018/05/01    tang rong       First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH# 1. 让使用者输入文件名称,并取得 fileuser 这个变量;
echo -e "I will use 'touch' command to create 3 files." # 纯粹显示资讯
read -p "Please input your filename: " fileuser         # 提示使用者输入# 2. 为了避免使用者随意按 Enter ,利用变量功能分析档名是否有配置?
filename=${fileuser:-"filename"}           # 开始判断有否配置档名# 3. 开始利用 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. 将档名创建吧!
touch "$file1"                             # 底下三行在创建文件
touch "$file2"
touch "$file3"

(3)

(4)
3)数值运算:简单的加减乘除
如果我们要使用者输入两个变量, 然后将两个变量的内容相乘,最后输出相乘的结果,那可以怎么做?

(5)
补充:鸟哥比较建议使用这样的方式来进行运算:
var=$((运算内容))
不但容易记忆,而且也比较方便的多,因为两个小括号内可以加上空白字节喔! 未来你可以使用这种方式来计算的呀!至於数值运算上的处理,则有:『 +, -, *, /, % 』等等。 那个 % 是取余数啦~举例来说, 13 对 3 取余数,结果是 13=4*3+1,所以余数是 1 啊!就是:

(6)
【13.2.2】script的执行方式差别(source, sh script, ./script)
1)脚本的运行方式除了前面小节谈到的方式之外,还可以利用 source 或小数点 (.) 来运行喔!那么这种运行方式有何不同呢?
方式1)利用直接执行的方式来执行script
当使用前一小节提到的直接命令下达 (不论是绝对路径/相对路径还是 $PATH 内),或者是利用 bash (或 sh) 来下达脚本时, 该 script 都会使用一个新的 bash 环境来运行脚本内的命令!也就是说,使用这种运行方式时, 其实 script 是在子程序的 bash 内运行的!
重点在于:『当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回到父程序中』!

【荔枝】我们举刚刚提到过的 sh02.sh 这个脚本来说明好了,这个脚本可以让使用者自行配置两个变量,分别是 firstname 与 lastname,想一想,如果你直接运行该命令时,该命令帮你配置的 firstname 会不会生效?

(7)
1.2)利用source来执行脚本:在父进程中执行

(8)

【13.3】善用判断式

【13.3.1】利用test命令的测试功能
1)判断 /trong 这个目录存在与否
(9)
2)那我知道 -e 是测试一个『东西』在不在, 如果还想要测试一下该档名是啥玩意儿时,还有哪些标志可以来判断的呢?呵呵!有底下这些东西喔!
(10)
(11)
3)OK!现在我们就利用 test 来帮我们写几个简单的例子。首先,判断一下,让使用者输入一个档名,我们判断:

  • 判断1)这个文件是否存在,若不存在则给予一个『Filename does not exist』的信息,并中断程序;
  • 判断2)若这个文件存在,则判断他是个文件或目录,结果输出『Filename is regular file』或 『Filename is directory』;
  • 判断3)判断一下,运行者的身份对这个文件或目录所拥有的权限,并输出权限数据!

(12)
(13)

#!/bin/bash
# Program:
#       User input a filename, program will check the flowing:
#       1.) exist? 2.) file/directory? 3.) file permissions
# History:
# 2005/08/25    VBird   First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
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="regulare 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 are : $perm"

【13.3.2】利用判断符号[]
1)除了我们很喜欢使用的 test 之外,其实,我们还可以利用判断符号『 [ ] 』(就是中括号啦) 来进行数据的判断呢! 举例来说,如果我想要知道 $HOME 这个变量是否为空的,可以这样做:

(14)
补充1:如果要在 bash 的语法当中使用中括号作为 shell 的判断式时,必须要注意中括号的两端需要有空白字节来分隔喔!
补充2)假设我空白键使用『□』符号来表示,那么,在这些地方你都需要有空白键:
(15)
所以说,你最好要注意:
  ● 在中括号 [] 内的每个组件都需要有空白键来分隔;
  ● 在中括号内的变量,最好都以双引号括号起来;
  ● 在中括号内的常数,最好都以单或双引号括号起来。
【荔枝】利用中括号[] 进行判断,加引号的区别
(16)
【荔枝】那我们也使用中括号的判断来做一个小案例好了,案例配置如下:
  1. 当运行一个程序的时候,这个程序会让使用者选择 Y 或 N ,
  2. 如果使用者输入 Y 或 y 时,就显示『 OK, continue 』
  3. 如果使用者输入 n 或 N 时,就显示『 Oh, interrupt !』
  4. 如果不是 Y/y/N/n 之内的其他字节,就显示『 I don't know what your choice is 』
利用中括号[]、 && 与 || 来继续吧!

(17)
【13.3.3】shell script的默认变量($0、 $1 ......)
1)如果你想要重新启动系统登录档的功能,可以这样做:

(18)
2)script 是怎么达成这个功能的呢?其实 script 针对参数已经有配置好一些变量名称了!对应如下:

(19)
3)除了这些数字的变量之外, 我们还有一些较为特殊的变量可以在 script 内使用来调用这些参数喔!
  ● $# :代表后接的参数『个数』,以上表为例这里显示为『 4 』;
  ● $@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);
  ● $* :代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字节,默认为空白键, 所以本例中代表『 "$1 $2 $3 $4" 』之意。

【荔枝】假设我要运行一个可以携带参数的 script ,运行该脚本后萤幕会显示如下的数据:

  • ● 程序的档名为何?
  • ● 共有几个参数?
  • ● 若参数的个数小於 2 则告知使用者参数数量太少
  • ● 全部的参数内容为何?
  • ● 第一个参数为何?
  • ● 第二个参数为何。

(20)
3)shift:造成参数变量号码偏移
【荔枝】那个 shift 会移动变量,而且 shift 后面可以接数字,代表拿掉最前面的几个参数的意思。

(21)
【13.4】条件判断式
【13.4.1】利用 if...then

1)单层、简单条件判断式: 如果你只有一个判断式要进行,那么我们可以简单的这样看:

(22)
1.1)如果我有多个条件要判别时,我还可以有多个中括号来隔开喔!而括号与括号之间,则以 && 或 || 来隔开,他们的意义是:
  ● && 代表 AND ;
  ● || 代表 or ;
1.2)所以,在使用中括号的判断式中, && 及 || 就与命令下达的状态不同了。举例来说, sh06.sh 里面的判断式可以这样修改:
[ "$yn" == "Y" -o "$yn" == "y" ]
上式可替换为
[ "$yn" == "Y" ] || [ "$yn" == "y" ]
之所以这样改,很多人是习惯问题!很多人则是喜欢一个中括号仅有一个判别式的原因。

【荔枝】将sh06.sh 修改为 if...then 的样式看看:

(23)
2)多重、复杂条件判断式
2.1)一个条件判断

(24)
2.2)多个条件判断

(25)
注意:你得要注意的是, elif 也是个判断式,因此出现 elif 后面都要接 then 来处理!但是 else 已经是最后的没有成立的结果了, 所以 else 后面并没有 then 喔!好!我们来将 sh06-2.sh 改写成这样:
【荔枝】将 多个if 语句改为 elif 语句

(26)
3)一般来说,如果你不希望使用者由键盘输入额外的数据时, 可以使用上一节提到的参数功能 ($1)!让使用者在下达命令时就将参数带进去! 现在我们想让使用者输入『 hello 』这个关键字时,利用参数的方法可以这样依序设计:
  1. 判断 $1 是否为 hello,如果是的话,就显示 "Hello, how are you ?";
  2. 如果没有加任何参数,就提示使用者必须要使用的参数下达法;
  3. 而如果加入的参数不是 hello ,就提醒使用者仅能使用 hello 为参数。
整个程序的撰写可以是这样的:

(27)
【荔枝】 netstat命令:查询到目前主机打开的网络服务端口
荔枝1)我可以利用『 netstat -tuln 』来取得目前主机有启动的服务:
(28)
补充:上面的重点是『Local Address (本地主机的IP与端口对应)』那个栏位,他代表的是本机所启动的网络服务! IP的部分说明的是该服务位於那个介面上,若为 127.0.0.1 则是仅针对本机开放,若是 0.0.0.0 或 ::: 则代表对整个 Internet 开放。 每个端口 (port) 都有其特定的网络服务,几个常见的 port 与相关网络服务的关系是:
  ● 80: WWW
  ● 22: ssh
  ● 21: ftp
  ● 25: mail
  ● 111: RPC(远程程序呼叫)
  ● 631: CUPS(列印服务功能)

荔枝2)假设我的主机有兴趣要侦测的是比较常见的 port 21, 22, 25及 80 时,那我如何透过 netstat 去侦测我的主机是否有开启这四个主要的网络服务端口呢?由於每个服务的关键字都是接在冒号『 : 』后面, 所以可以藉由撷取类似『 :80 』来侦测的!那我就可以简单的这样去写这个程序喔:

(29)
【荔枝】写个脚本程序来跑,让使用者输入他的退伍日期,让你去帮他计算还有几天才退伍?
由於日期是要用相减的方式来处置,所以我们可以透过使用 date 显示日期与时间,将他转为由 1970-01-01 累积而来的秒数, 透过秒数相减来取得剩余的秒数后,再换算为日数即可。整个脚本的制作流程有点像这样:
  1. 先让使用者输入他们的退伍日期;
  2. 再由现在日期比对退伍日期;
  3. 由两个日期的比较来显示『还需要几天』才能够退伍的字样。
似乎挺难的样子?其实也不会啦,利用『 date --date="YYYYMMDD" +%s 』转成秒数后,接下来的动作就容易的多了!

(30)

#!/bin/bash
# Program:
#       You input your demobilization date, I calculate how many days
#       before you demobilize.
# History:
# 2005/08/29    VBird   First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH# 1. 告知使用者这支程序的用途,并且告知应该如何输入日期格式?
echo "This program will try to calculate :"
echo "How many days before your demobilization date..."
read -p "Please input your demobilization date (YYYYMMDD ex>20090401): " date2# 2. 测试一下,这个输入的内容是否正确?利用正规表示法罗~
date_d=$(echo $date2 |grep '[0-9]\{8\}')   # 看看是否有八个数字
if [ "$date_d" == "" ]; thenecho "You input the wrong date format...."exit 1
fi# 3. 开始计算日期罗~
declare -i date_dem=`date --date="$date2" +%s`    # 退伍日期秒数
declare -i date_now=`date +%s`                    # 现在日期秒数
declare -i date_total_s=$(($date_dem-$date_now))  # 剩余秒数统计
declare -i date_d=$(($date_total_s/60/60/24))     # 转为日数
if [ "$date_total_s" -lt "0" ]; then              # 判断是否已退伍echo "You had been demobilization before: " $((-1*$date_d)) " ago"
elsedeclare -i date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60))echo "You will demobilize after $date_d days and $date_h hours."
fi

(31)
【13.4.2】利用 case...esac 判断
(32)
【荔枝】把 sh09.sh 修改一下,如下:

(33)

#!/bin/bash
# Program:
#       Show "Hello" from $1.... by using case .... esac
# History:
# 2005/08/29    VBird   First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATHcase $1 in"hello")echo "Hello, how are you ?";;"")echo "You MUST input parameters, ex> {$0 someword}";;*)   # 其实就相当於万用字节,0~无穷多个任意字节之意!echo "Usage $0 {hello}";;
esac

(34)
【补充】一般来说,使用『 case $变量 in 』这个语法中,当中的那个『 $变量 』大致有两种取得的方式:
  ● 直接下达式:例如上面提到的,利用『 script.sh variable 』 的方式来直接给予 $1 这个变量的内容,这也是在 /etc/init.d 目录下大多数程序的设计方式。
  ● 互动式:透过 read 这个命令来让使用者输入变量的内容。

【荔枝】让使用者能够输入 one, two, three , 并且将使用者的变量显示到屏幕上,如果不是 one, two, three 时,就告知使用者仅有这三种选择。(通过直接执行式来传入参数,即利用 script.sh variable 的方式来直接给予 $1 这个变量的内容)

(35)

#!/bin/bash
# Program:
#       This script only accepts the flowing parameter: one, two or three.
# History:
# 2005/08/29    VBird   First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATHecho "This program will print your selection !"
# read -p "Input your choice: " choice # 暂时取消,可以替换!
# case $choice in                      # 暂时取消,可以替换!
case $1 in                             # 现在使用,可以用上面两行替换!"one")echo "Your choice is ONE";;"two")echo "Your choice is TWO";;"three")echo "Your choice is THREE";;*)echo "Usage $0 {one|two|three}";;
esac

【继续荔枝】让使用者能够输入 one, two, three , 并且将使用者的变量显示到屏幕上,如果不是 one, two, three 时,就告知使用者仅有这三种选择。(通过read命令读入用户输入的变量内容)

(36)
【13.4.3】利用function功能
1)function的语法如下:
function fname() {
程序段
}
那个 fname 就是我们的自订的运行命令名称~而程序段就是我们要他运行的内容了。 要注意的是,因为 shell script 的运行方式是由上而下,由左而右, 因此在 shell script 当中的 function 的配置一定要在程序的最前面, 这样才能够在运行时被找到可用的程序段喔!

【荔枝】定义一个名为 printit的函数, 如下:

(37)

#!/bin/bash
# Program:
#       Use function to repeat information.
# History:
# 2005/08/29    VBird   First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATHfunction printit(){echo -n "Your choice is "     # 加上 -n 可以不断行继续在同一行显示
}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

2)另外, function 也是拥有内建变量的~他的内建变量与 shell script 很类似, 函数名称代表示 $0 ,而后续接的变量也是以 $1, $2... 来取代的~ 这里很容易搞错喔~因为『 function fname() { 程序段 } 』内的 $0, $1... 等等与 shell script 的 $0 是不同的。以上面 sh12-2.sh 来说,假如我下达:『 sh sh12-2.sh one 』 这表示在 shell script 内的 $1 为 "one" 这个字串。但是在 printit() 内的 $1 则与这个 one 无关。

【荔枝】将上面的例子再次改写一下,如下:
(38)

[root@localhost scripts]# vim sh12-4.sh#!/bin/bash
# Program:
#       Use function to repeat information.
# History:
# 2005/08/29    VBird   First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATHfunction printit(){echo "Your choice is $1"   # 这个 $1 必须要参考底下命令的下达
}echo "This program will print your selection !"
case $1 in"one")printit 1  # 请注意, printit 命令后面还有接参数!;;"two")printit 2;;"three")printit 3;;*)echo "Usage $0 {one|two|three}";;
esac

【13.5】循环
【13.5.1】while do done, until do done (不定循环)

1)循环方式
方式1) while do done 循环:while 的中文是当....时,所以,这种方式说的是『当 condition 条件成立时,就进行循环,直到 condition 的条件不成立才停止』的意思。
(39)
方式2)until do done 循环(不定循环):它说的是当 condition 条件成立时,就终止循环, 否则就持续进行循环的程序段。
(40)
【荔枝】while循环:假设我要让使用者输入 yes 或者是 YES 才结束程序的运行,否则就一直进行告知使用者输入字串。

(41)
(42)
【荔枝】想要计算 1+2+3+....+100 这个数据呢? 利用循环啊。
(43)
【13.5.2】for...do...done(固定循环)
1)相对于 while, until 的循环方式是必须要『符合某个条件』的状态, for 这种语法,则是已经知道要进行几次循环的状态!他的语法是:

(44)
2)让我们想像另外一种状况,由於系统上面的各种帐号都是写在 /etc/passwd 内的第一个栏位,你能不能透过管线命令的 cut 捉出单纯的帐号名称后,以 id 及 finger 分别检查使用者的识别码与特殊参数呢?
(45)
【补充】
补充1)id命令: id 命令可以显示真实有效的用户 ID(UID) 和组 ID(GID)。UID 是对一个用户的单一身份标识。组 ID(GID)则对应多个UID。
补充2)finger命令:finger命令用于查找并显示用户信息。包括本地与远端主机的用户皆可,帐号名称没有大小写的差别。单独执行finger指令,它会显示本地主机现在所有的用户的登陆信息,包括帐号名称,真实姓名,登入终端机,闲置时间,登入时间以及地址和电话。
(46)
【荔枝】利用 ping 这个可以判断网络状态的命令, 来进行网络状态的实际侦测时,我想要侦测的网域是本机所在的 192.168.1.1~192.168.1.100,由於有 100 台主机, 总不会要我在 for 后面输入 1 到 100 吧?此时你可以这样做喔!(但本机实验只取10台机器!!)
(47)

#!/bin/bash
# Program
#       Use ping command to check the network's PC state.
# History
# 2009/02/18    VBird   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 10)       # seq 为 sequence(连续) 的缩写之意
do# 底下的程序在取得 ping 的回传值是正确的还是失败的!ping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1# 开始显示结果是正确的启动 (UP) 还是错误的没有连通 (DOWN)if [ "$result" == 0 ]; thenecho "Server ${network}.${sitenu} is UP."elseecho "Server ${network}.${sitenu} is DOWN."fi
done

【荔枝】编写判别式加上循环的功能: 我想要让使用者输入某个目录文件名, 然后找出某目录内的文件名权限,该如何是好?
(48)

(49)
【13.5.3】for...do...done 的数值处理
1)for 循环还有另外一种写法!语法如下:

(50)
2)这种语法适合於数值方式的运算当中,在 for 后面的括号内的三串内容意义为:
  ● 初始值:某个变量在回圈当中的起始值,直接以类似 i=1 配置好;
  ● 限制值:当变量的值在这个限制值的范围内,就继续进行回圈。例如 i<=100;
  ● 运行步阶:每作一次回圈时,变量的变化量。例如 i=i+1。

【荔枝】执行从1的累加,上限是输入的数字,如下:
(51)
【13.6】shell script的追踪与调试
1)scripts 在运行之前,最怕的就是出现语法错误的问题了!那么我们如何 debug 呢? 有没有办法不需要透过直接运行该 scripts 就可以来判断是否有问题呢?呵呵!当然是有的!我们就直接以 bash 的相关参数来进行判断吧!
(52)
【荔枝】
(53)

(54)

  • 补充1) 在输出的信息中,在加号后面的数据其实都是命令串,由於 sh -x 的方式来将命令运行过程也显示出来, 如此使用者可以判断程序码运行到哪一段时会出现相关的资讯!这个功能非常的棒!
  • 补充2)Linux 系统本来就有很多的服务启动脚本,如果你想要知道每个 script 所代表的功能是什么? 可以直接以 vim 进入该 script 去查阅一下,通常立刻就知道该 script 的目的了。 举例来说,我们之前一直提到的 /etc/init.d/syslog ,这个 script 是干嘛用的? 利用 vi 去查阅最前面的几行字,就知道这个 shell 脚本是干什么的了。

【13.8】本章习题

  • shell script 是利用 shell 的功能所写的一个『程序 (program)』,这个程序是使用纯文字档,将一些 shell 的语法与命令(含外部命令)写在里面, 搭配正规表示法、管线命令与数据流重导向等功能,以达到我们所想要的处理目的;
  • shell script 用在系统管理上面是很好的一项工具,但是用在处理大量数值运算上, 就不够好了,因为 Shell scripts 的速度较慢,且使用的 CPU 资源较多,造成主机资源的分配不良;
  • 在 Shell script 的文件中,命令的运行是从上而下、从左而右的分析与运行;
  • shell script 的运行,至少需要有 r 的权限,若需要直接命令下达,则需要拥有 r 与 x 的权限;
  • 良好的程序撰写习惯中,第一行要宣告 shell (#!/bin/bash) ,第二行以后则宣告程序用途、版本、作者等;
  • 对谈式脚本可用 read 命令达成;
  • 要创建每次运行脚本都有不同结果的数据,可使用 date 命令利用日期达成;
  • script 的运行若以 source 来运行时,代表在父程序的 bash 内运行之意!
  • 若需要进行判断式,可使用 test 或中括号 ( [] ) 来处理;
  • 在 script 内,$0, $1, $2..., $@ 是有特殊意义的!
  • 条件判断式可使用 if...then 来判断,若是固定变量内容的情况下,可使用 case $var in ... esac 来处理;
  • 回圈主要分为不定回圈 (while, until) 以及固定回圈 (for) ,配合 do, done 来达成所需任务!
  • 我们可使用 sh -x script.sh 来进行程序的 debug;

linux-basic(13)学习shell script相关推荐

  1. 「学习笔记-Linux」学习Shell Script

    学习Shell Script Table of Contents 1 什么是Shell Scipt 1.1 程序书写 1.2 程序执行 2 简单Shell练习 2.1 例1 接收用户输入 2.2 例2 ...

  2. Linux基础篇学习—shell及shell脚本

    概述 shell概念 shell又称命令解释器,它能识别用户输入的各种命令,并传递给操作系统 它的作用类似于Windows操作系统中的命令行,但是,Shell的功能远比命令行强大的多:在UNIX或者l ...

  3. 鸟哥的Linux私房菜-第10/11/12/13章(vim程序编辑器、学习bash、正则表达式与文件格式化处理、学习Shell Scripts)...

    第10章 vim程序编辑器 可以将vim看做vi的进阶版本,vim可以用颜色或底线等方式来显示出一些特殊的信息. 为何要学习vim?因为: a. 所有的 Unix Like 系统都会内建 vi 文书编 ...

  4. Shell 编程 Shell Script

    Shell Script简介 什么是shell script? shell:与内核通信的工具: script:脚本: shell script:针对shell所写的脚本. 利用shell功能所写的一个 ...

  5. 第13章代码《跟老男孩学习Linux运维:Shell编程实战》

    本书历史上已出版最实战的Shell高级编程实战书籍,没有之一,和市面书籍不同,本书是作者经过18年的运维工作及教学工作后,创新类企业级实战书籍,适合所有学习及从事Linux相关工作的读者. <跟 ...

  6. 小白linux bash 学习二 shell Script

    之前说了一些脚本和变量,其实都是为了现在讲shell Script也就是shell脚本做铺垫.按照我自己的理解来讲.其实shell 脚本就是一些基础的语法和命令的总和, 所以要学shell 脚本,那么 ...

  7. 【shell脚本开发技术】linux中shell script脚本开发编程常用命令与脚本速记指南

    shell script #!/bin/bash # do something run shell script sh script.shorchmod a+x script.sh ./script. ...

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

    第十二章 学习shell脚本 通常利用shell脚本完成服务器的检测工作,不涉及大量运算. 12.1 简单shell脚本介绍 12.2 简单shell脚本练习 12.2.1 简单范例 范例1:永远的开 ...

  9. linux 下 将 shell script 与 一个桌面图标联系在一起 (2)

    Cy163注: 步骤如下: (1)         建立 xxxxx.sh (2)         在 vnc 虚拟终端 的desktop上,右键,然后选择"创建启动器" (3)  ...

最新文章

  1. hibernate多个主键
  2. 研究人员提出增强Wi-Fi传输的新方法
  3. 汇编 头文件 依赖库文件
  4. 链队列的建立、判空、入队、出队、求长、访头、清空和销毁
  5. SSH框架中配置log4j的方法
  6. linux安卓双系统板子,安卓迷你 PC 主机只要 109 美元,支持 Android 和 Linux 双系统...
  7. eureka 集群失败的原因_eureka集群中的疑问?
  8. 随机森林RF、XGBoost、GBDT和LightGBM的原理和区别
  9. Apollo配置中心热加载mysql_Apollo 配置中心部署注意事项
  10. linux逻辑卷创建与管理,CentOS创建LVM linux逻辑卷创建及管理
  11. hexo -d 部署的时候报错 FATAL Something's wrong Template render error: expected variable
  12. python选取tensor某一维_Python按维数操作多维张量,Pytorch,对,Tensor,维度
  13. 对链表结构体定义中的LNode,*LinkList的理解
  14. 无线桥接怎么设置网关和dns服务器,斐讯K2路由器怎么设置桥接_斐讯K2无线中继设置教程-192路由网...
  15. 360安全浏览器安装插件源文件存放位置
  16. 【转】我是一个INFP者
  17. PCL1.9.1下载与配置+Visual Studio2017
  18. Flink On K8s
  19. 安装指定版本docker
  20. Python 设置随机 User-Agent (利用 fake_useragent包)

热门文章

  1. Codeforces Global Round 14 F. Phoenix and Earthquake 思维 + 并查集
  2. 【康复训练】[国家集训队] calc【dp】【拉格朗日插值】
  3. [APIO2018] New Home 新家(线段树,二分答案,离散化)
  4. Codeforces Round #541 (Div. 2)
  5. Minimum spanning tree HDU - 6954
  6. Acwing 1082. 数字游戏
  7. 学习有向图和无向图的强连通分量(基本概念+割点+点双联通分量+桥+边双连通分量+全套模板【Tarjan】)
  8. YbtOJ#20236-[冲刺NOIP2020模拟赛Day9]红点蓝点【线段树,堆】
  9. P5887-Ringed Genesis【GCD】
  10. POJ1151-Atlantis【线段树,扫描线,离散化】