天天看点

Shell编程基本知识

shell编程的基本写法及语法,摘自菜鸟教程
http://www.runoob.com/linux/linux-shell.html
           

写一个shell脚本:

#!/bin/bash
echo "Hello World !"
           

“#!”是标记使用哪种shell解释器来执行shell,echo是输出后面的文本。

讲文件保存成xxxx.sh,然后需要给这个xxxx.sh加上执行权限,使用命令

chmod +x ./xxxx.sh,由于xxxx.sh是shell脚本,没有在系统的PATH中,所以直接找xxxx.sh是不存在的,所以要加上./,并且执行时也要加上./xxxx.sh。

定义一个变量:

sss=”sss” # 注意:这里等号的左右不能出现空格,否则将报错

使用变量则必须加上 符号,否则无法识别,如果在字符串中访问变量,则需要将变量名称使用括起来,如 {sss}

如果要定义只读变量,则只需要定义完变量之后另起一行在变量前加上readonly即可,如 readonly sss

删除变量 unset sss,注意,unset不能删除只读变量

shell字符串

单引号:写在单引号里面的字符串,不论什么,都会原样输出,包括转义符号;

双引号:可以有变量,可以出现转义符。

字符串的拼接不需要“+”,这与其他编程语言有区别。

如sss = “xxx” sss即可。获取字符串长度为 {#sss}。

截取字符串: sss:1:2,与python的列表/字符串切片操作有点像。bash只支持一维数组,并且没有大小限定,下标从0开始。数据定义arraysss=1234,可以看出,shell的数组元素之间不需要分隔符。读取数组元素同样使用下标完成,读取所有的元素则可以使用 {array_sss[@]}。

shell里面的注释只能使用“#”进行单行注释,没有多行注释。

shell的参数传递

shell的参数传递是根据数字编号来获取的,编号为0的,指的就是shell脚本本身,后边的参数对应的编号依次类推。

如执行: ./xxxx.sh a b 则对应编号0的参数为./xxxx.sh 1->a 2->b。

$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。
               如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$    脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
               如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。表示没有错误,其他任何值表明有错误。
           

shell的基本运算符

算数运算符、关系运算符、布尔运算符、字符串运算符、文件测试运算符等

原生的bash不支持简单的数学运算,但可以通过其他命令来实现,例如awk和expr。

#!/bin/bash
val=`expr  + `
echo "两数之和为 : $val"
           

注意两点:val后的引号为

反引号

,2 + 2 的加号两边必须留空格

假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例

+ 加法

expr $a + $b

结果为 30。

- 减法

expr $a - $b

结果为 -10。

* 乘法

expr $a \* $b

结果为 200。

/ 除法

expr $b / $a

结果为 2。

% 取余

expr $b % $a

结果为 0。

= 赋值 a= b将把变量b的值赋给a。==相等。用于比较两个数字,相同则返回true。[ a == b]返回false。!=不相等。用于比较两个数字,不相同则返回true。[ a != $b ] 返回 true。

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例

-eq 检测两个数是否相等,相等返回 true。 [ a−eq b ] 返回 false。

-ne 检测两个数是否相等,不相等返回 true。 [ a−ne b ] 返回 true。

-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ a−gt b ] 返回 false。

-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ a−lt b ] 返回 true。

-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。[ a−ge b ] 返回 false。

-le 检测左边的数是否小于等于右边的,如果是,则返回 true。[ a−le b ] 返回 true。

假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例

!   非运算,表达式为 true 则返回 false,否则返回 true。  [ ! false ] 返回 true。
-o  或运算,有一个表达式为 true 则返回 true。                               [ $a -lt  -o $b -gt  ] 返回 true。
-a  与运算,两个表达式都为 true 才返回 true。              [ $a -lt  -a $b -gt  ] 返回 false。

假定变量 a 为 ,变量 b 为 :
运算符 说明  举例
&&  逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
||  逻辑的 OR  [[ $a -lt 100 || $b -gt 100 ]] 返回 true
           

假定变量 a 为 “abc”,变量 b 为 “efg”:

运算符              说明                                                                                 举例
=   检测两个字符串是否相等,相等返回 true。                [ $a = $b ] 返回 false。
!=  检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z  检测字符串长度是否为,为返回 true。                [ -z $a ] 返回 false。
-n  检测字符串长度是否为,不为返回 true。             [ -n $a ] 返回 true。
str 检测字符串是否为空,不为空返回 true。                 [ $a ] 返回 true。
           
操作符             说明                                      举例                                                                                                             

-b file 检测文件是否是块设备文件,如果是,则返回 true。  [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。         [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。[ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。  [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是有名管道,如果是,则返回 true。      [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。  [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。          [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。          [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。         [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于),不为空返回 true。[ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。    [ -e $file ] 返回 true。
           

Shell的流程控制

if else-if else块
基本语法
if condition
then
    command
elif
then
    command
else
    command
fi
           

for 循环

基本语法

for var in item1 item2 …itemN 
do
    command
done
           

写成一行

for var in item1 item2 ... itemN; do command; command2… done;
           

while语句

while condition
do
    command
done
           

无限循环 ‘while ;’ 或 ‘while true’ 或 for(( ; ; ))

until 循环

执行一系列命令,直到特定条件时停止。

until condition
do
          command
done
           

case

基本语法

case 值 in
    模式)
        command
        ;;      
    模式)
               command
        ;;
    *) 
        other command
        ;;
esac
           

跳出循环

break 终止执行后面的所有循环

#!/bin/bash
while :
do
    echo -n "输入 1 到 5 之间的数字:"
    read aNum
    case $aNum in
        ||||) echo "你输入的数字为 $aNum!"
        ;;
        *) echo "你输入的数字不是 1 到 5 之间的! 结束"
            break
        ;;
    esac
done
           

continue 跳出当前循环,不结束循环。

Shell函数

shell函数定义格式:

[ function ] funname [()]
{
    action;
    [return int;]
}
           

1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。

2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)

3、返回值通过$?来获得。

4、函数必须定义在使用前,否则无法找到函数。

函数参数获取:

函数名 参数1 参数2 … 参数N

注意:当参数大于10个的时候,使用 10不能获取参数,需要使用 {10}来获取。

$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$    脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。表示没有错误,其他任何值表明有错误。
           

重定向命令列表如下:

命令 说明

command > file 将输出重定向到 file。

command < file 将输入重定向到 file。

command >> file 将输出以追加的方式重定向到 file。

n > file 将文件描述符为 n 的文件重定向到 file。

n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。

n >& m 将输出文件 m 和 n 合并。

n <& m 将输入文件 m 和 n 合并。

<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

重定向深入讲解

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。

标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。

标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

如果希望 stderr 重定向到 file,可以这样写:

command2>file如果希望stderr追加到file文件末尾,可以这样写: command 2 >> file

2 表示标准错误文件(stderr)。

如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

command > file 2>&1  

或者 command >> file 2>&1

如果希望对 stdin 和 stdout 都重定向,可以这样写:

$ command < file1 >file2

command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。

Shell 文件包含

和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。

Shell 文件包含的语法格式如下:

. filename # 注意点号(.)和文件名中间有一空格

source filename