简介
Bash(GNU Bourne-Again Shell)是一个为GNU计划编写的Unix shell,它是许多Linux平台默认使用的shell。
shell是一个命令解释器,是介于操作系统内核与用户之间的一个绝缘层。准确地说,它也是能力很强的计算机语言,被称为解释性语言或脚本语言。它可以通过将系统调用、公共程序、工具和编译过的二进制程序”粘合“在一起来建立应用,这是大多数脚本语言的共同特征,所以有时候脚本语言又叫做“胶水语言”
事实上,所有的UNIX命令和工具再加上公共程序,对于shell脚本来说,都是可调用的。Shell脚本对于管理系统任务和其它的重复工作的例程来说,表现的非常好,根本不需要那些华而不实的成熟紧凑的编译型程序语言。
运行Bash脚本的方式:
# 使用shell来执行
$ sh hello.sh
# 使用bash来执行
$ bash hello.sh
# 使用.来执行
$ . hello.sh
#使用source来执行
$ source hello.sh
初步练习:
#!/bin/bash
# 使用重定向
echo "Hello World" > test.txt
# 使用脚本清除/var/log下的log文件
LOG_DIR=/var/log
cd $LOG_DIR
> test.log
或
echo "" > test.log
或
cat /dev/null > test.log
# 复制test.txt的内容到test.log
cp test.{txt,log}
权限不够怎么办,我们可以使用
sudo sh -c "cat /dev/null > /var/log/wtmp "
让整个命令都具有sudo的权限执行
bash特殊字符
1,终止case选项(双分号)
#!/bin/bash
VARNAME=b
case "$VARNAME" in
[a-z]) echo "abc";;
[0-9]) echo "123";;
esac
2,引号
同样是$VARNAME,单引号会直接认为是字符,而双引号认为是一个变量
#!/bin/bash
VARNAME=b
echo '$VARNAME' # 输出 $VARNAME
echo "$VARNAME" # 输出 b
3,冒号
#!/bin/bash
while : #相当于 while true
do
echo "endless loop"
done
#!/bin/bash
condition=5
if [ $condition -gt 0 ] #gt表示greater than,也就是大于,同样有-lt(小于),-eq(等于)
then : # 什么都不做,退出分支
else
echo "$condition"
fi
4,数组元素
#!/bin/bash
arr=(12 22 32)
arr[0]=10
echo ${arr[0]}
5,管道(|)
分析前边命令的输出,并将输出作为后边命令的输入。这是一种产生命令链的好方法。
输入如下代码,作用是将小写字母转化为大写
#!/bin/bash
tr 'a-z' 'A-Z'
exit 0
现在让我们输送ls -l的输出到脚本中:
$ chmod 755 test.sh
$ ls -l | ./test.sh
输出的内容均变为了大写字母。
6,破折号(-):重定向stdin或stdout
下面脚本用于备份最后24小时当前目录下所有修改的文件.
#!/bin/bash
# 如果在命令行中没有指定备份文件的文件名,那么将默认使用"backup-MM-DD-YYYY.tar"
BACKUPFILE=${1:-backup}-$(date +%m-%d-%Y).tar
tar cvf - `find . -mtime -1 -type f -print` > $BACKUPFILE
gzip $BACKUPFILE
echo "Directory $PWD backed up in \"$BACKUPFILE.gz\"."
exit 0
参数
从命令行传递到脚本的参数:$0,$1,$2,$3
…
$0
就是脚本文件自身的名字,$1
是第一个参数,$2
是第二个参数,$3
是第三个参数,然后是第四个。$9
之后的位置参数就必须用大括号括起来了,比如,${10},${11},${12}
。
其他参数:
$# : 传递到脚本的参数个数
$* : 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过 9个
$$ : 脚本运行的当前进程 ID号
$! : 后台运行的最后一个进程的进程 ID号
$@ : 与$#相同,但是使用时加引号,并在引号中返回每个参数
$: 显示shell使用的当前选项,与 set命令功能相同
$? : 显示最后命令的退出状态。 0表示没有错误,其他任何值表明有错误。
文件
#!/bin/bash
file="/home/shiyanlou/test.sh"
if [ -r $file ]
then
echo "The file is readable"
else
echo "The file is not readable"
fi
if [ -e $file ]
then
echo "File exists"
else
echo "File not exists"
fi
参数说明:
-e filename 如果 filename存在,则为真
-d filename 如果 filename为目录,则为真
-f filename 如果 filename为常规文件,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename可读,则为真
-w filename 如果 filename可写,则为真
-x filename 如果 filename可执行,则为真
-s filename 如果文件长度不为0,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,则为真。
流程控制
1,if else 语法格式:
a=10
b=20
if [ $a == $b ]
then
echo "a == b"
elif [ $a -gt $b ]
then
echo "a > b"
elif [ $a -lt $b ]
then
echo "a < b"
else
echo "Ineligible"
fi
2,for循环一般格式:
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
3,while语句
int=1
while (( $int<=5 ))
do
echo $int
let "int++" #使用Bash let命令,不需要加上$来表示变量
done
while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量MAN,按结束循环。
echo 'press <CTRL-D> exit'
echo -n 'Who do you think is the most handsome: '
while read MAN
do
echo "Yes!$MAN is really handsome"
done
无限循环。要跳出这个循环,返回到shell提示符下,需要使用break命令。
#!/bin/bash
while :
do
echo -n "Enter a number between 1 and 5:"
read aNum
case $aNum in
1|2|3|4|5) echo "The number you entered is $aNum!"
;;
*) echo "The number you entered is not between 1 and 5! game over!"
break
;;
esac
done
算数运算
- 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
- expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
- 注意使用的反引号(esc键下边)
- 表达式和运算符之间要有空格
$a + $b
写成$a+$b
不行 - 条件表达式要放在方括号之间,并且要有空格
[ $a == $b ]
写成[$a==$b]
不行 乘号(*)前边必须加反斜杠()才能实现乘法运算
#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a == b"
fi
if [ $a != $b ]
then
echo "a != b"
fi