Linux shell 编程

Shell 是用户使用操作系统的命令接口,Shell 接受用户以命令行方式输入的命令,也能解释执行由 shell 命令所编写的 shell 程序。用户可以将 Linux 的命令以编程的方式组合起来提交给 shell, shell 负责解释执行这种程序设计语言所编写的代码。这种程序设计语言构成的文件成为 shell script 或 shell 脚本。

Shell 脚本是包含一个或多个 shell 命令的集合,这些命令按照编写的顺序而被依次执行。建立 shell 脚本文件与建立普通文件一样,可以用 vi、emacs等来建立。

 Bash shell 使用 中有 shell 变量、万用字符、数据流重导向、管线命令等内容,在此就不再介绍,只介绍一些其他的知识。


一、shell 基础知识

单引号、双引号与反引号

  • 双引号(" "):将“$”、“"”、“`”和“\”进行替换,作为特殊字符;
  • 单引号(' '):所有特殊字符均为普通字符;
  • 反引号(` `)“:字符解释成命令,并返回执行结果。

运行脚本
运行 shell 脚本文件的三种方法:

  • 把文件的权限设为可读、可执行,然后直接执行该文件;
  • 使用shell 的启动命令来执行:bash 脚本名及其参数;
  • 使用 bash 内部命令 source 或 . 来执行:source 脚本名及其参数 或 . 脚本名及其参数。

位置变量
位置变量是依据出现在命令行上的参数的位置来确定的变量。在调用 shell 程序的命令行中,参数的位置定义如下:

命令 参数1 参数2 ...

位置变量与命令行参数对应关系为:

$0:对应执行的命令名

$1:对应第一个参数

$2:对应第二个参数

... ...

$9:对应第九个参数

如果命令行上参数多余 9 个时,需要使用 shift 命令移动参数位置。每执行一次 shift 命令,变量 0 不变,从 1 开始位置参数左移一位。

数组变量

数组的索引从数字 0 开始,引用时需要使用中括号([])。

数组有两个特殊的索引:“*” 和 “@”,作用都是提取整个数组元素。但在加了双引号之后:

“@”表示原数组复制成一个新的数组,新数组与原数组一样;

“*”表示把原数组所有内容作为新数组的一个元素,新数组只有一个元素。

数组的个数:${ #name[*] }, name 为数组名。

数组元素的长度:${ #name[num] }, num 为数组下标。

name=("s1" "s2" "s3")    #定义一个数组变量
echo ${ name[0] }   #引用输出第一个变量
list=("${name[@]}")    #list 数组元素为 "s1" "s2" "s3"
class=("${name[*]}")    #class 为"s1 s2 s3"
echo ${#name[*]}    #数组元素个数
echo ${#name[0]}    #第一个元素的长度

特殊变量

shell中包含一些预定义的特殊变量,与环境变量类似。该类变量不能重新定义,均由“$”与另一个符号组成。常用的特殊变量:

  • $# :实际位置参数个数(不包括脚本名)
  • $* :所有位置参数组成的字符串
  • $! :上一个后台命令对应的进程号
  • $? :最近一条命令执行后的状态
  • $$ :当前进程号 PID

算术运算

expr 执行简单的整数操作,可使用:+、-、\*、/、% 五种运算符,运算符前后要有空格。

let 不需要在变量之前加美元符号,但必须将单个或带有空格的表达式用双引号引起来。

a=3; b=6
x=`expr $b / $a`    #整除,反引号
y=`expr $a + 1`    #a 加 1

let x=x+1   #x 加 1

二、控制结构

if 结构

语法:if 表达式;then 

    命令表

    [ else 命令表 ]

    fi

else 可以省略,fi 表示 if 结束。if 结构还提供 elif 语句,相当于 else if。

#!/bin/bash    #程序第一行,表示调用 bash 来执行脚本程序
#filename:ifcon    #程序名
read -p "输入字符串1" str1
read -p "输入字符串2" str2
if [ $str1 = $str2 ]    # 判断条件
then
    echo "两个字符串相同"
else
    echo "两个字符串不相同"
fi   #结束 if 

case 结构

语法:case 表达式 in

     模式1[|模式12 ] ...) 命令表1;;

     模式2[|模式22 ] ...) 命令表2;;

     ... ...

     *) 命令表n;;

    esac

说明:

  • 每一个分支可以有多个模式,但必须以“)”结尾;
  • 模式之间用“|”表示“或”的关系;
  • 每个分支以“;;”表示分支结束;
  • 分支 *)表示前面都不匹配时的处理,“esac” 表示 case 结束;
  • 模式中可以使用万用字符。
#!/bin/bash
#filename:case_con
a=$1    #取第一个参数赋给变量 a
case $a in 
    S|s)  
        case $2 in
            zou) echo "zou 同学,你好" ;;
            han) echo "han 同学,你好" ;;
            *) echo "未找到该名字" ;;
	    esac
    ;;    #第一个大分支结束
    T|t)  
        case $2 in
            zhou) echo "zhou 老师,您好" ;;
            zhang) echo "zhang 老师,您好" ;;
            *) echo "未找到该名字" ;;
	    esac
     ;;    #第二个大分支结束
    *)  echo "error input" ;;
