“Shell编程”的版本间的差异
(→shell中的特殊字符) |
(→while语句) |
||
(未显示3个用户的6个中间版本) | |||
第2行: | 第2行: | ||
shell是一种高级程序设计语言 | shell是一种高级程序设计语言 | ||
===shell的特点=== | ===shell的特点=== | ||
− | * | + | * 组合命令成为新的命令 |
* 允许灵活使用数据流,提供通配符、输入输出重定向、管道等机制 | * 允许灵活使用数据流,提供通配符、输入输出重定向、管道等机制 | ||
* 结构化程序设计 | * 结构化程序设计 | ||
第81行: | 第81行: | ||
=== 输入输出重定向符 === | === 输入输出重定向符 === | ||
− | + | 执行一个shell命令时,自动打开三个标准设备文件:标准输入stdin、标准输出stdout、标准出错stderr | |
很好的参考资料: http://blog.csdn.net/revilwang/article/details/8374362 | 很好的参考资料: http://blog.csdn.net/revilwang/article/details/8374362 | ||
第169行: | 第169行: | ||
== shell变量 == | == shell变量 == | ||
+ | 和C语言比较一下,shell变量没有类型,不需要预先定义。 | ||
+ | |||
+ | * 环境变量:其值不会随脚本执行结束而消失。 | ||
+ | * 临时变量:作用范围限于脚本内部。 | ||
+ | |||
+ | === 环境变量 === | ||
+ | ==== 常见环境变量 ==== | ||
+ | HOME/MAIL/PATH/PS1/PWD/SHELL/TERM | ||
+ | |||
+ | 删除环境变量:unset | ||
+ | ==== export的作用 ==== | ||
+ | 父进程中定义的变量对其子进程的运行环境没有任何影响,只有通过export输出环境变量,子进程才能够访问。 | ||
+ | |||
+ | 通过两种方式验证: | ||
+ | |||
+ | * 在终端定义变量并输出,然后在shell文件中访问变量(有效) | ||
+ | * 在shell中定义变量并输出,然后在终端访问(无效) | ||
+ | |||
+ | === 用户定义的变量 === | ||
+ | * 变量名 | ||
+ | * 变量赋值 | ||
+ | * 变量的引用:只有这个时候需要$,如果在其他字符串中间,需要{}括起来,比如:${dir}devel | ||
+ | |||
+ | === 数组 === | ||
+ | * 数组定义 | ||
+ | * 数组元素的引用:${数组名[下标]},$数组名:引用第一个元素(下标为0),下标为*或者@表示用用所有元素,unset 数组名表示取消整个数组的定义 | ||
+ | |||
+ | === 变量引用 === | ||
+ | 归纳一下,变量应用的几种形式: | ||
+ | * $name | ||
+ | * ${name} | ||
+ | * ${name[n]} | ||
+ | * ${name[*]} | ||
+ | * ${name[@]} | ||
+ | * ${name:+word}:如果$name为空,则$name,${name:+word}均为空,否则${name:+word}=word | ||
+ | * ${name:-word}:如果$name为空,则${name:-word}=word,否则${name:-word}值为$name | ||
+ | * ${name:=word}:如果$name为空,则$name=word,${name:=word}=word | ||
+ | * ${name:?word}:如果$name为空,则${name}的值为:shell脚本名:name:word,否则${name:?word}的值为$name | ||
+ | * ${name#pattern} | ||
+ | * ${name##pattern} | ||
+ | * ${name%pattern} | ||
+ | * ${name%%pattern} | ||
+ | * ${#@} | ||
+ | * ${$#*} | ||
+ | * ${#name} | ||
+ | * ${#name[*]} | ||
+ | * ${#name[@]} | ||
+ | |||
+ | === 输入输出命令 === | ||
+ | * read输入,简单直观 | ||
+ | * echo输出 | ||
+ | |||
+ | === 位置参数 === | ||
+ | * 0,1,2...是位置变量的名字,因此$0,$1...是对位置变量的引用 | ||
+ | * set命令可以为位置变量赋值,除$0外 | ||
+ | * $#:参数个数,可以认为,#,?,$等都是特殊变量的名字 | ||
+ | * $?:上一条命令的返回值 | ||
+ | * $$:当前进程的进程号,通常用于创建临时文件 | ||
+ | * $!:上一个后台命令的进程号 | ||
+ | * $-:当前shell的执行标志组成的字符串 | ||
+ | * $*:命令行所有参数的字符串 | ||
+ | * $@:几乎等价于$*,区别类似于${name[*]}和${name[@]} | ||
== shell控制结构 == | == shell控制结构 == | ||
第176行: | 第238行: | ||
=== 条件测试 === | === 条件测试 === | ||
− | === | + | [ $a = "b" ] |
+ | |||
+ | 有两点必须注意: | ||
+ | |||
+ | * []内部两端必须有空格 | ||
+ | * =两侧必须有空格 | ||
+ | |||
+ | 这两个规定的原因是,如果没有空格,shell会将关系表达式理解为一个字符串。 | ||
+ | |||
+ | === 循环控制 === | ||
+ | |||
+ | 单行执行shell的一个问题:http://dz.sdut.edu.cn/blog/subaochen/?p=638 | ||
== shell函数 == | == shell函数 == |
2015年12月18日 (五) 13:55的最新版本
shell概述
shell是一种高级程序设计语言
shell的特点
- 组合命令成为新的命令
- 允许灵活使用数据流,提供通配符、输入输出重定向、管道等机制
- 结构化程序设计
- 提供可配置的环境
shell的主要版本
csh/ksh/bash/ash/zsh,主流:bash
基本的bash shell脚本示例
#!/bin/bash # very simple bash script date pwd cd
shell脚本的文件扩展名通常为.sh,并具有可执行权限。
其中#!/bin/bash是必须的,表示调用/bin/bash解释下面的shell命令。
其中#开头的行为注释
shell脚本的执行
- sh ./test.sh
- chmod +x ./test.sh; ./test.sh
shell中的特殊字符
通配符
- *,圆点和路径符号必须显式匹配
- ?
- [字符组],比如f[abcd]匹配fa,fb,fc,fd,f[a-d],f[1-9]
- !,比如f[!1-9]
模式表达式
可以包含多个通配符,并支持扩展模式匹配:
- *(模式表),比如file*(.c|.o)匹配file,file.c,file.c.c,file.c.o,file.o.c,file.o.o等,不匹配file.h
- +(模式表),比如file+(.c|.o)匹配file.c,file.o,file.c.o,file.c.c等,但是不匹配file
- ?(模式表),file?(.c|.o)匹配file,file.c,file.o,不匹配file.c.o
- @(模式表),file@(.c|.o)匹配file.c,file.o,不匹配file,file.c.c等
- !(模式表),file!(.c|.o)匹配file,file.a,不匹配file.c,file.o
引号
双引号
由双引号括起来的字符均作为普通字符对待,$,`,\三个字符除外:
- $表示变量替换
- `表示命令替换
- \表示转义字符,通常用于显示特殊字符$\."'等,比如:echo "filename is \"$HOME\"\$*"的结果是:filename is "/home/subaochen"$*
需要注意的是:双引号中的单引号是普通字符。
例子:
echo "current directory is `pwd`" echo "home directory is $HOME" echo "file*.?" echo "directory '$HOME'"
单引号
单引号括起来的字符都是普通字符,不进行变量替换和命令替换,比如:
echo 'home directory is $HOME'
并不进行变量替换。同理也适应于命令替换。
倒引号
命令替换,比如:
echo `pwd` echo `date`
输入输出重定向符
执行一个shell命令时,自动打开三个标准设备文件:标准输入stdin、标准输出stdout、标准出错stderr
很好的参考资料: http://blog.csdn.net/revilwang/article/details/8374362
输入重定向符<
把标准输入设备重新定向到文件,标准用法:
[n]<file
即,将文件描述字为n的设备重定向到file,如果n省略则默认为标准输入设备(n=0)。
输出重定向符>
把脚本或者程序的执行结果写入指定的文件(重定向到文件):
[n]>file
即,将文件描述字为n的设备重定向到file。如果n省略则为标准输出设备(n=1)
例如:
$ who > who.txt $ cat who.txt
输出附加重定向>>
把命令的输出结果追加到指定文件的末尾
标准输出和标准错误重定向
将标准输出和标准错误都重定向的用法是:
&>file
比如下面的命令序列:
$ ls &> file $ cat file $ mkdir &> file $ cat file
复制文件描述符
用法:
[n]>&文件描述符 [n]<&文件描述符
比如:
$ mkdir > file 2>&1 # mkdir的执行结果(标准输出)重定向到file,并且标准错误也重定向到标准输出
此种用法常见于监控一些定时执行的任务的执行结果和出错信息。
注释、管道、后台命令符
管道的作用:将一个命令的输出作为另外一个命令的输入,比如:
$ ls -l $HOME| wc -l $ ls | grep *.c | wc -l
后台命令符&
命令执行操作符
顺序执行
逗号隔开多个命令即为顺序执行,比如:
pwd;who | wc -l;cd /usr/bin
逻辑与
使用&&连接多个命令,从左向右顺序执行命令,如果遇到一个命令执行不成功,则后面的命令不再执行。比如:
$ cp test1.c test1.c.bak && rm test1.c
逻辑或
使用||连接多个命令,从左向右顺序执行命令,如果前面的命令执行不成功,则执行后面的命令。也就是说,如果前面的命令执行成功,则后面的命令不再执行。比如:
$ cat abc || pwd
shell变量
和C语言比较一下,shell变量没有类型,不需要预先定义。
- 环境变量:其值不会随脚本执行结束而消失。
- 临时变量:作用范围限于脚本内部。
环境变量
常见环境变量
HOME/MAIL/PATH/PS1/PWD/SHELL/TERM
删除环境变量:unset
export的作用
父进程中定义的变量对其子进程的运行环境没有任何影响,只有通过export输出环境变量,子进程才能够访问。
通过两种方式验证:
- 在终端定义变量并输出,然后在shell文件中访问变量(有效)
- 在shell中定义变量并输出,然后在终端访问(无效)
用户定义的变量
- 变量名
- 变量赋值
- 变量的引用:只有这个时候需要$,如果在其他字符串中间,需要{}括起来,比如:${dir}devel
数组
- 数组定义
- 数组元素的引用:${数组名[下标]},$数组名:引用第一个元素(下标为0),下标为*或者@表示用用所有元素,unset 数组名表示取消整个数组的定义
变量引用
归纳一下,变量应用的几种形式:
- $name
- ${name}
- ${name[n]}
- ${name[*]}
- ${name[@]}
- ${name:+word}:如果$name为空,则$name,${name:+word}均为空,否则${name:+word}=word
- ${name:-word}:如果$name为空,则${name:-word}=word,否则${name:-word}值为$name
- ${name:=word}:如果$name为空,则$name=word,${name:=word}=word
- ${name:?word}:如果$name为空,则${name}的值为:shell脚本名:name:word,否则${name:?word}的值为$name
- ${name#pattern}
- ${name##pattern}
- ${name%pattern}
- ${name%%pattern}
- ${#@}
- ${$#*}
- ${#name}
- ${#name[*]}
- ${#name[@]}
输入输出命令
- read输入,简单直观
- echo输出
位置参数
- 0,1,2...是位置变量的名字,因此$0,$1...是对位置变量的引用
- set命令可以为位置变量赋值,除$0外
- $#:参数个数,可以认为,#,?,$等都是特殊变量的名字
- $?:上一条命令的返回值
- $$:当前进程的进程号,通常用于创建临时文件
- $!:上一个后台命令的进程号
- $-:当前shell的执行标志组成的字符串
- $*:命令行所有参数的字符串
- $@:几乎等价于$*,区别类似于${name[*]}和${name[@]}
shell控制结构
if语句
条件测试
[ $a = "b" ]
有两点必须注意:
- []内部两端必须有空格
- =两侧必须有空格
这两个规定的原因是,如果没有空格,shell会将关系表达式理解为一个字符串。
循环控制
单行执行shell的一个问题:http://dz.sdut.edu.cn/blog/subaochen/?p=638