shell学习入门

印象中,一直觉得只要多掌握linux命令,自然对于写shell脚本不会陌生.这句话对也不对.前半句对了,的确是要多掌握linux命令,这样才能写出使用高效的脚本,但是后半句不对.要写出shell脚本,还需要掌握shell的内部命令,流程控制,以及重定向等.

最近系统的学习了一些shell的入门,有了很多新的认识,积累如下.

1. 变量:

shell中,变量的使用并不需要声明,可以直接使用,而且没有类型的限制,同样一个变量,不同的操作,决定变量不同的类型,比如 [ $a = $b ],这里的变量a和b,是字符串.但是同样是他俩,[ $a -gt $b ],在这里他俩就成了数字.当然这只是特殊情况,如果a的值并不是数字,是会报错的.

同时需要明确,linux大小写敏感,shell自然也不例外.

另外需要注意的就是变量拓展,即声明一个a变量,$ab并不会被识别成a的值接上b,而应该${a}b.另外一种非变量拓展的方式是"$a"b

环境变量,用来改变shell的行为的一种特殊变量.常用的有

$HOME   当前用户的家路径

$PATH   当前系统的搜索命令的路径

$PS1   命令提示符

$PS2  二级提示符,即当输入的命令没有输入完全的时候的提示符

$IFS   域分隔符   默认是空格,制表符,换行符

$0   shell脚本的名字

$#   shell脚本参数的个数

$$   shell脚本的进程号

$1...$n   shell脚本的参数

$*   shell脚本参数列表,受域分隔符的影响.

$@   shell脚本参数列表,不受域分隔符的影响.

例如:

技术分享

2. 条件判断

test 和 [  ] , 对于判断而言,二者作用是完全一样的,可以使用test就可以用 [ ].

目前判断大致可以分为三种,

字符串的判断

[ $string1 = $string2 ]    字符串相等.这里需要注意空格的使用.

[ $string1 != $string2 ]   字符串不想等

[ -n $string1 ]   字符串不为空

[ -z $string1 ]  字符串为空

数字比较

[ $a -eq $b ]   a和b相等

[ $a -ne $b ]   a和b不相等

[ $a -gt $b ]   a大于b

[ $a -ge $b ]   a大于等于b

[ $a -lt $b ]   a小于b

[ $a -le $b ]   a小于等于b

[ ! a ]  a为假则表达式为真,注意空格的使用.

文件判断

-f   是否是普通文件

-e   是否存在,但是存在可移植性问题.并不是每个版本的shell都支持这个选项

-d   是否是目录

-b   是否是块文件.

-s   是否大小不为0

-r   是否可读

-w   是否可写

-x   是否可执行

以上为是,则为真.

3. 流程控制   (if   for   while   until   case)

if   测试某个结果,根据结果的不同做出不同的工作.

常见的if控制结构:

if [ condition ]

then

    command

elif [ condition ]

then

    command

else

    command

fi

举个例子:

#!/bin/bash

echo what day is it today?
read day

if [ $day = sateday ] || [ $day = sunday ]
then
    echo oh good!!!
else 
    echo oh god...
fi

这个小例子里面还包括了一个知识点,即命令列表的知识,简单的拓展一下.

command1 && command2 && command3 && .....    此shell语句中,从左往右顺序执行,遇到第一个返回false的命令则不再继续执行.

command1 || command2 || command3 || .....   此shell语句从左往右顺序执行,遇到第一个执行成功的命令就不再继续执行.

for    循环执行执行某个命令块.

用法如下:

for 变量 in 范围

do

    something

done

范围可以通过大括号指定,也可以是一个命令或者一个变量.如示例:

#!/bin/bash                                                                                                                                                          
                                                                                
echo test for 1                                                                 
for i in {a,b,c}                                                                
do                                                                              
    echo -e "\t$i"                                                              
done                                                                            
echo test for 1 end                                                             
                                                                                
echo test for 2                                                                 
for i in {d..g}                                                                 
do                                                                              
    echo -e "\t$i"                                                              
done                                                                            
echo test for 2 end                                                             
                                                                                
echo test for 3                                                                 
for i in `seq 10`                                                               
do                                                                              
    echo -e "\t$i"                                                              
done                                                                            
echo test for 3 end                                                             
                                                                                
