第二章 shell的语法

来源:互联网 发布:a8 μcos linux stm32 编辑:程序博客网 时间:2024/06/06 10:58
变量:字符串、数字、环境和参数

获取变量内容可以在变量前使用$字符,使用echo指令可以将变量内容输出到终端。

wuchao@wuchao-Lenovo:~$ var=hellowuchao@wuchao-Lenovo:~$ echo $varhellowuchao@wuchao-Lenovo:~$ var=2+3wuchao@wuchao-Lenovo:~$ echo $var2+3

注意:如果字符串中间有空格,则必须使用引号。此外等式两边不能有空格。

使用read命令可以将用户输入的值赋给变量

wuchao@wuchao-Lenovo:~$ read varhello worldwuchao@wuchao-Lenovo:~$ echo $varhello world

引号的使用

双引号中使用$var时,程序自动替换成变量的值。单引号中使用$var时,不会发生替换。如果想把$当作普通字符,则在$使用\取消它的特殊含义。

wuchao@wuchao-Lenovo:~$ var="hello world"wuchao@wuchao-Lenovo:~$ echo $varhello worldwuchao@wuchao-Lenovo:~$ echo "$var"hello worldwuchao@wuchao-Lenovo:~$ echo '$var'$varwuchao@wuchao-Lenovo:~$ echo \$var$var

环境变量

$HOME :当前home目录

$PATH :搜索命令的目录

$0 :shell脚本的名字

$# :传递给脚本的参数的个数

$$ :shell脚本的进程号

参数变量

$1 , $2,…… :脚本程序的参数

$* :在一个变量中列出所有参数,使用IFS环境变量作为分隔符

$@ :$*的变体。但不使用IFS环境变量

wuchao@wuchao-Lenovo:~/linux_program$ cat test02#!/bin/shvar=helloecho "value of var is: $var"echo "runing"echo "this shell name is $0"echo "the first param is $1"echo "the second param is $2"wuchao@wuchao-Lenovo:~/linux_program$ ./test02 Hell Worldvalue of var is: helloruningthis shell name is ./test02the first param is Hellthe second param is Worldwuchao@wuchao-Lenovo:~/linux_program$ 

 

条件:shell中的boolean值

shell的boolean判断常常使用test或[命令。其中[命令可以使用]结尾。

比如测试hello.h文件是否存在:

if test -f hello.h

then

...

fi

或者

if [ -f hello.h ]

then

...

fi

注意:[后面必须有空格

test命令归为一下三类:

字符串比较

string1 = string2  相同为真

string1 != string2   不同为真

-n string1    判断字符串是否为非0,字符为空时为false

-z string1    判断字符串是否为0,字符串为null时为true

算术比较

expression1 -eq expression2    表达式结果相等

expression1 -ne expression2    表达式结果不相等

expression1 -gt expression2     前者大于后者

expression1 -ge expression2    前者大于等于后者

expression1 -lt expression2      前者小于后者

expression1 -le expression2     前者小于等于后者

文件条件测试

-d file    测试文件是否是一个目录

-e file    测试文件是否存在

-f file     测试文件是否是一个普通文件

-g file    如果文件的set-group-id位被设置则为真

-r file    测试文件是否可读

-s file    测试文件大小是否不为0

-u file    如果文件的set-user-id位被设置则为真

-w file    测试文件是否可写

-x file    测试文件是否可执行

程序控制:if、elif、for、while、until、case

if语句

if condition

then

statements

else

statements

fi

elif语句

if condition

then

statements

elif

then

statements

else

statements

fi

for循环

for variable in values

do

statements

done

举例:

wuchao@wuchao-Lenovo:~/linux_program$ cat test02#!/bin/shfor var in  hello world ccdo  echo $vardoneexit 0wuchao@wuchao-Lenovo:~/linux_program$ ./test02helloworldcc

使用通配符的for循环

打印所有以foo开头并以.sh结尾的文件

wuchao@wuchao-Lenovo:~/linux_program$ ls foo*.shfoo01.sh  foo02.sh  foo03.shwuchao@wuchao-Lenovo:~/linux_program$ cat test02#!/bin/shfor var in  $(ls foo*.sh)do  echo $vardoneexit 0wuchao@wuchao-Lenovo:~/linux_program$ ./test02foo01.shfoo02.shfoo03.sh

while语句

while condition

do

  statements

done

until语句

until condition

do

  statements

done

case语句

case variable in

pattern [ | pattern ] ...) statements;;

pattern [ | pattern ] ...) statements;;

