目录
shell是什么
shell编程
shell变量
自定义变量
位置变量
环境变量
特殊变量
shell脚本语句
说明性的语句(注释)
功能性语句
read
重定向问题
expr
test测试语句
文件测试
整数测试
正文
shell是什么
shell是一个命令解析器
我们可以把很多要执行的命令,以某种语言的方式组织起来,交给shell去执行。
这种命令的组织方式,称之为脚本语言。
一个包含多个命令的shell脚本文件。
shell脚本文件是一个普通的文本文件,是以shell脚本语言的方式把多条命令组织在一起的。这些脚本语言可执行文件 交给shell命令解析器,去执行。
shell编程
shell变量
在shell脚本中,我们可以定义变量。
shell脚本变量没有类型的概念,全部都是字符串类型。
shell变量也不需要定义,直接用赋值就行。引用变量名时,使用“$”符号
自定义变量
正如上面所说,不需要对变量定义类型,直接赋值即可,例如
var=100 echo $var #输出 100 var1=`date` #``反撇号,引用里面的那个命令或程序或脚本的输出结果(标准输出 类似于printf ) echo $var1 #这两句相当于在终端直接输入date,即引用命令date的输出结果
位置变量
指的是传递给脚本文件或者函数的参数
在shell脚本或shell函数中:
$0: --》表示的是第0个参数 命令行的程序运行名 -》1.sh
$1 $2 ...$9 :表示第一个到第九个参数的名字
$# :表示命令行参数的个数(不包括脚本名)
$@: 包含所有的命令行参数
$@ ==> $1 $2 ...$9
$*:包含所有的命令行参数
$@ ==> $1 $2 ...$9
$?:表示前面一个命令或者一个程序的退出码(返回值 进程的返回值)
main返回值 或者exit返回值
例如shell脚本中这么写
echo "$0 $1 $3 $4"
在终端我们这么输入
./shell.sh 12 ab ff %$& ** lk
最终输出的结果是 ./shell 12 ff ** lk,会对应输出
环境变量
环境变量:在同一个终端下面所有进程都可以共享的变量。
HOME: 用户主目录的路径
eq:
echo $HOME 会显示当前用户的家目录路劲名
如 -->/home/china
PATH:
命令或者可执行程序的搜索路径
你们有没有发现一个问题?
我们在运行一个命令的时候,比如:ls
我并没没有指定这个命令(文件)的路径,那么系统怎么知道这个命令或程序文件在哪呢?
eq: echo $PATH
环境变量PATH:
PATH :
指定系统要搜索的命令或可执行文件的路径列表
path的值:
dir1:dir2:..
eq: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/arm/5.4.0/usr/bin:/snap/bin
如果你想把你的一个程序或者命令,在运行的时候不需要指定路径,那么
你的程序或者文件的路径,必须要在PATH列出的那些1目录下。
eq:
1. cp 2.sh /usr/local/bin [把文件放到可执行文件的目录下去]
2.能不能改变环境变量PATH的值呢?
可以的
怎么改变呢?
export 环境变量名=环境变量的值
eq:
export PATH=$PATH:/home/china/shell
特殊变量
shell数组
数组名[下标]=value 下标:0,1,2...n-1
引用数组元素:
1.${数组名[下标]}
2.${数组名} $数组名 ==》在bash/dash中引用的是数组的第一个元素。
unset:清除数组元素
引用数组: 引用整个数组(引用数组中的所有元素)
1.${数组名[*]}
2.${数组名[@]}
例如
name=(i am very happy) name[0]=myself echo ${name[@]} #myself am very happy unset name[0] echo ${name[@]} #am very happy unset name[@] echo ${name[*]} #无输出 name[0]=your name[1]=are echo ${name[*]} #your are
shell脚本语句
说明性的语句(注释)
以#开头的行 就是注释行
功能性语句
任意操作系统的命令(eq: ls, echo, cd , date...)
shell内部命令,自编的的可执行程序。
我们可以来试一下,用.sh文件去调用.c文件
例如当前目录为 /mnt/test 次目录下有文件 1.c ,1.sh,我们在1.sh中写入:
cd /mnt/test #如果cd目录名,就默认是当前文件 ./1 #该.c文件已经执行过 gcc 1.c -o 1
read
ead:表示从终端获取输入,如
read var1 var2 echo "var1 = $var1" echo "var2 = $var2"
我们在终端输入两个字符串,回车,就能看到输出啦。但是需要注意的是,写在一行的read获取输入时,是以空格隔开的,如果输入 1 2 3 4 5,超出了两个怎么办,本例题会输出var1 = 1,var2 = 2 3 4 5,也就是最后一位会将这一行剩下的所有字符都获取。
read var1 read var2 echo "var1 = $var1" echo "var2 = $var2"
想这个,就是以回车符隔开,var1会将第一行所有字符获取,var2同理
重定向问题
输入重定向
命令的输入请求是向标准输入设备(如:键盘)提交请求。
我们也可以很方便地把输入来源指定为另外一个设备或文件。
这种改变输入来源,我们叫做“输入重定向”
在命令后面加一个<filename
该命令或者语句块所有输入来源来自filename指定的文件
read var1 var2 <test.txt
echo "var1 = $var1"
echo "var2 = $var2"
test.txt 内容自定义,会将同目录下test.txt文件中的内容读取出来,var1 与var2按顺序获取信息,以空格分割。
输出重定向
命令的输出请求通常是向标准输出设备(如:终端)提交请求。
我们也可以很方便地把输出目的指定为另外一个设备或文件。
这种改变输出目的,我们叫做“输出重定向”
在命令后或者语句 >filename
在命令后或者语句 >>filename
>会先清空filename原来的内容(如果有),然后再输出到文件
>> 追加,把输出的内容添加到filename指定的文件末尾去。
china@ubuntu:~/text$ cat test.txt sma] hiazhnenrghk china@ubuntu:~/text$ echo "heihei">test.txt china@ubuntu:~/text$ cat test.txt heihei china@ubuntu:~/text$ echo "aduiduidui">>test.txt china@ubuntu:~/text$ cat test.txt heihei aduiduidui
expr
expr主要是用于进行简单的算数运算,包括:
+ 加
- 减
\* 乘(注意,需要加反斜杠)
/ 除
% 取余
#从键盘中输入两个数,并对他们求积输出 read i j ret=`expr $i + $j` echo "$i \* $j = $ret"
使用 expr时,要用``反撇号撇起来
test测试语句
echo $? #永远代表最近的一个表达式的值或返回值
文件测试
命令行 | 含义 |
-d filename | 测试filename是否为一个目录(directory) |
-f filename | 测试filename是否为一个普通文件(file) |
-L filename | 测试filename是否为一个链接文件(link) |
-r filename | 测试filename是否存在并可读 |
-w filename | 测试filename是否存在并可写 |
-x filename | 测试filename是否存在并可执行 |
-s filename | 测试filename是否存在且长度不为0 |
eq:测试1.sh是否存在并可读
test -r 1.sh echo $?
f1 -nt f2:
nt: newer than
测试文件1是否比文件2更新
eq:
test 1.sh -nt 2.sh echo $?
f1 -ot f2:
ot: older sister
测试文件1是否比文件2更旧
eq:
test 1.sh -nt 2.sh echo $?
最后,test命令可以用[]来简写。
NOTE: expression前后左右要空格
test expression(表达式) <==> [ expression ]
eq:
test 1.sh -nt 2.sh
以上表达式也可以写成
[ 1.sh -nt 2.sh ] echo $?
test复合表达式
组合了两个或两个以上的测试表达式,称为复合表达式,为了使用复合表达式
你可以使用test([])内置的操作符,也可以用条件操作符。
(1) 使用test内置的操作符 来创建复合表达式 --》1个test语句
语法:
test expr1 "test_buildin" expr2
也可以写成
[ expr1 "test_buildin" expr2 ]
"test_buildin":test 内置的操作符:
-a and 并且
-o or 或者
eq:
测试一个文件($1)是否为普通文件,并且这个文件比文件2($2)更新
test -f $1 -a $1 -nt $2 [ -f $1 -a $1 -nt $2 ] #这两句是一样的
eq:
a b c
a>b或b>c
[$a -gt $b -o $b -gt $c]
5 > 4 > 3
[ 5 -gt 4 -a 4 -gt 3 ]
(2)使用条件操作符来创建复合表达式
语法:
test expr1 "op" test expr2
op | 含义 |
&& | 与 |
|| | 或 |
! | 非 |
eq:
测试一个文件1$1是否为普通文件,并且这个文件比文件2($2)更新。
test -f $1 && test $1 -nt $2 [ -f $1 ] && [ $1 -nt $2 ] #这两句一样
a>b且b>c -->条件操作符
整数测试
test $a -eq $b
eq: equal 测试两个整数是否相等
test $a -ne $b
ne: not equal 不等于
test 3 -ne 4 echo $? # 0 测试成功 test 3 -ne 3 echo $? # 1 测试失败
test $a -gt $be
gt:greater than 大于
test 3 -gt 4 echo $? #1-->测试失败 test 4 -gt 3 echo $? #0 测试成功
test $a -lt $b
lt: less than 小于
test 3 -lt 4 echo $? # 0 测试成功 test 4 -lt 3 echo $? # 1 测试失败
test $a -le $b
le : less or equal 小于等于
test 3 -le 4 echo $? # 0 测试成功
test $a -ge $b
ge:greater or equal 大于等于
test 3 -ge 4 echo $? # 1 测试失败
test $a op $b
op | 含义 |
-eq | == |
-ne | != |
-gt | > |
-lt | < |
-ge | >= |
-le | <= |