echo test for 4                                                                 
filelist=$(ls)                                                                  
for i in $filelist                                                              
do                                                                              
    echo -e "\t$i"                                                              
done                                                                            
echo test for 4 end 

while   循环执行一段代码块但是和for不一样的是,while后面跟的是一个条件限定,而不是一个范围.while循环执行直到条件为假.

基本用法如下:

while condition

do

    something

done

一般可以作为condition的有很多,if里面适用的在这里也几乎适用.如下:

#!/bin/bash

while read i 
do 
    echo $i
done < for.sh

echo "this is a test" | while read i 
do
    echo $i
done
一定要注意shell中的真假只能用true(:)和false来表示.如果你用0或者1,那就错了.对于shell而言,无论0和1在条件判断中,都是真.而在上面的这个例子中,文件为eof代表条件为假.


until   循环执行一段代码段.和while相反,until循环执行直到条件为真.

用法和while类似.

until condition

do

    something

done

惭愧,我一时竟然想不到一个可以使用的例子.抄一段:

#!/bin/bash

until who | grep "$1" > /dev/null
do
    sleep 60
done

echo -e "\a"
echo "$1 logged"
这个脚本的意思是,指定一个参数,也就是$1.如果$1代表的用户登陆过系统,就报警并且打印信息然后退出.否则就循环等待.


case    分支语句,和if有点类似我想,看看用法吧.

case 变量 in

pattern1)  something ;;

pattern2)  something ;;

esac

还是通过一个实例来看看他是怎么使用的吧.

#!/bin/bash

echo will you marry me?

read choice
case $choice in 
    Y|y|[Yy][Ee][Ss]) 
        echo yes, i will
        ;;
    [Nn]*)
        echo you are good man,please don\'t let me hurt
        ;;
    *) 
        echo ni chi fan mei you
        ;;
esac
case的语句可以选择的几种方式,上面都列了出来.

Y|y|[Yy][Ee][Ss]   #这段的意思是,无论输入Y或者y或者YEs或者yeS都会输出yes,i will
而*)的意思相当于default.

<span style="font-size:18px;">4. 函数</span>

shell的函数很简单.不需要参数,不需要返回值.只需要这样

func()

{

    do something

}

但是这个函数看起来不是和废物一样嘛,接受不了参数,又没有办法输出结果.肯定不是啊,shell的函数可以理解成一个脚本内的脚本,也就是说他传递参数的方式和shell脚本接收参数的方式类似.$#表示函数的参数个数,$@函数的参数列表$*也是参数列表$1$2是函数的第1或者2个参数.

#!/bin/bash

test_master()
{
    if test $# -ne 2
    then
        echo please input 2 parameter
        exit
    fi

    echo who is the master in your home?
    for i in `seq $#`
    do
        eval res='$'$i
        if [ $res != "alai" ]
        then
            echo $res
        fi
    done
}

test_master alai jingjing

5. 部分命令

本段主要涉及的都是内置命令.

break   用来跳出循环,为内置命令.可以在后面跟一个数字表示跳出多少层循环.一般不建议这么使用.容易把代码逻辑搞乱.

:命令   此命令为空命令.永远表示true,但是运行速度要快于true(书本上这么说的,我反正察觉不到),很早之前的shell习惯性的用 : command 的方式作为脚本注释.现在统一采用#

continue    跳大下一次循环,统一可以跟一个数字表示继续第n此循环,也不建议这么使用.

. 命令   表示在当前shell执行命令.一般我们用的./的方式,会生成一个子进程然后执行脚本,使用这个命令,直接在当前的进程执行命令.

echo   打印命令.不解释啦.

eval   这个命令很有趣,允许对参数进行求值.上面讲解函数的时候也有它的用法.这里不多说啦.不要忘记单引号哈.

exit n   以退出码n来结束脚本的运行.目前而言0表示运行成功.其它表示运行失败.在脚本中多运用这个命令是个很好的习惯.

export   将其后的变量导入到子shell中.

expr   将参数作为表达式求值相当于$[ ]    用法  res=`expr 1+2`

let   作用和expr是一样的,用法有差异   let a=1+1   注意别有空格.这个应该不是内置的


大致就总结这么多吧.希望能够对同学们入门shell有帮助.

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。