...

esac

注:每个模式下都可以放置多条语句,因此使用;;表示模式的结束。

case示例一:

wuchao@wuchao-Lenovo:~/linux_program$ cat test02#!/bin/shecho "please input you choice (y,yes,n,no)"read choice;case "$choice" in  y ) echo "your choice is yes";;  yes ) echo "your choice is yes";;  n ) echo "your choice is no";;  no ) echo "your choice is no";;  * ) echo "wrong input";;esacexit 0wuchao@wuchao-Lenovo:~/linux_program$ ./test02please input you choice (y,yes,n,no)yesyour choice is yeswuchao@wuchao-Lenovo:~/linux_program$ ./test02please input you choice (y,yes,n,no)dwrong input

 

case语句当匹配到以后,不会再继续匹配后面的模式。使用通配符*可以匹配所有情况。

case示例二:合并匹配模式

wuchao@wuchao-Lenovo:~/linux_program$ cat test02#!/bin/shecho "please input you choice (y,yes,n,no)"read choice;case "$choice" in  y|yes ) echo "your choice is yes";;  n|no ) echo "your choice is no";;  * ) echo "wrong input";;esacexit 0wuchao@wuchao-Lenovo:~/linux_program$ ./test02please input you choice (y,yes,n,no)yyour choice is yes

case示例三:执行多条语句

wuchao@wuchao-Lenovo:~/linux_program$ cat test02#!/bin/shecho "please input you choice a num (0-2)"read choice;case "$choice" in  0 ) echo "num is 0";      echo "num is 0";;  1 ) echo "num is 1";      echo "num is 1";;  2 ) echo "num is 2";      echo "num is 2";;  * ) echo "bad input";      echo "bad input";;esacexit 0wuchao@wuchao-Lenovo:~/linux_program$ ./test02please input you choice a num (0-2)1num is 1num is 1wuchao@wuchao-Lenovo:~/linux_program$ ./test02please input you choice a num (0-2)3bad inputbad input

 

命令列表

AND列表

statement1 && statement2 && statement3 ……

只有前面的命令执行成功后才执行后一条。&&用于测试前一条语句是否成功执行,成功的话执行后一句。

OR列表

statement1 || statement2 || statement3 ……  

直到某一个命令执行成功才结束,即当前面的命令返回false时才执行下一条。||用于测试前一条语句是否成功执行,失败的话执行后一句。

函数

函数必须在调用前定义。

