前言
之前有一篇博文简单写了一个shell脚本程序,主要用来计算日期
之后再仔细去看了这方面的一些书,还是觉得那时候的自己太年轻,应该踏实的从根基做起,于是重新将语法之类的再学了一遍。
以前是觉得shell脚本学了是没有什么用途,但是在读了一些书之后发现是自己学的少了才会有这样的想法,况且我是相信存在即合理这种说法的,开始重视起来这个脚本语言。
介绍
shell脚本一般情况下以.sh结尾,创建该文件时不会以可执行文件创建,所以需要使用chmod +x XX.sh来修改它的权限,变为可执行文件之后,只要用./XXX.sh就可以执行了,第二种执行方法/bin/bash XX.sh也是可以执行.sh脚本。
bash执行原理
变量
在bash中,bash 会将所有变量看成是字符串。变量和等号之间不能有空格,不能使用标点符号
变量命名不能使用bash里的关键字,比如if ,else,while, local,echo等都是bash里的关键字。
bash是弱类型解释器,bash里的变量不需要定义,直接可以使用。
使用赋过值的变量,只需要在变量名前面加上$
比如:
当一个变量名后面还跟的有其他字符串需要将那个变量名用花括号括起来,仅仅是将变量名括起来,不包括$!!
echo "${mystring} how are you"
环境变量是全局变量,且它可以被子进程继承
本地变量是局部变量
文件名代换:
通配符*:匹配0个或任意多个通配符
?:匹配任意一个字符
[若干字符]:匹配方括号中任意一个字符的一次出现
命令代换
反引号 ` ` 括起来的是命令,它先被执行,然后再将结果替换到当前命令行中。
命令代换:$() 先将括号里的命令执行,然后返回结果
DATE=`date +%Y:%m:%d`
DATE=$(date +%Y:%m:%d)
echo $DATE
算术代换
(())双括号表示算术代换,在双括号里面可以进行算术计算,加减乘除等。
转义字符
\ 如果某些字符不想要特殊的含义,只想要它字面的意思,需要进行转义
单引号,双引号
' '单引号里不进行变量替换,里面是什么就是什么
“”当里面有变量时会进行替换
语法
条件测试
测试命令:test [
如何测试成功与否,通过查看退出码决定是否测试成功
测试成功返回0,失败返回1
测试整数:
-eq 相等
-ne 不等于
-le 小于等于
-ge 大于等于
-lt 小于
-gt 大于
read myint //从屏幕上读
test $myint -eq 100 //测试输入的数是否等于100
[ $myint -eq 100 ] //同测试输入的数是否等于100
echo $? //输出退出码,成功则为0,失败则为1
注意:[ 做测试命令时必须要与 ] 匹配使用,否则会报语法错误
测试字符串:
== 两个字符串是否相等
!= 两个字符串是否不相等
-z 是否为空串
-n 是否不为空串
read mystr
[ $mystr == 'hello' ]
echo $?
[ $mystr != 'hello' ]
echo $?
[ -z $mystr ]
echo $?
[ -n $mystr ]
echo $?
注意:不能判断空串是否相等,可以在判断的字符串前面各加一个相同字符
多条件测试
下面三个只能用于测试条件中
逻辑与 -a
逻辑或 -o
逻辑非 !
语句分流
if elif else fi
read mystr
if [ $mystr == 'hello' ];then
echo "hello world"
fi
shell脚本里是不能出现空循环的,那么当不想执行任何语句时,可以用:填充,就表示任何事不做。
|| ---- &&
上面用于连接两个命令
case语句
以esac结尾,并且每个分支末尾以 ;; 结尾,每执行完一个分支,下一个分支不再执行,直接跳出。
例如下面这个例子:如果在执行语句的后面加上start 就会输出start,$1表示取第一个命令行参数
case $1 in
'start' )
echo "start"
;;
'stop' )
echo "stop"
;;
esac
循环语句:
for循环:
for ((i=1;i<10;i++))
do
echo $i
done
while循环
i=0
while [ $i -le 5 ]
do
echo "hello $i"
let i++
done
until循环
i=0
until [ $i -ge 5 ] #--------该处的条件是不满足就继续,满足了就停止
do
echo "hello world"
let i++
done
位置参数和特殊变量
$0 表示运行的脚本的名称
$@ 表示参数列表
$# 表示命令行参数的个数
$? 上一个进程退出的退出码
#遍历命令行参数
#方法一
while [ $# -ne 0 ]
do
echo $1
shift 1
done
#方法二
for i in $@
do
echo $i
done
函数:
没有返回值,也没有参数
函数定义时前面要加function 函数体用{} 括起来,调用时直接写上函数名,不用带()
function fun(){
echo "success"
}
ret=$(fun)
if [ $ret == "success" ];then
echo "success"
else
echo "failed"
fi
脚本调试:
-n 只检查语法不进行执行
-x 提供跟踪执行命令,将执行的命令和结果显示出来
-v 边执行脚本边打印刚执行过的命令到标准输出
数组:
#遍历数组
#方法一:
i=0
arr=(2 3 4.13 'hello')
for i in ${arr[@]}
do
echo $i
done
#方法二:
arr=(2 3 4.13 'hello')
for ((i=0;i<${#arr[*]};i++))
do
echo ${arr[i]}
done
shell文件重定向
输出重定向:>
echo "hello world" > file
输入重定向:<
追加重定向:>>,不会覆盖原来的文件,在原来的文件后面进行追加
shell 文件包含,像其他语言包含头文件一样,shell也可以包含。
使用方法:
root@queen-virtual-machine:shellStudy# cat a.sh
#!/bin/bash
function fun(){
let data=$1+$2
echo $data
}
root@queen-virtual-machine:shellStudy# cat test.sh
#!/bin/bash
. a.sh
read d1 d2
res=$(fun d1 d2)
echo $res