一、编写Shell 脚本
一般步骤:1.编写一个脚本 2.使脚本文件可执行 3.把脚本放置到 shell 能够找到的地方例如:
1.编写hello_world脚本
2.赋予可执行权限
3.执行脚本
例如:
- 使用"here document"方式(可以随意的嵌入引号)
格式如下:
command << tokentexttoken
这里的 command 是一个可以接受标准输入的命令名,token 是一个用来指示嵌入文本结束的字符串
把操作符"<<"改为 "<<-",shell 会忽略开头的 tab 字符,可使用缩进提高可读性
例如:
或
- 例子:使用 一个 here document 将一系列的命令传递到 ftp 程序中以从一个远端 FTP 服务器中得到一个文件
三、Shell脚本中的变量
- 创建变量或给变量赋值
variable=value(注:等号左右不能有空格)
可以在同一行中对多个变量赋值
a=5 b="a string"
使用变量
$variable 或 ${variable}
例如
四、Shell中的函数
- 函数语法形式(其中name为函数名,commands为一系列包含在函数中的命令,函数中须至少包含一条命令,return为可选)
function name {
commands
return
}
或
name () {
commands
return
}
*例如
- 局部变量
*例如
五、流程控制:if 分支结构
- if 语句语法如下
if commands; thencommands[elif commands; thencommands...][elsecommands]fi
*例如:
- 退出状态
当命令执行完毕后会给系统发送一个值,叫做退出状态。Shell 提供了一个参数$?可用来检查退出状态
例如:(状态0为命令执行成功)
$ ls -d /usr/bin/usr/bin$ echo $?0
- 测试
*经常与 if 一块使用的命令是 test。test 命令执行各种各样的检查与比较,它有两种等价模式:
test expression或[ expression ]
*其中expression 为一个表达式,其执行结果是 true 或者是 false。当表达式为真时,这个 test 命令返回一个0退出状态,当表达式为假时,test 命令退出状态为1
- 测试表达式
*文件表达式
file1 -ef file2:file1 和 file2 拥有相同的索引号(通过硬链接两个文件名指向相同的文件)file1 -nt file2:file1新于 file2file1 -ot file2:file1早于 file2-b file:file 存在并且是一个块(设备)文件-c file:file 存在并且是一个字符(设备)文件-d file:file 存在并且是一个目录-e file:file 存在-f file:file 存在并且是一个普通文件-g file:file 存在并且设置了组 ID-G file:file 存在并且由有效组 ID 拥有-k file:file 存在并且设置了它的“sticky bit”-L file:file 存在并且是一个符号链接-O file:file 存在并且由有效用户 ID 拥有-p file:file 存在并且是一个命名管道-r file:file 存在并且可读(有效用户有可读权限)-s file:file 存在且其长度大于零-S file:file 存在且是一个网络 socket-t fd:fd 是一个定向到终端/从终端定向的文件描述符 。 这可以被用来决定是否重定向了标准输入/输出错误-u file:file 存在并且设置了 setuid 位-w file:file 存在并且可写(有效用户拥有可写权限)-x file:file 存在并且可执行(有效用户有执行/搜索权限)
*文件表达式例子(其中在表达式中参数$FILE两边的引号并不是必需的,但这可防范空参数)
*字符串表达式
string:string 不为 null-n string:字符串 string 的长度大于零-z string:字符串 string 的长度为零string1 = string2或string1 == string2:string1 和 string2 相同. 单或双等号都可以,不过双等号更受欢迎string1 != string2:string1 和 string2 不相同string1 > string2:sting1 排列在 string2 之后string1 < string2:string1 排列在 string2 之前
注:> 和 <表达式操作符必须用引号引起来或者是用反斜杠转义,否则会被 shell 解释为重定向操作符,造成潜在地破坏结果
*字符串表达式例子:
*整型表达式
integer1 -eq integer2:integer1 等于 integer2integer1 -ne integer2:integer1 不等于 integer2integer1 -le integer2:integer1 小于或等于 integer2integer1 -lt integer2:integer1 小于 integer2integer1 -ge integer2:integer1 大于或等于 integer2integer1 -gt integer2:integer1 大于 integer2
*整型表达式例子:
- 更现代的测试版本
*目前的 bash 版本包含一个复合命令:[[ expression ]],与test相比增加了一个重要的新的字符串表达式:string1 =~ regex,若string1匹配扩展的正则表达式 regex则返回真
例子:
*为整数设计的复合命令:(( ))
例子:
- 通过使用逻辑操作符来结合表达式
操作符 测 试 [[ ]] 和 (( )) AND -a && OR -o || NOT ! !
- 控制操作符:分支的另一种方法
*bash 支持两种可以执行分支任务的控制操作符。这个 &&(AND)和||(OR)操作符作用如同复合命令[[ ]]中的逻辑操作符
*语法:command1 && command2 和 command1 || command2
*对于 && 操作符,只有当command1 执行成功后,才会执行 command2。对于 || 操作符,只有当command1 执行失败后, 才会执行command2
*例如:
$ mkdir temp && cd temp :在成功创建目录temp后跳转到temp$ [ -d temp ] || mkdir temp :若目录 temp 不存在则创建这个目录[ -d temp ] || exit 1 : 若目录temp不存在则返回退出状态1
六、读取键盘输入(交互)
- read - 从标准输入读取单行数据
*语法形式:read [-options] [variable...]
*读取一个整数:
*给多个变量赋值:
*若没有提供变量名,shell 变量 REPLY 会包含数据行
*read选项
-a array:把输入赋值到数组 array 中,从索引号零开始-d delimiter:用字符串 delimiter 中的第一个字符指示输入结束,而不是一个换行符-e:使用 Readline 来处理输入。这使得与命令行相同的方式编辑输入-n num:读取 num 个输入字符,而不是整行-p prompt :为输入显示提示信息,使用字符串 prompt
-r:Raw mode. 不把反斜杠字符解释为转义字符-s:Silent mode. 不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这会很有帮助-t seconds:超时. 几秒钟后终止输入。read 会返回一个非零退出状态,若输入超时-u fd:使用文件描述符 fd 中的输入,而不是标准输入
*read选项例子:
*此脚本提示用户输入一个密码,若在10秒内没有完成输入,则脚本会退出并返回一个错误。因包含了一个 -s 选项,所以输入的密码不会出现在屏幕上