esac

select 结构

语法:select 变量 in 列表
    do
      命令表
    done
select 生成一个数字化的菜单,并提示用户选择,用户只需按下对应菜单项的数字即可完成选择。
select 总是与 case 一起使用,先让用户选择,再基于选择执行相应的命令。

#!/bin/bash
#filename:select_con
select N in 周五 周六    #菜单由“周五、周六”组成
do
 case $N in  #根据选择,执行相应的菜单功能
     周五) echo "周五是工作日";;
     周六) echo "周六可以休息";;
     *) echo "选择错误" 
        break;;
 esac
done

while 循环

通常在无法确定循环次数时,使用 while 循环;当确切知道循环次数时,使用 for 循环。

用法:while 表达式

    do

      命令表

    done

for 循环

用法:for 变量 [ int 列表 ]

    do

      命令表

    done

“列表”通常由一系列以空格为分隔的字符串组成,依次将“列表”中的字符串赋给“变量”,直到取完。

如果“in 列表”省略,则会将当前执行脚本中的位置参数作为“列表”。

break 和 continue 语句可以从循环结构中跳出来,如 while、for、select 等循环。break 和 continue 都可以在其后加上数字,指明要跳出的结构的层数。

#!/bin/bash
#filename:while_for
i=1
while [ $i -le 5 ]   #“$i -le 5”为判断条件,当变量 i 小于等于 5 时循环
do
    echo "while 第 $i 次循环,输出:$i"
    i=$(($i+1))   #变量 i 加 1,也可用 let i=i+1 或 expr
done
for j in 1 2 3 4 5    #变量 j 依次取值 1、2、3、4、5
do
    echo "for 第 $j 次循环,输出:$j"
    let j=j+1;
done

三、条件测试

test 命令是 shell 编程中条件判断最常用的测试命令。test 命令的语法:test 表达式。test 命令也可以由方括号取代:[ 表达式 ]。

文件属性测试

常用的文件测试表达式格式:


#!/bin/bash
#filename:filetype
read -p "input the file name:" file
if test -c $file ; then    #判断是否是字符设备
   ls -l $file
elif test -d $file ; then    #判断是否是目录
   cd $file
else
   echo "$file 不是字符设备,也不是目录"
fi

数值测试

常用的数值测试表达式:


#!/bin/bash
#filename:numbertest
read -p "input n1:" n1
read -p "input n2:" n2
if [ $n1 -eq $n2 ] ; then    #判断两个变量的值是否相等
   echo "n1 等于 n2"
elif [ $n1 -gt $n2 ] ; then    #判断n1 是否大于 n2
   echo "n1 大于 n2"
else
   echo "n1 小于 n2"
fi

字符串测试

                                                           

#!/bin/bash
#filename:stringtest
read -p "input s1:" s1
read -p "input s2:" s2
if [ -z $s1 ] ; then    #判断字符串 s1 长度
   echo "s1 长度为 0"
elif [ $s1 = $s2 ] ; then    #判断 s1 与 s2 是否相等
   echo "s1 与 s2 相等,且长度不相等"
fi

逻辑运算符

常用的逻辑运算符:

#!/bin/bash
#filename:logical_test
read -p "input n1:" n1
read -p "input n2:" n2
if [ $n1 -ge $n2 -o $n1 -eq $n2 ] ; then    #判断 n1 是否大于等于 n2
   echo "n1 大于或等于 n2"
elif [ $n1 -ge 10 -a $n1 -le 30 ] ; then    #判断n1 大于 10 且小于 30
   echo "10 <= $n1 <= 30"
fi

四、函数

shell 函数类似于 shell 脚本,里面存放了一系列指令。不同的是,shell 函数可以有返回值,而脚本没有。

函数定义: function 函数名

       {

         命令表

         [return]

       }

函数中的 return 用于返回函数中最后一个命令的退出状态或给定的参数值。

可以在函数中使用 exit 或 break 语句来中断函数执行。

可以使用命令“declare -f”显示定义的函数。

shell 函数定义可以放在“~/.bash_profile”文件中,也可以放在使用该函数的脚本中,还可以直接放在命令行。

无论在函数内外,没有用关键字 local 声明的变量都是全局变量。

#!/bin/bash
#filename:hellofunc
function hello    #定义函数
{
   s="static"    #全局变量
   local a="temp"    #局部变量
   if test $1 = "T" ; then
      echo "hello teacher $2"
      return 1
   else
      echo "error input"
      return 0
   fi
}
echo $s    #输出 static
echo $a    #变量 a 未声明,无输出
hello T zhou   #执行函数,位置参数 T,zou
a=$?   # 变量 a 的值为函数 return 返回值

如果需要使用的函数保存在其他脚本文件中,可以通过 “source”或“.” 命令将函数载入到内存中,供当前脚本使用。

#!/bin/bash
#filename:sourcefunc
source hello   #使用 source 载入文件 hellofunc
read -p "input two para:" s1 s2
hello $s1 $s2    #调用 hello 函数,位置参数为 $s1 $s2 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值