第一步:使用文本编辑器来创建文本文件
第一行必须包括shell声明序列:#!
首行shebang机制,添加注释,注释以#开头
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
第二步:加执行权限
给予执行权限,在命令行上指定脚本的绝对或相对路径
第三步:运行脚本
直接运行解释器,将脚本作为解释器程序的参数运行
只检测脚本中的语法错误,但无法检查出命令错误,但不真正执行脚本
bash -n /path/to/some_script
调试并执行
bash -x /path/to/some_script
$1, $?, $PATH, $HOME ,$PS1,$UID,$HOSTNAME,$$,$BASHPID,$PPID,$HISTSIZE
定义方式:
在shell 中定义变量格式如下:
name=vlue
变量的生效范围等标准划分变量类型
普通变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell
进程均无效
环境变量:生效范围为当前shell进程及其子进程
本地变量:生效范围为当前shell进程中某代码片断,通常指函数
变量赋值
name='value'
value 可以是以下多种形式
直接赋值 name= 'value'
引用另一个变量的值 name=”$USER“
一个命令的输出 name=$(command) 或者 name=`command`
注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除
变量引用
$name //name是指变量名
${name}
弱引用和强引用
"$name " 弱引用,其中的变量引用会被替换为变量值
'$name ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
只读变量
只读变量:只能声明定义,但后续不能修改和删除,即常量
声明只读变量:
readonly name
declare -r name
查看只读变量
readonly [-p]
declare -r
位置变量:在bash shell中内置的变量, 在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, ... 对应第1个、第2个等参数,shift [n]换位置
$0 命令本身,包括路径
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数
注意:$@ $* 只在被双引号包起来的时候才会有差异
set 命令:可以用来定制 shell 环境
$- 变量
h:hashall,打开选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭,
i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。所谓的交互式shell,在脚本中,i选项是关闭的
m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等
B:braceexpand,大括号扩展
H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令
set 命令实现脚本安全
-u 在扩展一个没有设置的变量时,显示错误信息, 等同set -o nounset
-e 如果一个命令返回一个非0退出状态值(失败)就退出, 等同set -o errexit
-o option 显示,打开或者关闭选项 显示选项:set -o
打开选项:set -o 选项
关闭选项:set +o 选项
-x 当执行命令时,打印命令及其参数,类似 bash -x 常用于调试
条件测试,判断某个需求是否满足,若满足则为真,不满足则为假
若为真,则状态码$?返回为0
若为假,测状态码$?返回为非零
条件测试命令
test EXPERSSION
[ EXPERSSION ] 于上述test 等价。建议使用 [ ] ,注意符号前后必须有空格
[[ EXPERSSION ]] 相当于增强版[ ] ,支持[ ] 所有用法,并支持正则表达式和通配符
[[ ]]用法
[[ expression ]] 用法
== 左侧字符串是否和右侧的PATTERN相同
注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
注意: 此表达式用于[[ ]]中;扩展的正则表达式
建议:当使用正则表达式或通配符时使用[[ ]],其它情况一般使用 [ ]
条件判断相关选项
选项 | 作用 |
---|---|
文件判断 | – |
-a FILE | 如果文件存在,则为true。 |
-b FILE | 如果文件是块特殊的,则为true。 |
-c FILE | 如果文件是特殊字符,则为true。 |
-d FILE | 如果文件是目录,则为true。 |
-e FILE | 如果文件存在,则为true。 |
-f FILE | 如果文件存在并且是常规文件,则为true。 |
-g FILE | 如果文件是set-group-id,则为true。 |
-h FILE | 如果文件是符号链接,则为true。 |
-L FILE | 如果文件是符号链接,则为true。 |
-k FILE | 如果文件的粘滞位(sticky)设置了,则为true。 |
-p FILE | 如果文件是命名管道,则为true。 |
-r FILE | 如果您可以读取文件,则为true。 |
-s FILE | 如果文件存在且不为空,则为true。 |
-S FILE | 如果文件是套接字,则为true。 |
-t FD | 如果在终端上打开FD,则为True。 |
-u FILE | 如果文件是set-user-id,则为true。 |
-w FILE | 如果文件可写,则为true。 |
-x FILE | 如果您可以执行文件,则为true。 |
-O FILE | 如果文件有效地归您所有,则为true。 |
-G FILE | 如果文件有效地归您的组所有,则为true。 |
-N FILE | 如果文件自上次读取以来已被修改,则为true。 |
FILE1 -nt FILE2 | 根据修改日期,如果 file1 比 file2 新,则为true。 |
FILE1 -ot FILE2 | 根据修改日期,如果 file1 比 file2 旧,则为true。 |
FILE1 -ef FILE2 | 如果 file1 为 file2 的硬链接,则为true。 |
数值判断 | – |
-eq: | 判断两个值是否相等。 |
-ne: | 判断两个值是否不相等。 |
-gt: | 判断第一个值是否大于第二个值。 |
-ge: | 判断第一个值是否大于等于第二个值。 |
-lt: | 判断第一个值是否小于第二个值。 |
-le: | 判断第一个值是否小于等于第二个值。 |
字符判断 | – |
-z STRING | 字符串是否为空,没定义或空为真,不空为假, |
-n STRING | 字符串是否不空,不空为真,空为假 |
STRING1 = STRING2 | 是否等于,注意 = 前后有空格 |
STRING1 != STRING2 | 是否不等于 |
PS:在比较字符串时,建议将变量放到双引号中“变量”
与
第一种写法:
[ EXPRESSION1 -a EXPRESSION2 ] 并且,EXPRESSION1和EXPRESSION2都是真,结果才为真
第二种写法:
COMMAND1 && COMMAND2 #并且,短路与,代表条件性的AND THEN,如果COMMAND1 成功,将执行COMMAND2,否则,将不执行COMMAND2
或
第一种写法:
[ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要有一个真,结果就为真
第二种写法:
COMMAND1 || COMMAND2 #或者,短路或,代表条件性的OR ELSE 如果COMMAND1 成功,将不执行COMMAND2,否则,将执行COMMAND2
非
[ ! EXPRESSION ] 取反
使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变
量,所有剩余单词都被分配给最后一个变量,如果变量名没有指定,默认标准输入的值赋值给系统内置
变量REPLY
常见选项
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d '字符' 输入结束符
-t N TIMEOUT为N秒
if 判断条件;then
条件为真的分支代码
fi
if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
fi
if 判断条件1; then
条件1为真的分支代码
elif 判断条件2; then
条件2为真的分支代码
elif 判断条件3; then
条件3为真的分支代码
...
else
以上条件都为假的分支代码
fi
ps:
多个条件时,逐个条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件
重复运行次数
常见的循环的命令:for, while, until
#方式1
for 变量名 in 列表;do
循环体
done
#方式2
for 变量名 in 列表
do
循环体
done
类似C语言的实现方式
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
do
循环体
done
范例:
for ((i=0;i<100;i++))
do
echo $i
don
写成一行:
for ((i=0;i<100;i++));do echo $i; done;
while COMMANDS; do COMMANDS; done
或
while CONDITION; do
循环体
done
PS:
CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION为 true
退出条件:CONDITION为 false
until COMMANDS; do COMMANDS; done
或
until CONDITION; do
循环体
done
说明:
进入条件: CONDITION 为false
退出条件: CONDITION 为true
函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分
函数定义
#语法一:
func_name (){
...函数体...
}
#语法二:
function func_name {
...函数体...
}
#语法三:
function func_name () {
...函数体...
}