Shell脚本学习(一)
Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等,Linux中最常用的是bash。
脚本语言是一种解释型语言,会执行这类程序时,解释器(interpreter)需要读取我们编写的源代码(source code),并将其转换成目标代码(object code),再由计算机运行。
而我们常见的C、C++、Java都是编译型语言。这类语言需要预先将我们写好的源代码(source code)转换成目标代码(object code),这个过程被称作“编译”。
#!/bin/bash echo "Hello World !"
“#!” 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行。
像perl脚本通常会在第一句加上
#!/usr/bin/perl -w
对于加上这些标记的脚本,可以通过修改权限直接执行它们,比如这样:
chmod +x ./test.sh ./test.sh
chmod 是linux中修改权限的一个命令,+x表示给后面那个文件加上可执行的属性。
然后使用./test.sh就能运行脚本了。
为什么一定要用./test.sh才能运行脚本,直接使用test.sh却不行呢?
因为PATH这个环境变量默认后面是没有加./的,如果直接执行test.sh自然是无法被找到的
[root@localhost addPort]# echo $PATH /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
当然如果不加这个约定的标记,只需要这样就能执行bash脚本了
bash test.sh
使用 read 命令可以读取终端stdin的数据
read inputString echo "input String is $inputString"
会发现上面两个inputString一个加了$一个没有加,为什么?
我的理解是,当这变量被当做左值时,不需要加$,而当这个变来那个被当做右值时,必须加$
Shell声明一个变量
testString1="hello" testString2='world' testInt=123
初始化的时候必须注意的是,=号两边都不能有空格,不然是错误的,shell对格式的要求比较严格。
使用变量的时候就需要加上$符号了,因为这个时候它被当做一个右值来使用。
echo $testString1 echo $testString2 echo "${testInt}456"
当然,必要的时候需要加上花括号,这样才会跟后面的字符串分隔开,用作解释器限定边界。
readonly :在变量前面加上readonly可以限定为只读变量
unset:使用unset可以删除变量,删除变量以后再输出这个变量将不会有数据输出。
shell当中存在二种变量类型,分别是局部变量和环境变量。
局部变量只能在shell当前脚本中使用,而环境变量能被创建它们的shell脚本以及派生出来的子进程中使用。
在Shell当中还有一些比较特殊的变量
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同。 |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |
$n和C语言main函数当中的char* argv[]比较相似,都是传递进来的参数,$#对应的就是int argc了,比如有两个路径,需要分别用ls命令查看目录信息,这个时候可以这样:
#!/bin/bash myPath1=$1 myPath2=$2 ls $1 ls $2 echo $#
然后执行这个脚本
[root@localhost /]# chmod +x 123.sh [root@localhost /]# ./123.sh /mnt/ /usr/ cdrom hgfs bin etc games include lib lib64 libexec local sbin share src tmp 2
第一行打印的就是第一个参数ls以后的列表,第二行打印的就是第二个参数ls以后的列表,第三行打印的就是参数的个数。
$*和$@被直接使用的时候,他们的参数都会被当成一个个体使用,而当两者都被""包含时,"$*"会将参数组合成一个整体字符串输出,而"$@"的参数任然是一个个体。