函数被调用时,脚本程序的位置参数($*,$@,$#,S1,$2等)会被替换成函数的参数。执行完毕后在恢复原来的值。

举例:

#!/bin/sh#以下为函数yes_or_no(){  echo "Is your name $* ?"  while true  do    echo -n "Enter yes or no:"    read x    case "$x" in      y | yes ) return 0;;      n | no ) return 1;;      * ) echo "Anser yes or no"    esac  done}#以下为主程序echo "Original params are $*"if yes_or_no "$1"then  echo "Hi $*,nice name"else  echo "Never mind"fiexit 0
yes_or_no "$1"表示执行yes_or_no函数,并传递变量$1给函数

执行结果
wuchao@wuchao-Lenovo:~/linux_program$ ./test02 wu chaoOriginal params are wu chaoIs your name wu ?Enter yes or no:yHi wu chao,nice name

注意:shell中命令执行成功时返回状态码0,失败返回非0,故if遇到0时,为真。比如上面的例子。函数yes_or_no返回0时,主程序的if语句才执行then后面的语句。

shell内置命令

break 命令

跳出一层循环

: 命令

空命令,相当于true的别名。

continue 命令

跳到下一次循环,继续执行。

. 命令

一般情况下,当脚本执行一条外部命令或脚本程序时会创建一个新的环境,命令将在新的环境下执行,结束后退回父shell。但外部的source命令和.命令(两个命令一致)在执行脚本程序中列出的命令时,使用的是调用该脚本程序的同一个shell。因此使用.命令执行程序,可以改变当前shell的环境变量,程序结束后,环境变量仍然有效。

比如以下脚本:

# test.sh
echo
“shell is runing”exit 0

当执行./test.sh时,终端显式“shell is runing”,当执行. ./test.sh时,由于脚本最后一行exit 0是退出shell,结果当前shell被关闭。

echo 命令

echo默认输出带换行符的字符串。可以使用echo -n “string”来输出不换行的字符串。

eval 命令

对参数进行求值。(个人理解为将字符串解析成命令)

举例:

wuchao@wuchao-Lenovo:~/linux_program$ foo=10wuchao@wuchao-Lenovo:~/linux_program$ x=foowuchao@wuchao-Lenovo:~/linux_program$ y='$'$xwuchao@wuchao-Lenovo:~/linux_program$ echo $y$foowuchao@wuchao-Lenovo:~/linux_program$ eval y='$'$xwuchao@wuchao-Lenovo:~/linux_program$ echo $y10

exec命令

将当前shell替换为一个不同的程序。

exit n 命令

交互式shell使用该命令时会使你退出系统。

export 命令

将作为它参数的变量导出到子shell中,并使之生效。默认下,一个shell中被创建的变量在这个shell调用的子shell中是不可用的。export将自己的参数创建为一个环境变量,而这个环境变量是可以被当前程序调用的其他脚本和程序读取的。

(个人理解:父进程的一般变量,子进程不能访问,而环境变量可以)

外部命令和shell脚本执行时,会创建新的shell,内置命令好像不创建新的shell。

expr 命令

将它的参数当作表达式求值。

比如:x=`expr $x + 1` 或 x=$(expr $x + 1)  (注意+左右的空格)

反引号(``)使x的取值为expr $x + 1的执行结果。也可以用$()替换反引号。

expr现在被$((...))替代了。

如:x=$(($x + 1))

printf 命令

类似于c++的printf

格式化字符串然后被用来解释后续参数的含义并输出结果。

 

wuchao@:~$ printf "%s %d\t%s" "Hi There" 15 peopleHi There 15    people

 

 

return 命令

函数返回值

set 命令

为shell设置参数变量

shift 命令

把所有参数变量左移一个位置,使$2变成$1,$3变成$2……,$0保持不变。

 

wuchao@:~/linux_program$ cat test02#!/bin/shwhile [ "$1" != "" ];do  echo "$1"  shiftdoneexit 0wuchao@:~/linux_program$ ./test02 aa bb ccaabbcc

 

 

 

trap 命令

指定在接收到信号时将要采取的行动。

trap command signal

信号说明HUP(1)挂起,通常因终端掉线或用户退出而引发INT(2)中断,通常因Ctrl+C组合键而引发QUIT(3)退出,通常因Ctrl+\组合键而引发ABRT(6)中止,通常因严重的执行错误而引发ALRM(14)报警,通常用来处理超时TERM(15)终止,通常在系统关机时发送

 

unset 命令

从环境中删除变量或函数。

find 命令

格式:

find [path] [options] [tests] [actions]

选项含义-depth在查看目录本身之前先搜索目录的内容-follow跟随符号链接-maxdepths N最多搜索N层目录-mount(或-xdev)不搜索其他文件系统的目录

下面是测试部分,每种测试返回的结果有两种可能:true和false。find命令开始工作时,按照顺序将每种测试应用到它搜索到的每个文件,如果返回false,find停止处理当前找到的文件,并继续搜索。如果返回true,find将继续下一个测试或对当前文件采取行动(actions)。

测试含义-atime N文件在N天前被访问过-mtime N文件在N天前被修改过-name pattern文件名匹配提供的模式pattern,为了确保pattern被传递给find而不是由shell处理,pattern必须被引号括起。-newer otherfile文件比otherfile新-type c文件的类型是c(常见的是d和f)-user username文件的拥有者

还可以使用操作符来组合测试

操作符,短格式操作符,长格式含义-not测试取反-a-and两个测试必须为真-o-or两个测试必须有一个为真

可以使用圆括号来强制优先级。括号需要使用反斜杆。如果文件名处使用的是匹配模式,则此处必须用引号。

如:\(-newer X -o -name "_*"  \)

 

动作含义-exec command执行一条命令,后面跟一个{}用于表示当前的完整路径,然后以 \;结束。-ok command同上,只不过每次询问用户。-print打印文件名-ls对当前文件使用ls -dils

举例:

在当前目录查找比bill.c文件更新的文件,并且使用ls -l命令处理这些找到的文件。

 

wuchao@:~/linux_program$ find . -newer bill.c -type f -exec ls -l {} \;-rw-rw-r-- 1 wuchao wuchao 46 10月 12 19:16 ./test01.sh-rw-rw-r-- 1 wuchao wuchao 1528 10月 10 15:29 ./fred.o-rw-rw-r-- 1 wuchao wuchao 1568 10月 10 15:39 ./program.o-rw-rw-r-- 1 wuchao wuchao 1528 10月 10 15:29 ./bill.o-rwxrwxr-x 1 wuchao wuchao 8656 10月 10 15:59 ./a.out-rwxrwxr-x 1 wuchao wuchao 8720 10月 10 15:56 ./program-rw-rw-r-- 1 wuchao wuchao 86 10月 10 15:37 ./program.c-rw-rw-r-- 1 wuchao wuchao 0 10月 12 20:02 ./foo01.sh-rw-rw-r-- 1 wuchao wuchao 0 10月 12 20:02 ./foo02.sh-rw-rw-r-- 1 wuchao wuchao 3266 10月 10 15:54 ./libfoo.a-rwxrw-r-- 1 wuchao wuchao 59 10月 13 20:21 ./test02-rw-rw-r-- 1 wuchao wuchao 35 10月 10 15:33 ./lib.h-rw-rw-r-- 1 wuchao wuchao 0 10月 12 20:03 ./foo03.sh

 

 

grep 命令

参数:

grep [options] pattern [files]

选项含义-c输出匹配行的数目,而不是匹配行-E启用扩展表达式-h取消每个输出行的普通前缀,即匹配查询模式的文件名-i忽略大小写-l只列出包含匹配行的文件名,而不是匹配行-v对匹配模式取反

 

正则表达式

常用的特殊字符

字符含义^指向一行的开头$指向一行的结尾.任意单个字符[]方括号内的一个字符访问,其中任何一个字符都可以被匹配,例如字符范围a~e,或在字符范围前面加上^符号表示取反向字符范围。

 

特殊匹配模式

 匹配模式含义[:alnum:]大小写字符及数字,0-9,A-Z,a-z[:alpha:]英文大小写字符[:blank:]空格键与tab键[:cntrl:]控制按键,CR,LF,TAB,DEL等[:digit:]代表数字[:graph:]除空格符(空格和Tab)外其他按键[:lower:]小写字符[:print:]可以被打印出来的字符[:punct:]标点字符," ' ? ; : # $[:upper:]大写字符[:space:]任何会产生空白的字符[:xdigit:]十六进制数字

 

基础正则表达式字符

 选项意义^word带查找的字符串在行首word$待查找的字符串在行尾.代表一定有一个任意字符的字符\转义字符*重复零到无穷多个前一个字符[list]从字符集合的RE字符里找到想要选取的字符[n1-n2]从字符集合的RE字符里找到想要选取的字符范围[^list]从字符集合的RE字符里找到不想要选取的字符范围\{n,m\}前一个字符重复n到m次

命令的执行

捕获命令的执行结果: $(command)

算术扩展

$((...))

wuchao@:~/linux_program$ cat test02#!/bin/shx=0while [ "$x" -ne 10 ];do  echo $x  x=$(($x+1))doneexit 0wuchao@:~/linux_program$ ./test020123456789wuchao@:~/linux_program$

参数扩展

参数扩展说明${param:-default}若 param 未定义或为空,则返回 default,否则返回 param 的值${param-string}若 param 未定义,则返回 string,否则返回 param 的值${param:+string}若 param 为非空,则返回 string,否则返回 param 的值${#param}给出param的长度${param%word}从param的尾部开始删除与word匹配的最小部分,返回剩余部分${param%%word}从param的尾部开始删除与word匹配的最长部分,返回剩余部分${param#word}从param的头部开始删除与word匹配的最小部分,返回剩余部分${param##word}从param的头部开始删除与word匹配的最长部分,返回剩余部分

here文档

本章节应用程序设计

查看程序请点击这里。

0 0