bash脚本语法学习

                                   Bash script语法学习

                                                 (材料为bash reference manual)

3.1.2引用

     简单来说就是通过一些操作让一些特殊字符原样输出,而不是被识别成指令或者变量值。

   一些操作如下:

       转义字符 \ :保留反斜杠(backslash)后跟的字符的字面意思,例如:echo "\"test\""输出”test”,因为双引号为特殊字符,要作为普通字符输出需要反斜杠转义。但有一个例外,反斜杠后跟回车代表新起一行,一般用于命令太长一行打不完,用这个可以在第二行接着打。

       单引号:单引号里的内容保留其字面意义,两个单引号之间不能再用一个单引号,哪怕加了反斜杠。

       双引号:双引号里大部分内容都按字面意义输出,有以下例外:$  ‘  \  !   其中叹号只有在history expansion启用时才有特殊意义,这玩意我也不清楚,后面看到了再说。$代表引用变量值,单引号除啦上一段我还不知道有什么特殊的意义。反斜杠只有在后跟$、单引号、双引号、反斜杠、换行这几个特殊字符时才有特殊意义。例子:echo "\$\'\"\\\!" 输出为$\'"\\!

       . 3.1.2.4  ANSI-C Quoting

 

3.1.3 注释

       第一行开头#后跟注释,不能打在命令后面。且注释能用只在以下几种情况:In a non-interactive shell, or an interactive shell in which the interactive_comments option to the shopt builtin is enabled

 

3.2.2管道以及3.6重定向以及文件描述符另开一篇

 

3.2.3

       Cmd1 && cmd2 ,cmd1||cmd2 只有当cmd1返回0时才会执行第二个,整句的返回值为最后一个执行的命令的返回值。

 

3.2.4.1

       三种循环结构,在讲这个之前,由于我不知道有没有自带的返回值几次执行后会从非零变到0的命令,所以为了可以测试这三个循环结构,我先写了一个简单的返回值从3到0循环变化的脚本,如下:

#!/bin/bash

#read var file,assign the value to the var1

while read line

do

var1=$line

done < var

#delete after read,the arguments -i is necessary,or else it will not be effective,

#only print the result without change the file

sed -i '/'"$var1"'/d' var

let var1--

#be cautious that the space is necessary

if [ "$var1" = "-1" ];then

var1=3

fi

#write the var1 to the var file

echo "$var1" >> var

echo $var1

exit $var1

 

该文件置于家目录的bin下,同时新建一个文本文件var,输入3保存即可。这个脚本就是读取文件里的数字赋给var1变量,删除文件里的这个数字,var1变量--,写回文件中,若这个变量为-1,重新赋值为3,最后返回var1。效果就是每执行一次输出一个数,返回值也是这个数,值从3到0循环变化。

 

接下来简单讲三个循环结构

#test-commands非零时执行do后面的命令,整个语句返回值为最后一个被执行的consequent-commands返回值,若没有被执行过则返回0

until test-commands;

do consequent-commands

done

以下为测试效果,test1.sh为之前的脚本,test2如下

#!/bin/bash

until test1.sh;

do echo "untilDo"

done

exit 0

 

#test-commands为零时执行do后面的命令,整个语句返回值为最后一个被执行的consequent-commands返回值,若没有被执行过则返回0

while test-commands

do consequent-commands

done

以下为测试

#!/bin/bash

while test1.sh

do echo "untilDo"

done

exit 0

 

先将var的值调为1,执行test2.sh,结果如下

 

For循环,有两种形式,先说更符合c的一种,如下

for (( expr1 ; expr2 ; expr3 ))

do commands

done

 

开始时,expr1被执行,接着expr2值若为非零,执行commands后执行expr3,再检查expr的值,如此往复,若3个式子有一个或多个省略,默认为1,返回值为最后执行的commands的值,若没有被执行,返回false。

例子如下

#!/bin/bash

for (( i=1 ; i<3 ; i++ )) 

do echo "forDo"

done

exit 0

输出:

 

再看另一个例子

#!/bin/bash

test1.sh

var1=$?

for ((  ;var1;  )) 

do echo "forDo"

test1.sh

var1=$?

done

exit 0

 

test1就是之前写的那个,$?可以获得上次执行的命令的返回值,注意这个for里能放的只能是表达式,不像之前两个循环结构,我放命令在for里会有语法错误。输出如下

 

再说说for的第二种形式

for 变量 in 值1 值2 值3…
do
程序
done

变量分别被赋为值1 值2 ….,每赋值一次执行一次后面的程序,有几个值就循环几次,例子如下

#!/bin/bash

for t in 1 2 3

do echo "t:$t"

done

exit 0

 

输出

 

还有一种用法,涉及到后面的知识,所以只是在这记录下

for t

do echo "t:$t"

done

exit 0

 

输出

 

 

分支结构

if test-commands

then consequent-commands

elif more-test-commands

then more-consequents;

else alternate-consequents;

fi

为0为真,执行对应if后面的语句,最后的else执行条件为,前面所有语句均不符合条件(返回值不为零)

以下为test2.sh

#!/bin/bash

if test1.sh

then echo "if-1"

elif test1.sh

then echo "if-2"

else echo "if-3"

fi

exit 0

 

几组测试如下

 

Case语句语法

case $var in

var1 | var2 )

Cmd1

;;

var3)

Cmd2

;;

*)

Cmd3

;;

Esac

 

根据var变量,选择一致的分支,执行对应指令,若都不符合则执行最后的指令

测试代码如下

#!/bin/bash

test1.sh

var=$?

case $var in

1 | 2)

echo "1 or 2"

;;

3)

echo "3"

;;

*)

echo "*"

;;

esac

exit 0

 

输出如下

 

select 语句

select表达式是bash的一种扩展应用,擅长于交互式场合。用户可以从一组不同的值中进行选择:

select var in ... ; do

 break;

done

.... now $var can be used ....

 

下面是一个简单的示例:

#!/bin/bash

 

echo "What is your favourite OS?"

select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do

  break;

done

echo "You have selected $var"

该脚本的运行结果如下:

What is your favourite OS?

1) Linux

2) Gnu Hurd

3) Free BSD

4) Other

#? 1

You have selected Linux

 

 

关于(( )):If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to let "expression"  实例如下

 

3.2.4.2关于[[ ]] 太长了 先跳过

 

3.2.4.3 ()和{}的作用是将几个指令作为一个整体执行,以下为使用的实例

Dir1和dir2中分别有2个和一个文件,若要统计的是这两个目录下文件的总数,可以用如下方法。

两个均可以,wc -l统计行数,wc -w统计单词数,这里注意,第一个ls虽然输出是两个一行的文件名,但是应该是显示的时候对ls的输出做了处理,实际上,把ls输出重定向到文件再用cat显示,它是有换行的,所以统计行数为2

 

 

有几点注意可以提一下。

可见,( )的内容是在子shell中执行的,所以变量更改没有生效,另外,使用{ }时,大括号旁的空格和最后一个命令的分号都不能少。

 

3.2.5 没看懂,跳过

 

3.2.6简单介绍了下GNU Parallel,这是一个能实现任务并行处理的工具,暂时用不到,就先跳过了。

 

3.3shell函数,我个人理解就是把一段命令取了个名字,调用这段命令就变得简便一些。

 

猜你喜欢

转载自blog.csdn.net/sinat_30457013/article/details/89531354