1、shell srcipt的注释。
脚本语言中用#进行注释
2、shell中的计算式。
计算方式:var=$((运算内容))
如:total=$((${firstnu}*${secnu}))
3、shell script的执行方式的差异。
首先由三种执行方式:source script、sh(包含bash dash等) script、./script等。
第一类: 直接执行sh/bash 脚本或者 ./ 都是在子进程中的。
cnbjlx24729:~/Desktop$ echo $firstname
cnbjlx24729:~/Desktop$ sh nametest.sh
Please input your first name :zhao
Please input your last name :yuan
your name is:zhaoyuan
cnbjlx24729:~/Desktop$ echo $firstname
cnbjlx24729:~/Desktop$
可以看到变量并没有起作用因为该 script 都会使用一个新的 bash 环境来执行脚本内的指令。也就是
说,
使用这种执行方式时, 其实 script 是在子程序的 bash 内执行的,
当子程序完成后,
在子程序内的各项变量或动作
将会结束而不会传回到父程序中。
第二类:使用source的时候。
cnbjlx24729:~/Desktop$ source nametest.sh
Please input your first name :zhao
Please input your last name :yuan
your name is:zhaoyuan
cnbjlx24729:~/Desktop$ echo $firstname
zhao
cnbjlx24729:~/Desktop$
会在父程序中执行的(其实该说是当前进程吧?),因此各项动作都会在原本的 bash 内生效!
4、test指令。
检测系统上面某些文件或者是相关的属性时,根据不同的参数执行不同的操作。
注意单独执行test的指令的
时候不会出什么显示结果,需要配合&&或||才可以。
1)、关于某个档名的文件类型判断,参数如下图:
cnbjlx24729:~/Desktop$ test -e ./nametest.sh && echo "exist" || echo "Not exist"
exist
cnbjlx24729:~/Desktop$ test -f ./nametest.sh && echo "exist" || echo "Not exist"
exist
cnbjlx24729:~/Desktop$ test -b ./nametest.sh && echo "exist" || echo "Not exist"
Not exist
可以看到就是每个类型文件前面的字母的缩写。
2)、文件的权限侦测。
图:
3)、两个文件之间的比较。
图:
4)、两个整数之间的判定。
图:
5)、判定字符串的数据。
6)、多重条件判定,例如: test -r filename -a -x filename
例子:
#!/bin/bash
#program:
# test command prictice
#history:
# 2017/06/05
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input file name:" filename
test ! -e ${filename} && echo "filename dose not exist" && exit 0
(这块一定的注意要是你 test -e ${filename} || echo "filename dose not exist" && exit 0
此时就算是存在也会
退出,因为存在返回0,符合后退出)
test -f ${filename} && filetype="regulare file"
test -d ${filename} && filetype="directory"
echo ${filetype}
echo "end"
5、[ ]来用作判断。
[] 也可以用作判断,基本用法和test一样,参数都通用。
如判断是否为空:(参数的位置,先参数后变量)
[ -z "$PATH" ] && echo "equals" || echo "not equals"
但是一定要注意中括号的两端需要有空格符来分隔,否则命令执行出错如下:
[-z "$PATH" ] && echo "equals" || echo "not equals"
xp022430@cnbjlx24729:~/Desktop$ sh judgeFile.sh
judgeFile.sh: 20: judgeFile.sh: [-z: not found
not equals
end
当比较两个字符串相等的时候(亲测不可以用==,会报错)
[ "TEST" = "TEST" ] && echo "equals" || echo "not equals"
至于每个组件之间都应该有空格,不然运行结果有误!用这个例子看就是两个等号两边都有空格!
中括号使用规范:
a、在中括号 [] 内的每个组件都需要有空格键来分隔;
b、在中括号内的变数,最好都以双引号括号起来
(不括起来的话,假如这个变量是如 Hello word,此时
会当用两个字符串的后边比较,且参数中多前面的字符串)
c、在中括号内的常数,最好都以单或双引号括号起来。
一个小例子,需要注意的是第一按照格式来,第二exit直接退出不需要echo exit,注意:利用-o参数
read -p "Please input Y/N : " choose
[ "$choose" = y -o "$choose" = Y ] && echo "OK,continue" && exit 0
[ "$choose" = n -o "$choose" = N ] && echo "Oh,interrupt" && exit 0
echo "I don't known what your choice is"
echo "end"
6、shell script 默认参数。
shell script 能在脚本档名后面带有参数,然后内部的shell 脚本会根据你传入的参数不同有不同的响应。
默认如下:
/path/to/scriptname opt1 opt2 opt3 opt4
$0 $1 $2 $3 $4
如上:
$0这个变量就是shell script的文档名字,后面一次是第几个参数,还有一些特殊的参数如下:
$# :代表后接的参数个数,以上表为例这里显示为4;
$@ :代表 "$1" "$2" "$3" "$4" 之意,每个变量是独立的(用双引号括起来);
$* :代表"$1c$2c$3c$4",其中 c 为分隔字符,默认为空格键, 所以本例中代表"$1 $2 $3 $4"之意。
变量就是想用的时候直接用就可以,字符串内部也行。
echo "the shellscript name is : $0"
变量偏移命令shift,直接执行偏移一个就是去掉第一个变量,shift 2 就是去掉前两个!
7、条件判断。
在做条件判断的时候[ ] ||[ ]或者 [ ]&&[ ]等,
中括号的判断式中, && 及 || 就与指令下达的状态不同了。
&& 代
表 AND ;
|| 代表 or ;
基本格式:
if [ 条件判断式 ]; then ( 注意if后面必须有空格,then前面的分号的是英文。)
(当条件判断式成立时,可以进行的指令工作内容)
fi (代表结束)
例子:
if [ "${choose}" = "N" ] || [ "${choose}" = "n" ];then
echo "Oh, interrupt!"
exit 0
fi
if..else 的格式:
if [ 条件判断式 ]; then(注意这个不变)
当条件判断式成立时,可以进行的指令工作内容;
else
当条件判断式不成立时,可以进行的指令工作内容;
fi
if...elseif...的格式:
if [ 条件判断式一 ]; then
当条件判断式一成立时,可以进行的指令工作内容;
elif [ 条件判断式二 ]; then
当条件判断式二成立时,可以进行的指令工作内容;
else
当条件判断式一与二均不成立时,可以进行的指令工作内容;
fi
综上可看出来其实和一般变成不同的就是判断式的哪一行,多个then
还有elseif缩写为elif.还有fi只有一个注
意了。
例子:
read -p "Please input Y/N : " choose
if [ "$choose" = y -o "$choose" = Y ] ; then
echo "OK,continue"
exit 0
elif [ "${choose}" = "N" ] || [ "${choose}" = "n" ];then
echo "Oh, interrupt!"
exit 0
else
echo "I don't known what your choice is"
fi
echo "end"
其实想完成更为复杂的功能就是条件判断复杂点,再加上正则表达式即可
(shell 脚本里面就是一堆Linux命
令嘛!)
。
需要一定量的练习才会熟知,此处继续学习语法,不知道某个命令的时候可以查。
8、日常编程中的switch case的实现:
格式:
case $变量名称 in (注意变量名称前面的$符号)
"第一个变量内容")(每个变量内容建议用双引号括起来,关键词则为小括号 )
程序段
;;(每个类别结尾使用两个连续的分号来处理!否则语法出错)
"第二个变量内容")
程序段
;;
*)最后一个变量内容都会用 * 来代表所有其他值不包含前面的其它程序执行段。
exit 1
;;
esac (结束符号,就是case反过来了)
例子:
case $1 in
"Hello")
echo "Hello, how are you ?"
;;
"")
echo "you should input argument"
;;
*)
echo "you must input Hello at first"
esac
注意变量有两种方式获取:
1)、直接下达式:直接在调用 文档名 参数 这样来给予.
2)、交互式:透过 read 这个指令来让用户输入变量的内容。reap -p
read -p "Please input one/two/three : " choice
case $choice in
......
9、函数
函数(function):
shell script 的执行方式是由上而下,由左而右, 因此在 shell script 当中的 function 的设定一
定要在程序的最前面。
格式:
function fname() {
程序段
}
然后在程序中需要用到的时候你直接fname即可。
function 也是拥有默认变量为$0、$1、$2......,注意它的变量是从0开始算起的
使用得时候 fname() 0 1 2
注意和传统的是不一样的,它不是在括号内加变量。
10、循环。
while循环的实现格式:
while [ condition ](中括号内的状态就是判断式)
do (循环开始)
(程序段落)
done(循环结束)
当 condition 条件成立时,就进行循环,直到 condition 的条件不成立才停止。
对应的有一个相反的条件。
until [ condition ]
do
程序段落
done
当 condition 条件成立时,就终止循环, 否则就持续进行循环的程序段。
一个例子:
echo "Show the sum of 1+2+3+...+100"
i=0 (变量的声明和赋值就这样直接紧挨着给)
s=0
while [ "${i}" != "100" ] (${i}这就是取变量中的值)
do
i=$((${i}+1)) (此时有个计算的模式别弄混了$((计算式)),计算式里面显示取值然后相加)
s=$((${s}+${i}))
done
echo "sum = ${s}"
for循环的实现:
第一种实现格式:
for var in con1 con2 con3 ...
do
(程序段)
done
说明:
1). 第一次循环时, $var 的内容为 con1 ;
2). 第二次循环时, $var 的内容为 con2 ;3. 第三次循环时, $var 的内容为 con3 ;
4). ....
例子:
for animal in dog cat elephant (需要注意的是此处的var不能用$animal的形式,注意和case的区别)
do
echo "There are ${animal}s"
done
小知识点:
a、$( )中放的是命令,相当于` `。如:users=$(cut -d ':' -f1 /etc/passwd) 就是执行()中的命令,把执
行结果给users
b、$(seq 1 100) :表示连续的1到100
c、分号的作用
不同的语法命令之间要用分号隔开或是换行方能执行,否则将会在调用脚本的时候报
错。
d、如何查看软连接连接到哪儿了?
ls -la
xp022430@cnbjlx24729:/bin$ ls -la | grep "sh"
-rwxr-xr-x 1 root root 1021112 May 16 20:51 bash
-rwxr-xr-x 1 root root 121272 Feb 19 2014 dash
lrwxrwxrwx 1 root root 57 May 8 09:48 fg4 -> /home/CORPUSERS/xp02...am/fg4/fg4
lrwxrwxrwx 1 root root 4 May 16 20:51 rbash -> bash
lrwxrwxrwx 1 root root 4 Feb 19 2014 sh -> dash
lrwxrwxrwx 1 root root 4 Apr 6 14:30 sh.distrib -> dash
lrwxrwxrwx 1 root root 7 Nov 15 2013 static-sh -> busybox
e、whoami 查看当前用户。
另一种for循环的实现格式:
for (( 初始值; 限制值; 执行步阶 )) (这就和我们平常认知的相似了)
do
程序段
done
例子:
read -p "Please input a number, I will count for 1+2+...+your_input: " nu
s=0
for ((i=1; i<=5; i++))
do
s=$((${s}+${i}))
done
echo "The result of '1+2+3+...+${nu}' is ==> ${s}"
默认用sh直接执行时。语法错误,在for的这一行是因为
ubuntu 就将先前默认的bash shell 更换成了dash shell,
其表现为
/bin/sh 链接倒了/bin/dash而不是传统的/bin/ba
sh。
所以直接bash judgeFile.sh可以执行成功。
不过可能不便于移植。
可以改成如下:
read -p "Please input a number, I will count for 1+2+...+your_input: " nu
s=0
for nu in $(seq $nu) (后面这种形式便于移植也可以用`seq $nu`和$()一样的执行命令)
do
s=$((${s}+${nu}))
done
echo "The result of '1+2+3+...+${nu}' is ==> ${s}"
11、shell script的debug
运行脚本的时候可以先添加参数以便于我们调试如下:
[dmtsai@study ~]$ sh [-nvx] scripts.sh
选项与参数:
-n :不要执行 script,仅查询语法的问题;
-v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;
-x :将使用到的 script 内容显示到屏幕上,这是很有用的参数! (可以详细到某一步的指令执行)
12、重要概念。
1)、shell script 是利用 shell 的功能所写的一个『程序 (program)』,这个程序是使用纯文本文件,将一些
shell 的
语法与指令(含外部指令)写在里面, 搭配正规表示法、管线命令与数据流重导向等功能,以达到
我们所想
要的处理目的。
2)、shell script 用在系统管理上面是很好的一项工具,但是用在处理大量数值运算上, 就不够好了,因为
Shell
scripts 的速度较慢,且使用的 CPU 资源较多,造成主机资源的分配不良。
3)、shell script 的执行,至少需要有 r 的权限,若需要直接指令下达,则需要拥有 r 与 x 的权限。
4)、Shell script 拥有更强大的功能,那就是他可以进行类似程序 (program) 的撰写,并且不需
要经过编译
(compile) 就能够执行,