第二章 shell的语法

时间:2021-09-23 01:47:36

变量:字符串、数字、环境和参数

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

wuchao@wuchao-Lenovo:~$ var=hello
wuchao@wuchao-Lenovo:~$ echo $var
hello
wuchao@wuchao-Lenovo:~$ var=+
wuchao@wuchao-Lenovo:~$ echo $var
+

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

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

wuchao@wuchao-Lenovo:~$ read var
hello world
wuchao@wuchao-Lenovo:~$ echo $var
hello world

引号的使用

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

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

环境变量

$HOME :当前home目录

$PATH :搜索命令的目录

$0 :shell脚本的名字

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

$$ :shell脚本的进程号

参数变量

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

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

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

wuchao@wuchao-Lenovo:~/linux_program$ cat test02
#!/bin/sh
var=hello
echo "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 World
value of var is: hello
runing
this shell name is ./test02
the first param is Hell
the second param is World
wuchao@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/sh for var in hello world cc
do
echo $var
done exit wuchao@wuchao-Lenovo:~/linux_program$ ./test02
hello
world
cc

使用通配符的for循环

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

wuchao@wuchao-Lenovo:~/linux_program$ ls foo*.sh
foo01.sh foo02.sh foo03.sh
wuchao@wuchao-Lenovo:~/linux_program$ cat test02
#!/bin/sh for var in $(ls foo*.sh)
do
echo $var
done exit wuchao@wuchao-Lenovo:~/linux_program$ ./test02
foo01.sh
foo02.sh
foo03.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/sh
echo "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";;
esac
exit wuchao@wuchao-Lenovo:~/linux_program$ ./test02
please input you choice (y,yes,n,no)
yes
your choice is yes
wuchao@wuchao-Lenovo:~/linux_program$ ./test02
please input you choice (y,yes,n,no)
d
wrong input

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

case示例二:合并匹配模式

wuchao@wuchao-Lenovo:~/linux_program$ cat test02
#!/bin/sh
echo "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";;
esac
exit wuchao@wuchao-Lenovo:~/linux_program$ ./test02
please input you choice (y,yes,n,no)
y
your choice is yes

case示例三:执行多条语句

wuchao@wuchao-Lenovo:~/linux_program$ cat test02
#!/bin/sh
echo "please input you choice a num (0-2)"
read choice;
case "$choice" in
) echo "num is 0";
echo "num is 0";;
) echo "num is 1";
echo "num is 1";;
) echo "num is 2";
echo "num is 2";;
* ) echo "bad input";
echo "bad input";;
esac
exit wuchao@wuchao-Lenovo:~/linux_program$ ./test02
please input you choice a num (-) num is
num is
wuchao@wuchao-Lenovo:~/linux_program$ ./test02
please input you choice a num (-) bad input
bad 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 ;;
n | no ) return ;;
* ) 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"
fi exit
yes_or_no "$1"表示执行yes_or_no函数,并传递变量$1给函数

执行结果
wuchao@wuchao-Lenovo:~/linux_program$ ./test02 wu chao
Original params are wu chao
Is your name wu ?
Enter yes or no:y
Hi 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

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

echo 命令

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

eval 命令

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

举例:

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

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 people
Hi There 15 people

return 命令

函数返回值

set 命令

为shell设置参数变量

shift 命令

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

wuchao@:~/linux_program$ cat test02
#!/bin/sh
while [ "$1" != "" ];
do
echo "$1"
shift
done
exit wuchao@:~/linux_program$ ./test02 aa bb cc
aa
bb
cc

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-- wuchao wuchao 10月 : ./test01.sh
-rw-rw-r-- wuchao wuchao 10月 : ./fred.o
-rw-rw-r-- wuchao wuchao 10月 : ./program.o
-rw-rw-r-- wuchao wuchao 10月 : ./bill.o
-rwxrwxr-x wuchao wuchao 10月 : ./a.out
-rwxrwxr-x wuchao wuchao 10月 : ./program
-rw-rw-r-- wuchao wuchao 10月 : ./program.c
-rw-rw-r-- wuchao wuchao 10月 : ./foo01.sh
-rw-rw-r-- wuchao wuchao 10月 : ./foo02.sh
-rw-rw-r-- wuchao wuchao 10月 : ./libfoo.a
-rwxrw-r-- wuchao wuchao 10月 : ./test02
-rw-rw-r-- wuchao wuchao 10月 : ./lib.h
-rw-rw-r-- wuchao wuchao 10月 : ./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/sh
x=
while [ "$x" -ne ];do
echo $x
x=$(($x+))
done
exit wuchao@:~/linux_program$ ./test02 wuchao@:~/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文档

本章节应用程序设计

查看程序请点击这里

