高级bash/shell脚本编程指南

简介

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  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

你可能感兴趣的:(Linux/Unix,脚本,编程,bash,shell,unix)