shell脚本基础

可关注网址:http://www.shellcn.net/

http://blog.csdn.net/taiyang1987912/article/details/39551385

shell脚本是shell命令的集合。

第一行应指定执行脚本的shell程序,#! /bin/sh

shell命令的行末不能加符号,如;,除非符号作为参数的一部分。

变量

所有变量无类型,都是字符串。不支持小数。

定义变量时不用$,取变量时要用$--${var}或$var,其中{}指定变量名边界(推荐)。

所有变量初值均为空串("\0")。

定义变量时等号=两边不能有空格,变量名首个字符必须是字母(a-z,A-Z),且只能包含数字、字母和下划线。

可用readonly将变量定义为只读变量,只读变量的值不能被改变。

可用unset删除变量,但只读变量readonly不能用unset。

如果值中含有空格时,需要加上引号。 second=”Hello world one”

当将几个变量连接起来时,需要使用引号。 fullname=”$first $second”

局部变量作用域仅限下函数内,关键字local。受限于不同系统,不是posix标准。

变量替换

${var} 变量本来的值

${var:-word} 如果变量为空或已被删除(unset),那么返回word,但不改变var的值。

${var:=word} 如果变量var为空或已被删除(unset),那么返回word,并将var的值设置为word。

${var:?message} 如果变量var为空或已被删除(unset),那么将消息message送到标准错误输出,可以用来检测变量var是否可以被正常赋值。若此替换出现在shell脚本中,那么脚本将停止运行。

${var:+word} 如果变量var被定义,那么返回word,但不改变var的值。

${var/pattern/pattern}表示将var字符串的第一个匹配的pattern替换为另一个pattern。

