0. shell 是什么东西?
shell 是一个命令解析器。
我们可以把很多要执行的命令,以某种语言的方式,
组织起来交给shell去解析执行。
xxx.sh 是多个命令的组织文件,shell脚本文件,也是一个普通
文件,是以shell脚本语言的方式、语法把多条语句组织起来!
./xxx.sh 把这些命令全部交给shell命令解析器,去执行!
命令解析器其实也是一个程序:
/bin/bash
/bin/sh
/bin/dash
......
都是shell用来解析命令(指令)程序文件。
1. shell 脚本文件
一个简单的shell脚本文件:
vim hello.sh
---------------------------
#!/bin/bash #指定shell的解析程序
echo "hello shell!" #在代码中表示注释
---------------------------
修改脚本文件的权限: +x
chmod +x hello.sh
运行脚本文件:
./hello.sh
2. shell 变量
在shell脚本中,也可以去定义变量。
shell变量没有类型的概念,全部都是当作字符串处理。
shell变量没有类型,说明咱们可以直接拿过来使用,无需定义!!
如:
变量名=值
name=value
引用变量: 引用变量的值
$变量名
${变量名}
例子: 1.sh
val=sb250
DATE=2014/2/29
echo $val
echo ${DATE}
注意:
'=' 赋值符号两边都不能有空格
shell变量有四种:
(1) 自定义变量
如:
var=xxx
DATE=`date`
`` 反撇号,引用里面的那个命令或执行程序或脚本的输出结果
(2) 位置变量
指的是传递给脚本文件或函数参数。
如:
./xxx.sh 123 456 abcde
在shell脚本或shell函数中:
$0 -> 第0个参数,命令行程序名(./xxx.sh)
$1 -> 第1个参数,(123)
......
$3 -> 第3个参数,(abcde)
......
$# -> 表示命令行参数的个数(不包括 ./xxx.sh)
$* -> 包含所有的参数
$* <=> $1C$2C$3......
C: 内部域分隔符(默认是空格,或换行)
$? -> 表示前面一个命令或者程序的退出码(返回值,进程的退出码)
练习: 2.sh
请大家写一个脚本文件,把脚本参数的个数,
以及每一个参数都打印出来!!
(3) 环境变量
环境变量: 在同一个终端下面所有进程都可以共享变量。
HOME : 保存的值是 用户主目录的路径
如:
echo $HOME
=> /home/china
PATH : 命令或可执行程序搜索路径
问题:
ls 命令在哪个路径都可以执行,然而我们并没有去指定ls的路径
PATH: 指定系统要搜索的命令或可执行程序的路径列表
echo $PATH
=> dir1:dir2:dir3:.....
修改环境变量的值:
export 环境变量名=新值
如:
将/home/china 添加到PATH中去
export PATH=$PATH:/home/china
让环境变量在所有的终端都生效:
修改配置文件: /etc/profile
在上述文件的末行,加一行代码:
export PATH=$PATH:/home/china
重启后生效!
(4) 特殊变量
3. shell数组
a、定义数组以初始化
数组名=(1 2 3 4 5 6)
例子:
arr=(1 2 3 4 5 6)
b、引用数组元素
${数组名[下标]}
如:
${arr[4]}
${数组名} or $数组名 => 引用数组的第0个元素
c、引用整数数组
${数组名[*]}
${数组名[@]}
求数组元素个数:
${#数组名[*]}
${#数组名[@]}
例子: 3.sh
定义一个数组,并初始化。
打印数组中的所有元素值,还有数组元素个数。
4. shell 语句
4.1 说明性语句(注释)
以#开始的,就是注释行
但是除去:
#!/bin/bash
4.2 功能性语句
任意的操作系统的命令:
如:
ls、echo、cd、date、pwd、shutdown、reboot ==
shell内部命令、自编程序
read : 在shell中表示从终端获取输入
类似于scanf。
例子: 4.sh
#!/bin/bash
read val1 val2
v1=$val1
v2=$val2
echo $val1
echo $v2
上述列子从终端获取两个字符串,第一个字符串保存在
变量val1中,第二个字符串保存在变量val2中。
重定向的问题:
(1) 输入重定向
命令的输入请求通常是向 标准输入输入(如:终端)提出请求,
我们也可以很方便的把输入重定向到一个文件,这种情况
我们称之为“输入重定向”。
在命令后面添加 < filename
该命令的所有输入都来自于 filename 所指定的那个文件!
例子:
4.sh
read val1 val2
-------------------
./4.sh < filename
(2) 输出重定向
输出某些内容的时候,一般是将内容输出到终端,那么咱们现在
也可以方便的将要输出的内容输出到一个文件中去,这种操作我们
称之为 “输出重定向”
在命令后面添加 > filename
> 会先清空filename的内容,然后再输出到文件中去!
在命令后面添加 >> filename
>> 追加,把输出的内容添加到filename指定的文件的下一行
expr: 算术运算
主要是用于进行简单的整数的运算。
包含:
+
-
\*
/
%
例子:
expr 5 + 3
val=`expr 5 + 3`
注意:
操作数与运算符,前后至少要有一个空格。
例子: 5.sh
#!/bin/bash
read i j
ret=`expr $i + $j`
echo $ret
test : test语句可以用来测试三种对象
字符串 整数 文件
test 测试成功 返回0
test 测试失败 返回1
a、字符串测试
= 测试两个字符串内容是否完全一致
例子:
test "abc" = "abc"
echo $? #0 表示成功
test "abc" = "ab"
echo $? #1 表示失败
!= 测试两个字符串内容是否不一致
例子:
test "abc" != "abc"
echo $? #1 表示失败
test "abc" != "ab"
echo $? #0 表示成功
-z zero测试字符串是否为空串
例子:
test -z ""
echo $? #0
test -z " "
echo $? #1
-n not null 测试字符串是否不为 空
例子:
test -n ""
echo $? #1
练习: 6.sh
从键盘获取一个变量的值,测试这个变量的值
是否等于 "good".
b、整数测试
a, b表示两个整数
a -eq b :equal 测试两个整数是否相等
例子:
test 3 -eq 4
echo $? #1
read i
test $i -eq 0
echo $? => 0 : i == 0
echo $? => 1 : i != 0
a -ne b : not equal 不等于 "!="
例子:
test 3 -ne 4
echo $? #0
a -gt b : greater than 大于 ">"
a -lt b : litter than 小于 "<"
a -ge b : greater equal 大于或等于 “>=”
a -le b : litter equal 小于或等于 "<="
c、文件测试
-d filename 测试filename否是为一个目录文件(dir)
-f filename 测试filename否是为一个普通文件(file)
-L filename 测试filename否是为一个符号链接文件(软链接Link)
-r filename 测试filename是否存在 并且可读
-w filename 测试filename是否存在 并且可写
-x filename 测试filename是否存在 并且可执行
-s filename 测试filename是否存在 并且长度不为0
file1 -nt file2 测试file1是否比file2更新
newer than
file1 -ot file2 测试file1是否比file2更旧
older than
最后,test命令可以使用 [ ] 来简写:
例子:
test $i -eq $j
<=>
[ $i -eq $j ]
test 复合表达式:
例子:
数学: 5 > 4 > 3
C语言: 5 > 4 && 4 > 3
组合了两个或两个以上的表达式称之为 复合表达式,
为了使用复合表达式,您可以使用:
(1) test([]) 内置的操作
test expr1 "符号" expr2
"符号": test内置的操作符
-a : and 并且
-o : or 或者
例子:
5 > 4 > 3
=>
test 5 -gt 4 -a 4 -gt 3
(2) 直接使用C语言中的逻辑运算符来进行操作
&& ||
例子:
5 > 4 > 3
=>
test 5 -gt 4 -a 4 -gt 3
<=>
[ 5 -gt 4 ] && [ 4 -gt 3 ]