#!/usr/bin/env bash #---------------------- # 这里是注释 #---------------------- <<EOF 这里是多行注释 EOF echo "hello, world" # printf 后面的格式化字符串可以是加双引号,可以加单引号,可以不加引号 printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876 name="abc" # 定义变量,等号两边不能有空格 unset name # 注销变量 # 局部变量 - 局部变量是仅在某个脚本内部有效的变量。它们不能被其他的程序和脚本访问。 # 环境变量 - 环境变量是对当前shell会话内所有的程序或脚本都可见的变量。创建它们跟创建局部变量类似,但使用的是 export 关键字,shell 脚本也可以定义环境变量。 # 数据类型:整型 字符串 数组 # 单引号不识别变量,双引号识别变量 str1="abc" str2="123" echo "$str1""$str2" # 获取字符串长度 echo "${#str1}" # 获取子串长度,下标从0开始,最后一个参数截取字符串个数 str3="123456" echo ${str3:1:3} echo ${str3:1:1} # 查找子字符串的位置 str4="123456aabcdef" echo `expr index ${str4} aa` # bsah只支持一维数组,下标必须大于等于0 arr1=("aa", "bb", "cc") arr2=([2]=2 [0]=0 [1]=1) echo ${arr1[0]} echo ${arr1[1]} echo ${arr1[*]} # 输出全部数组元素 echo ${arr1[@]} # 输出全部数组元素 echo ${#arr1[*]} # 访问数组长度 arr3=("11", ${arr1[*]}, "22") # 向数组中添加元素,实际上是创建一个新数组 echo ${arr3[*]} unset arr2[2] # 删除数组中的元素 echo ${arr2[*]} # 算术运算 <<EOF 运算符 说明 举例 + 加法 expr $x + $y 结果为 30。 - 减法 expr $x - $y 结果为 -10。 * 乘法 expr $x * $y 结果为 200。 / 除法 expr $y / $x 结果为 2。 % 取余 expr $y % $x 结果为 0。 = 赋值 x=$y 将把变量 y 的值赋给 x。 == 相等 用于比较两个数字,相同则返回 true。 [ $x == $y ] 返回 false。 != 不相等 用于比较两个数字,不相同则返回 true。[ $x != $y ] 返回 true。 EOF a=10 b=20 echo `expr $a + $b` echo `expr $a - $b` echo `expr $a / 3` # 关系运算:关系运算符只支持数字,不支持字符串,除非字符串的值是数字 <<EOF 运算符 说明 举例 -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。 EOF if [[ ${a} -eq ${b} ]]; then echo "${a} -eq ${b} : a 等于 b" else echo "${a} -eq ${b}: a 不等于 b" fi # 布尔运算 <<EOF 运算符 说明 举例 ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。 -o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。 -a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。 EOF if [[ ${a} -eq ${b} && false ]]; then echo "${a} -eq ${b} : a 等于 b" else echo "${a} -eq ${b}: a 不等于 b" fi # 字符串运算符 <<EOF 运算符 说明 举例 = 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。 != 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。 -z 检测字符串长度是否为 0,为 0 返回 true。 [ -z $a ] 返回 false。 -n 检测字符串长度是否为 0,不为 0 返回 true。 [ -n $a ] 返回 true。 str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。 EOF s="abcd" if [[ -z $s ]]; then echo "字符串是空" else echo "字符串不是空" fi # 文件测试运算符 <<EOF 操作符 说明 举例 -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 检测文件是否为空(文件大小是否大于 0),不为空返回 true。 [ -s $file ] 返回 true。 -e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。 EOF file="/etc/hosts" if [[ -r ${file} ]]; then echo "${file} 文件可读" else echo "${file} 文件不可读" fi echo "*********************************************************" # 控制语句 x=1 y=2 if [[ $x > $y ]]; then echo "x > y" elif [[ $x < $y ]]; then echo "x < y" else echo "x = y" fi operator="+" case $operator in "+") echo `expr $x + $y` ;; "-") echo `expr $x - $y` ;; "*") echo `expr $x * $y` ;; "/") echo `expr $x / $y` ;; *) echo "default" ;; esac z=1.2 case $z in 1.2) echo "two" ;;& "1.2") echo "one" ;; *) echo "default" ;; esac # )匹配case,;;表示break,*)表示匹配任意条件,也就是最后的default # ;;& 后面的条件继续匹配,匹配的case会进入执行 # ;& 后面挨着的一个case无条件执行,直到break跳出 # 循环语句 for x in 2 3 4 5 6 do echo $x done data=(8 9 10) for x in ${data[*]} do echo $x done for (( i = 0; i < 10; i++ )); do echo $i done for path in /home/chusiyong/* do echo $path done x=0 while [[ ${x} -lt 10 ]] do echo $((x * x)) x=$((x + 1)) done x=0 until [[ ${x} -ge 5 ]]; do echo ${x} x=`expr ${x} + 1` done # 函数 <<EOF [ function ] funname [()] { action; [return int;] } 函数定义时,function关键字可有可无。 函数返回值,return返回函数返回值,返回值类型只能为整数(0-255)。如果不加return语句,shell默认将以最后一条命令的运行结果,作为函数返回值。 函数返回值在调用该函数后通过 $?来获得。 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时才可以使用。调用函数仅使用其函数名即可 函数内部获取参数 变量 描述 $0 脚本名称 $1 … $9 第 1 个到第 9 个参数列表 ${10} … ${N} 第 10 个到 N 个参数列表 $* or $@ 除了$0外的所有位置参数 $# 不包括$0在内的位置参数的个数 $FUNCNAME 函数名称(仅在函数内部有值) 函数调用 funname arg1 arg2 ... EOF func () { echo "$1" echo "$2" echo "$#" } func "one" "two" # shell扩展 # 大括号扩展 echo {0..10} echo {0..10..2} # 命令置换 now=`date +%T` echo $now # 单引号和双引号之间有很重要的区别。在双引号中,变量引用或者命令置换是会被展开的。在单引号中是不会。 INPUT="A string with strange whitespace." echo $INPUT echo "$INPUT" # 重定向 <<EOF 代码 描述符 描述 0 stdin 标准输入 1 stdout 标准输出 2 stderr 标准错误输出 EOF # command > /dev/null 2>&1 标准输出和标准错误都输出到/dev/null # command > /dev/null 2>1 标准错误输出到文件名是"1"的文件