${var//pattern/pattern}表示将var字符串中的所有能匹配的pattern替换为另一个pattern。

算术代换

$((表达式))

支持+-*/

eg. a=100; b=200; c=$(($a+$b));

命令代换

`shell`(反引号) 或 $()

eg. DATA=$(date)

其中命令可为shell命令或函数。

算术运算符

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

支持+、-、*、/、%、=、==、!=。

注:条件表达式要放在方括号之间,并且要有空格。

#! /bin/sh

a=10

b=20

val=`expr $a + $b`

val=`expr $a \* $b`

关系运算符

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

-gt 大于

-ge 大于等于

-lt 小于

-le 小于等于

-eq 相等

-ne 不等于

布尔运算符

! 非运算,表达式为ture则返回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。

字符串运算符

= 检测两个字符串是否相等,相等返回true。

!= 检测两个字符串是否相等,不相等返回ture。

-z 检测字符串长度是否为0,为0返回ture。

-n 检测字符串长度是否为0,不为0返回true。

str 检测字符串是否为空,不为空返回true。 [ $a ] 返回true。

[ -z STRING ] 字符串长度为0则真,空串

[ -n STRING ] 字符串长度不为0则真,非空串

比较数值字符串,常用方法: test "pre"$dig1 = "pre"$dig2 || mv $file $dir

先转换数值为字符串后比较。

文件测试运算符

文件测试运算符用于检测unix文件的各种属性。

文件测试运算符列表

操作符

说明

举例

-b file

检测文件是否是块设备文件,如果是,则返回 true。

[ -b $file ] 返回 false。

-c file

检测文件是否是字符设备文件,如果是,则返回 true。

[ -b $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。

shell字符串

单引号内字符全字面义,任何字符都会原样输出,单引号字符串的变量无效。单引号内不能出现单引号(对单引号转义也不行)。

双引号可以有变量,可有特殊字符:

反引号仍代表命令替换

\$标识$的字面值

`标识`的字面值

\"标识"的字面值

\标识\的字面值

拼接字符串

your_name=”www”      

greeting=”hello, ”$your_name” !”

greeting1=”hello, ${your_name} !”

获取字符串长度

string=”abce”

echo ${#string}   #输出4

提取子字符串

string=”alibaba is a great company”

echo ${string:1:4}    #输出liba

查找子字符串

string=”alibaba is a great company”

echo `expr index “$string” is`

数组

bash支持一维数组(不支持多维数组),并且没有限定数组大小。用小标取元素。

定义数组

shell中用括号表示数组,数组元素用“空格”符号分割。一般形式为:

array_name=(value1 … valuen)

读取数组

${array_name[index]}

使用@或*可以获取数组中的所有元素:${array_name[*]},${array_name[@]}

获取数组长度

获取数组长度的方法与获取字符串长度的方法相同,如

length=${#array_name[@]}  ${#array_name[*]}   #获取数组元素个数

length=${#array_name[n]}   #获取数组单个元素的长度

逻辑语法

if [ 表达式 ]; then

...

elif [ 表达式 ]; then

...

else

...

fi


while [ ] # 只要满足条件会永远执行,不满足条件时退出
do ...
done
________________________________________
until [ ] # 只要不满足条件就永远执行,满足条件时退出
do ...
done


for i in apple banana pear

do

echo $i;

done

for 变量 in 列表

do

      command1

      command2

      commandN

done

列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中下一个值赋给变量。

in列表是可选的,如果不用它,for循环使用命令行的位置参数。

for file in `ls`; do echo $file; done


case 值 in

模式1)

      command1

       command2

       ;;

模式2)

       command1

       command2

       command3

       ;;

*)

       command1

       command2

       command3

       ;;

esac

case取值可以为变量或常数。

read读入数据,echo打印数据

#! /bin/sh

read tmp

echo "input is $tmp."

printf输出

echo输出在不同unix版本之间选项有很大不同。有了printf命令,它模仿c程序库的printf().

printf  string  arguments

printf “The first program always prints %s %s\n”  Hello World

#! /bin/sh -
tmp=0
while [ $tmp -lt $1 ]
do
    printf "%.2x " $tmp
    tmp=`expr $tmp + 1`
done

exit 0

shift与选项处理

shift用来处理命令行参数,一次向左移动一位(或更多位)。在执行shift之后,原来的$1就会消失,以$2的旧值取代,$2的新值即为$3的值,依次类推,而$#的值也会逐次减少。
shift可接受一个参数,指定要移动几位,默认为1。

脚本参数

$0  当前脚本的文件名

$n  传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。判断第一个参数存在即非空,应用[ -n "$1" ]而非[ -n $1 ],前者将空转化为字符串为空值,后者永远成立。

$#  传递给脚本或函数的参数个数。

$*  传递给脚本或函数的所有参数。

$@  传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同

$?  上个命令的退出状态,或函数的返回值。shell退出状态为0-255,最大值为255。

$$  当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

父进程id:ppid=$(awk '{print $4; }' /proc/$$/stat)
祖父进程id:pppid=$(awk '{print $4; }' /proc/$ppid/stat)

示例

ping整个局域网,查询可用ip(一般DHCP分配IP):

#/bin/sh

num=2
while [ $num -lt 255 ]
do
    ip="172.10.1.$num"
    ping -c 1 $ip 
    if [ $? -eq 0 ]; then
        echo "----------------------------------------------------------$ip"
    fi  
    num=$(($num+1))
done

exit 0

 case用法:

#!/bin/sh

wan_way=$(cat /etc/wan_way)
case $wan_way in
    "dhcp" | "static" )
        ifconfig wlan0 down
        echo "dhcp or static"
        ;;
    "wifi")
        ifconfig eth0 down
        echo "wifi"
        ;;
    "pppoe")
        ifconfig wlan0 down
        systemctl restart pppoe
        echo "pppoe"
        ;;
    *)
        echo "not dhcp, static, pppoe or wifi"
        ;;
esac

exit 0

拼接字符串

#!/bin/sh

write_log(){
    local up_name=$1
    local num=${#string}

    while [ $num -le 256 ]; do
        up_name="$up_name*"
        num=$(($num + 1))
    done
    echo $up_name
}

write_log "wang"
wang*****************************************************************************************************************************************************************************************************************************************************************

 

 

参考:

1. http://c.biancheng.net/cpp/view/2739.html

2. http://www.cnblogs.com/jiqing9006/p/3253232.html

posted @ 2015-12-23 22:34  yuxi_o  阅读(421)  评论(0编辑  收藏  举报