linux-basic(13)学习shell script
【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相关推荐
- 「学习笔记-Linux」学习Shell Script
学习Shell Script Table of Contents 1 什么是Shell Scipt 1.1 程序书写 1.2 程序执行 2 简单Shell练习 2.1 例1 接收用户输入 2.2 例2 ...
- Linux基础篇学习—shell及shell脚本
概述 shell概念 shell又称命令解释器,它能识别用户输入的各种命令,并传递给操作系统 它的作用类似于Windows操作系统中的命令行,但是,Shell的功能远比命令行强大的多:在UNIX或者l ...
- 鸟哥的Linux私房菜-第10/11/12/13章(vim程序编辑器、学习bash、正则表达式与文件格式化处理、学习Shell Scripts)...
第10章 vim程序编辑器 可以将vim看做vi的进阶版本,vim可以用颜色或底线等方式来显示出一些特殊的信息. 为何要学习vim?因为: a. 所有的 Unix Like 系统都会内建 vi 文书编 ...
- Shell 编程 Shell Script
Shell Script简介 什么是shell script? shell:与内核通信的工具: script:脚本: shell script:针对shell所写的脚本. 利用shell功能所写的一个 ...
- 第13章代码《跟老男孩学习Linux运维:Shell编程实战》
本书历史上已出版最实战的Shell高级编程实战书籍,没有之一,和市面书籍不同,本书是作者经过18年的运维工作及教学工作后,创新类企业级实战书籍,适合所有学习及从事Linux相关工作的读者. <跟 ...
- 小白linux bash 学习二 shell Script
之前说了一些脚本和变量,其实都是为了现在讲shell Script也就是shell脚本做铺垫.按照我自己的理解来讲.其实shell 脚本就是一些基础的语法和命令的总和, 所以要学shell 脚本,那么 ...
- 【shell脚本开发技术】linux中shell script脚本开发编程常用命令与脚本速记指南
shell script #!/bin/bash # do something run shell script sh script.shorchmod a+x script.sh ./script. ...
- 【Linux命令】《鸟哥Linux基础》第十二章 学习shell脚本
第十二章 学习shell脚本 通常利用shell脚本完成服务器的检测工作,不涉及大量运算. 12.1 简单shell脚本介绍 12.2 简单shell脚本练习 12.2.1 简单范例 范例1:永远的开 ...
- linux 下 将 shell script 与 一个桌面图标联系在一起 (2)
Cy163注: 步骤如下: (1) 建立 xxxxx.sh (2) 在 vnc 虚拟终端 的desktop上,右键,然后选择"创建启动器" (3) ...
最新文章
- hibernate多个主键
- 研究人员提出增强Wi-Fi传输的新方法
- 汇编 头文件 依赖库文件
- 链队列的建立、判空、入队、出队、求长、访头、清空和销毁
- SSH框架中配置log4j的方法
- linux安卓双系统板子,安卓迷你 PC 主机只要 109 美元,支持 Android 和 Linux 双系统...
- eureka 集群失败的原因_eureka集群中的疑问?
- 随机森林RF、XGBoost、GBDT和LightGBM的原理和区别
- Apollo配置中心热加载mysql_Apollo 配置中心部署注意事项
- linux逻辑卷创建与管理,CentOS创建LVM linux逻辑卷创建及管理
- hexo -d 部署的时候报错 FATAL Something's wrong Template render error: expected variable
- python选取tensor某一维_Python按维数操作多维张量,Pytorch,对,Tensor,维度
- 对链表结构体定义中的LNode,*LinkList的理解
- 无线桥接怎么设置网关和dns服务器,斐讯K2路由器怎么设置桥接_斐讯K2无线中继设置教程-192路由网...
- 360安全浏览器安装插件源文件存放位置
- 【转】我是一个INFP者
- PCL1.9.1下载与配置+Visual Studio2017
- Flink On K8s
- 安装指定版本docker
- Python 设置随机 User-Agent (利用 fake_useragent包)
热门文章
- Codeforces Global Round 14 F. Phoenix and Earthquake 思维 + 并查集
- 【康复训练】[国家集训队] calc【dp】【拉格朗日插值】
- [APIO2018] New Home 新家(线段树,二分答案,离散化)
- Codeforces Round #541 (Div. 2)
- Minimum spanning tree HDU - 6954
- Acwing 1082. 数字游戏
- 学习有向图和无向图的强连通分量(基本概念+割点+点双联通分量+桥+边双连通分量+全套模板【Tarjan】)
- YbtOJ#20236-[冲刺NOIP2020模拟赛Day9]红点蓝点【线段树,堆】
- P5887-Ringed Genesis【GCD】
- POJ1151-Atlantis【线段树,扫描线,离散化】