第二章 shell的语法的更多相关文章

  1. java面向对象编程——第二章 java基础语法

    第二章 java基础语法 1. java关键字 abstract boolean break byte case catch char class const continue default do ...

  2. 第二章	JavaScript核心语法

    第二章   avaScript核心语法 一.变量的声明和赋值 JavaScript是一种弱类型语言,没有明确的数据类型,也就是在声明变量时不需要指定数据类型,变量的类型由赋给变量的值决定. 在Java ...

  3. 第二章 Java 基本语法1

    2.1关键字 1.定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词). 2.特点:关键字中所有字母都是小写字母. 3.分类: 用于定义数据类型的关键字:byte.short.int.lo ...

  4. PHP-----PHP程序设计基础教程----第二章PHP基本语法

    博文结构: 2.1 PHP语法风格 2.1.1 PHP标记 PHP有四种风格的标记,具体如表2-1所示: 表2-1 PHP开始和结束标记 标记类型 开始标记 结束标记 示例 说明 标准标记 <? ...

  5. 第二章 Python基础语法

    2.1 环境的安装 解释器:py2 / py3 (环境变量) 开发工具:pycharm 2.2 编码 编码基础 ascii ,英文.符号,8位为一个东西,2**8 unicode ,万国码,可以表示所 ...

  6. 第二章 python基本语法元素

    python有两种编程方式,交互式和文件式. 交互式:对每个输入语句即时运行结果------适合语法练习 文件式:批量执行一组语句并运行结果------编程的主要方式 实例1:圆面积的计算(根据半径r ...

  7. &lbrack;转&rsqb;Windows Shell 编程 第二章 【来源:http&colon;&sol;&sol;blog&period;csdn&period;net&sol;wangqiulin123456&sol;article&sol;details&sol;7987893】

    第二章Shell的结构  “Shell 编程”的大伞之下有大量的API函数和COM接口.这个种类繁多的‘命令’集允许你用不同的方法对Windows Shell进行编程.函数和接口并不是两种提供相同功能 ...

  8. &lpar;linux shell&rpar;第二章--命令之乐&lpar;一&rpar;

    文章来自于我的个人博客:(linux shell)第二章--命令之乐(一)    上一章我们描写叙述了一些linux shell中须要注意的一些语法.接下来我们開始了解linux shell的经常使用 ...

  9. Java基础知识二次学习-- 第二章 基础语法与递归补充

    第二章 基础语法与递归补充   时间:2017年4月24日10:39:18 章节:02章_01节,02章_02节 视频长度:49:21 + 15:45 内容:标识符,关键字与数据类型 心得:由字母,下 ...

随机推荐

  1. 【转】Checkpoint--与lazy writer区别

      checkpoint目的是减少数据库的恢复时间(服务奔溃或重启服务后的恢复),而lazy writer的目的是保证SQL OS 有空闲缓存块和系统有一定可用内存. Checkpoint和lazyW ...

  2. System V 信号量

    1 概述 计数信号量集semid_ds: struct semid_ds { struct ipc_perm sem_perm; struct sem *sem_base; //指向信号量结构数组 u ...

  3. 初次踏上GUI编程之路(有点意思,详细介绍了菜鸟的学习之路)

    初次踏上GUI编程之路 —— 我的Qt学习方法及对Qt认识的不断转变 -> 开始接触GUI与开始接触Qt: 话说,我第一次看见“Qt”这一个名词,好像是在CSDN网站的主页上吧,因为CSDN好像 ...

  4. Hash表的使用

    Hash表能够实现在O(1)时间内对数据访问,虽然空间复杂度很高,但是时间复杂度很好.所以下面说一些使用Hash的算法. 第一个只出现一次的字符 利用Hash可以实现统计字符的个数,然后在遍历一次得到 ...

  5. RAS 加密 解密

    蚂蚁金服电话面试时,问到了RAS加密解密,感觉回答的有点模糊,遂写个例子加深一下印象 package cheng.test.cipher;import java.io.FileInputStream; ...

  6. String类为什么是final的

    首先我们使用new创建一个String对象的时候比如: String str=new String("123"); 这句话里面创建了两个对象,第一个在系统中创建了一个"a ...

  7. 一名Java架构师分享自己的从业心得,从码农到架构师我用了八年

    工作了挺久,发现有个挺有意思的现象,从程序员.高级程序员,到现在挂着架构师.专家之类的头衔,伴随着技术和能力的提高,想不明白的事情反而越来越多了. 这些疑问有些来自于跟小伙伴的交流,有些是我的自问自答 ...

  8. 学习java一个月的进展

    作为一个阶段性总结,有很多的东西需要说明,有细节的,有架构的,且听我细细说来. java和php最大的区别不止是类型的强制定义,而是在设计思路上有着非常重大的偏差(虽然SY3框架已经开始借鉴JAVA的 ...

  9. javascript关于onclick&lpar;&rpar;

    1 <html> <head> <title>js1 </title> <style> #content{ margin:0 auto; t ...

  10. Windows下安装和配置Apache2&period;2&period;22服务器&plus;PHP5&plus;Mysql5

    接下来,笔者将WindowsXP(Sp3)下,搭建和配置php运行环境做一个简单的介绍: 1.安装准备 1.1Apache下载,官方地址(http://httpd.apache.org/),此处笔者下 ...

相关文章