Linux基础篇,Shell
一、基本知识
Shell Script是一种脚本。可以用来极大的简化计算机的管理。在谱写shell script的时候,需要注意以下问题:
- 1. 指令的执行是从上而下、 从左而右的分析与执行;
- 2. 指令的下达就如同第四章内提到的: 指令、 选项与参数间的多个空白都会被忽略掉;
- 3. 空白行也将被忽略掉, 并且 [tab] 按键所推开的空白同样视为空白键;
- 4. 如果读取到一个 Enter 符号 ( CR) , 就尝试开始执行该行 ( 或该串) 命令;
- 5. 至于如果一行的内容太多, 则可以使用“ [Enter] ”来延伸至下一行;
- 6. “ # ”可做为注解! 任何加在 # 后面的数据将全部被视为注解文字而被忽略!
编写好shell script后,可以通过以下方法执行程序:
- 绝对路径(注意这里的shell脚本必须具有rx的权限)
- 相对路径(注意这里的shell脚本必须具有rx的权限)
- 通过 bash shell.sh 或 sh shell.sh执行程序(注意这里的shell脚本必须具有r的权限)
二、规范与语法
1.第一个shell script
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
export PATH
echo "hello world!"
exit 0
注意:
(1)在shell script脚本中,#只有在 #!/bin/bash中才不起注释作用,其余的#都是注释声明
(2)export在这里是声明全部变量的意思,证明这个变量只有在这个程序及其子程序中可以使用
(3)exit 0表示退出程序,返回0,释放内存。一般约定返回0代表执行OK,返回非0代表执行出错
(4)使用exit 返回的值,在程序执行完毕之后,我们还可以使用 $? 变量获取到该值。
2.执行方式
(1)路径执行方式
这种方式执行程序后,其中的变量会直接结束。
(2)source执行方式
这种方式执行程序后,其中的变量会传给父进程。程序结束后,我们依然可以得到变量的值,例如:
源程序
变量生存周期:
3.命令间的关系
&& ===> 前一个命令执行完成后才会执行后面的命令
|| ===> 无论前一个命令是否执行成功后面的命令都会执行
$? ===> 前一个程序的返回值
三、判断式子
1.test 判断
test具有很多的判断功能,但是它并不会显示任何消息,这时候,我们需要用 && || $? 来进行逻辑思考了。test测试标记如下:
测试的标志 | 代表意义 |
一、文件夹判断 | |
-e | 该“文件名”是否存在? ( 常用) |
-f | 该“文件名”是否存在且为文件( file) ? ( 常用) |
-d | 该“文件名”是否存在且为目录( directory) ? ( 常 用) |
-b | 该“文件名”是否存在且为一个 block device 设备? |
-c | 该“文件名”是否存在且为一个 character device 设 备? |
-S | 该“文件名”是否存在且为一个 Socket 文件? |
-p | 该“文件名”是否存在且为一个 FIFO ( pipe) 文件? |
-L | 该“文件名”是否存在且为一个链接文件? |
二、文件判断 | |
-r | 侦测该文件名是否存在且具有“可读”的权限? |
-w | 侦测该文件名是否存在且具有“可写”的权限? |
-x | 侦测该文件名是否存在且具有“可执行”的权限? |
-u | 侦测该文件名是否存在且具有“SUID”的属性? |
-g | 侦测该文件名是否存在且具有“SGID”的属性? |
-k | 侦测该文件名是否存在且具有“Sticky bit”的属性? |
-s | 侦测该文件名是否存在且为“非空白文件”? |
三、文件比较 | |
-nt | ( newer than) 判断 file1 是否比 file2 新 |
-ot | ( older than) 判断 file1 是否比 file2 旧 |
-ef | 判断 file1 与 file2 是否为同一文件, 可用在判断 hard link 的判定上。 主要意义在判定, 两个文件是 否均指向同一个 inode 哩! |
四、两个整数之间的比较 | |
-eq | 两数值相等 ( equal) |
-ne | 两数值不等 ( not equal) |
-gt | n1 大于 n2 ( greater than) |
-lt | n1 小于 n2 ( less than) |
-ge | n1 大于等于 n2 ( greater than or equal) |
-le | n1 小于等于 n2 ( less than or equal) |
五、判断字符串 | |
test -z string | 判定字串是否为 0 ? 若 string 为空字串, 则为 true |
test -n string | 判定字串是否非为 0 ? 若 string 为空字串, 则为 false。 -n 亦可省略 |
test str1 == str2 | 判定 str1 是否等于 str2 , 若相等, 则回传 true |
test str1 != str2 | 判定 str1 是否不等于 str2 , 若相等, 则回传 false |
六、多重条件判断 |
-o | 两状况任何一个成立! (or) |
! | 反相状态 (!) |
-a | 两状况同时成立! (-and) |
eg:测试根目录下是否存在 /tmp 和 /info 文件夹
test -d /tmp && echo "存在" || echo "不存在"
test -d /info && echo "存在" || echo "不存在"
注意:
其实上面的命令等效于
(test -d /tmp && echo "存在") || echo "不存在"
(test -d /info && echo "存在") || echo "不存在"
若指定文件 存在,则test -d返回0,条件成立输出“存在”,继而屏蔽“不输出”
若指定文件不存在,则test -d返回非0,条件不成立,从而触发 || 右边的程序
2.中括号 [] 判断式
注意:
- 中括号用作判断式时,左右两边得分别有一个空格。
- 中括号内的每个组件都必须有空格键来分隔
- 中括号内的变量,最好都以双引号括起来
- 中括号内的常量最好都以单引号或双引号括起来
- 中括号的判别参数与test的参数几乎一模一样
eg:判断根目录下是否存在data文件
[ -e /data ] ; echo $?
注意:
0代表存在,非0代表不存在
3.条件判断
具体包括if then和case esac语句,使用方法见下方 五标题。
四、shell script传参
1.传参与使用参数
很多脚本都带有传参的功能,例如
service xxx [restart | stop | start]
中的restart 、stop、 start就是参数,并且传进去的参数会从 $1开始到 $2、$3......,而 $0 代表执行的脚本名。
除此之外,还有其他的一些特殊变量。具体的特殊变量如下
$# ===> 代表参数个数
$@ ===> "$1"、"$2"、"$3"..."$n" (注意,这里每个变量是独立的)
$* ===> ""$1 $2 $3...$n"" (注意这里把参数作为整体了,但是每个参数之间都有一个间隔符默认为空格)
$0 ===> 当前脚本的完整路径名
$n ===> 第n个参数(注意,n必须是一个正整数)
2.偏移参数
什么意思呢?就是每执行一次,就会删除第一个参数$1,并且把第二个参数作为新的第一个参数使用。
eg:
五、必备语句
1.if...then
该语句与C语言中的if...else if...else语句类似
if [条件判断式]; then
(工作内容)
elif [条件判断式]; then
(工作内容)
else
(工作内容)
fi
注意:
以上的 [条件判断式] 是仅判断一个条件的情况,若有多个情况需要一起判断,则有以下两种方法:
(1)每个判断式用 [] 隔开,[]与[]之间通过 && 或 || 进行逻辑判断
(2)多个判断式可以写在一个[]内,中间通过 -o 或 -a 进行逻辑判断(-o与-a是test和[]判断式的内容)
,%%%%%%%%,
,%%/\%%%%/\%%
,%%%\c "" J/%%%
%. %%%%/ o o \%%%
`%%. %%%% _ |%%%
`%% `%%%%(__Y__)%%'
// ;%%%%`\-/%%%'
(( / `%%%%%%%'
\\ .' |
\\ / \ | |
\\/ ) | |
\ /_ | |__
(___________)))))))]
eg:
if [ $1 -lt 60 ];
then echo "您的成绩不及格"
elif [ $1 -ge 60 ] && [ $1 -le 85 ];
then echo "您的成绩及格"
else
echo "您的成绩优秀"
fi
2.case...esac
该语句与C语言中的switch case语句类似
case $变量名称 in
"标志1")
(工作内容)
;;
"标志2")
(工作内容)
;;
*)
(工作内容)
exit 1
;;
esac
例如:
case $1 in
"1")
echo "您选择的是1号功能"
;;
"2")
echo "您选择的是2号功能"
;;
*)
echo "输入无效"
;;
esac
3.while do done
while [ 判断式 ]
do
(工作内容)
done
#!/bin/bash
declare -i data=10
while [ $data -ge 0 ]
do
echo $data
data=$(($data-1));
done
4.until do done
until [ 判断式 ]
do
(工作内容)
done
注意:
这里刚好与while do相反,即若满足判断式中的条件,则停止循环
eg:
#!/bin/bash
declare -i data=10
until [ $data -eq 0 ]
do
echo $data
data=$(($data-1));
done
5.for...do...done
==================================模式一====================================
for (变量) in (集合)
do
(工作内容)
done
===========================================================================
==================================模式二====================================
for (( 初始值; 限制值; 执行步长))
do
(工作内容)
done
===========================================================================
注意:
模式一适用于系统级常见任务处理,模式二适用于数值处理
eg:
#!/bin/bash
for animals in dog cat bird
do
echo ""$animals"来了"
done
#!/bin/bash
for (( i=1; i<=10; i=i+1))
do
echo $i
done
六、函数 function
定义方法:
function 函数名 () {
}
或
函数名() {
}
注意:
调用方法时,直接使用函数名即可调用,无需加括号
定义函数时function关键字可以省略
eg:
#!/bin/bash
function show () {
echo "您第 "$1" 次执行了show函数"
date
}
display () {
echo "您第 "$1" 次执行了display函数"
}
show 100
display 20
七、shell script的追踪与调试
sh [-nvx] xxx.sh
-n ===> 不要执行该脚本,仅查询语法错误
-v ===> 在执行该脚本前,先将脚本内容输出到屏幕上
-x ===> 将脚本中使用到的内容输出到屏幕上
eg: