回顾: shell 的基础特性、grep
shell:
#!/bin/bash
过程式:以指令为中心
对象式:以数据为中心
grep:文本过滤器,global search regular expression and print out the line
PATTERN
REGEXP:
1. BRE: basic regualr expression
2. ERE: extended regular expression
BRE:
1. 字符匹配:., [], [^]
2. 次数匹配: \?, \+, *, \{m\}, \{m,n\}
3. 位置锚定: ^, $, \<, \b, \>, \b
4. 分组: \(\)
后向引用: \1, \2, ...
vim, sed, awk, nginx 当涉及到文本时,都能使用到正则表达式
egrep 及扩展的正则表达式
egrep = grep -E
egrep [OPTIONS] PATTERN [FILE...]
扩展正则表达式的元字符:
1. 字符匹配:
.
[]
[^]
2. 次数匹配
?
+
*
{m}
{m,n}
3. 位置锚定
^
$
\<, \b
\>, \b
4. 分组
()
后向引用: \1, \2, ...
5. 或者
a|b
C|cat: 表示的意思是,C 或者 cat
(C|c)at: 如果想要对单个字符做【或者】,使用分组括起来
basename: 基名
dirnaem: 目录名
/usr/lib/java 的基名是 java, 目录名是 /usr/lib
练习:
1. 显示当前系统 root、 centos 或 user1 用户的默认 shell 和 UID。
grep -E "^(root|centos|user1)\>" /etc/passwd | cut -d: -f1,3,7
2. 找出 /etc/rc.d/init.d/functions 文件(centos6)中某单词后面跟一个小括号的行。
grep -E -o "^[_[:alnum:]]+\(\)" /etc/rc.d/init.d/functions
注释: 加 -o 与不加 -o 的区别是,
1. 不加,后面会继续匹配出小括号后面的内容,比如 methodName() {
2. 加上,只匹配出了方法名,比如:methodName()
3. 使用 echo 输出一个绝对路径,使用 egrep 取出其基名。
echo "/usr/lib/java" | grep -E -o "[^/]+$"
改进
echo "/usr/lib/java/" | grep -E -o "[^/]+/?$" | cut -d/ -f1
说明:
基名是以除了分隔符 【/】 之外的任意字符结尾的任意字符
-o: 只匹配正则表达式匹配到的内容
基名后面可能会出现 【/】 分隔符,所以使用 /?,表示分隔符 【/】 可能会出现一次或零次
4. 使用 echo 输出一个绝对路径,使用 egrep 取出其目录名,类似于 dirname 命令的结果。
4. 找出 ifconfig 命令结果中 1-255 之间的数值。
5. 找出 ifconfig 命令结果中的 IP 地址。
fgrep: 不支持正则表达式搜索
bash 的基础特性(4)
变量类型:
数据存储格式、存储空间大小、参与运算种类
字符型
数值型:
整型
浮点型
强类型:定义变量时必须指定类型、参与运算必须符合类型要求
弱类型:无需指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无需事先定义可直接调用
bash
bash 中的类型的种类:
根据变量的生效范围等标准:
1. 本地变量:生效范围为当前 shell 进程,对当前 shell 之外的其它 shell 进程,包括当前 shell 的子 shell 进程均无效
2. 环境变量:生效范围为当前 shell 进程及其子进程
3. 局部变量:生效范围为当前 shell 进程中某代码片段(通常指函数)
4. 位置变量:$1, $2, ...来表示,在脚本代码中调用命令行传递进来的参数
5. 特殊变量:$?, $0(指命令本身), $*, $@, $#
1. 本地变量:
变量赋值:name='value'
可以使用引用:
value:
(1) 可以是直接字符串;name="username"
(2) 变量引用: name="$username"
(3) 命令引用: name=`COMMAND`, name=$(COMMAND)
变量引用:${name}, $name
"": 弱引用,其中的变量引用会被替换为变量值
'': 强引用,其中的变量引用不会被替换为变量值
显示已定义的所有变量
set
销毁变量:
unset name
2. 环境变量:
变量声明、赋值:
export name=VALUE
declare -x name=VALUE
变量引用:$name, ${name}
显示所有环境变量:
export
env
printenv
销毁:
unset name
bash 有许多内建的环境变量:
PATH, SHELL, UID, HISTFILE, HISTSIZE, HOME, PWD, OLDPWD, PS1
只读变量:
readonly name
declare -r name
3. 位置变量:
在脚本代码中调用命令行参数
$1, $2, ...: 对应调用第1、第2等参数
$0: 命令本身
$*: 传递给脚本的所有参数
$@: 传递给脚本的所有参数
区别:$*: 把所有参数当做一个字符串
$@: 把每个参数当做一个字符串
$#: 传递给脚本的参数的个数
示例:判断给出的文件的行数
#!/bin/bash
linecount=$(wc -l $1 | cut -d" " -f1)
echo $linecount
bash 的配置文件:
按生效范围划分,存在两类:
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
~/.bashrc
按功能划分,存在两类:
profile类:为交互式登录的 shell 提供配置
全局: /etc/profile, /etc/profile.d/*.sh
个人: ~/.bash_profile
功用:
(1) 用户定义环境变量
(2) 运行命令或脚本
bashrc类:为非交互式登录的 shell 提供配置
全局: /etc/bashrc
个人: /.bashrc
功用:
(1) 用于定义别名
(2) 用于定义本地变量
shell 登录:
交互式登录:
直接通过终端输入账号密码登录
su - Username 或 su -l Username 切换的用户
读取配置文件次序:
1. /etc/profile
2. /etc/profile.d/*.sh
3. ~/.bash_profile
4. ~/.bashrc
5. /etc/bashrc
非交互式登录:
su Username
图形界面下打开的终端
执行脚本
读取配置文件次序:
1. ~/.bashrc
2. /etc/bashrc
3. /etc/profile.d/*.sh
问题:
1. 定义对所有用户都生效的别名
/etc/bashrc
例如: 自定义用户登录提示信息:/etc/profile.d/*.sh
2. 让用户的 PATH 环境变量的值多出一个路径,例如 /usr/local/apache2/bin
export PATH="$PATH:/usr/local/apache2/bin"
管理员? 定义在 ~/.bash_profile 中
所有? 定义在 /etc/profile.d/*.sh 中
bash 中的算数运算,可以查看 help let
+, -, *, /, %, **
实现算术运算:
1. let var=算术表达式
2. var=$[算术表达式]
3. var=$((算术表达式))
4. var=$(expr arg1 arg2 arg3 ...)
乘法符号在 $(expr) 中需要转义
bash 有内建的随机数生成器 $RANDOM
例子:生成 1-60之间的随机数
echo $[$RANDOM % 60 + 1]
增强型赋值:
+=, -=, *=, /=, %=
例如:let count+=1
自增,自减
let var+=1
let var++
let var-=1
let var--
说明:
$( )与``:命令替换
${ }:变量替换
练习:
1. 写一个脚本,计算 /etc/passwd 文件中第10个用户和第20个用户的ID之和
#!/bin/bash
num1=$(head -10 /etc/passwd | cut -d: -f3)
num2=$(head -20 /etc/passwd | cut -d: -f3)
echo $[$num1+$num2]
2. 写一个脚本,传递两个文件路径为参数给脚本,计算这两个文件中所有空白行之和
#!/bin/bash
num1=$(grep "^[[:speace:]]*$" $1 | wc -l)
num2=$(grep "^[[:speace:]]*$" $2 | wc -l)
echo $[$num1+$num2]
3. 统计 /etc/, /var, /usr 目录共有多少个一级子目录和文件
条件测试:
判断某需求是否满足,需要由测试机制来实现:
注意:专用的测试表达式需要由测试命令辅助完成测试过程
测试命令:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
注意: EXPRESSION 前后必须有空白字符
bash的测试类型:
数值测试:
-gt, -ge, -eq, -ne, -lt, -le
例子: test 1 -gt 3;echo $?
字符串测试:
==, >, <, !=
=~: 左侧的字符串是否能被右侧的 PATTERN 所匹配到
注意:此表达式一般用于 [[ ]] 中
-z "String": 测试字符串是否为空
-n "String":测试字符串是否不为空
注意:用于字符串比较时用到的操作数都应该使用引号
例子: name=Obama
[[ "$name" =~ ^O.* ]]
判断 $name 是否以首字母O开头
文件测试:
bash 自定义退出状态码
exit [n]: 自定义退出状态码
注意:脚本中一旦遇到 exit 命令,脚本会立即终止,终止退出状态取决于 exit 命令后面的数字
如果未给脚本指定退出状态码,整个脚本的退出状态取决于脚本中执行的最后一条命令的状态码
练习:
1. 写一个脚本,接受一个文件路径为参数
如果参数的个数小于1,则提示用户“至少应该给一个参数”,并立即退出
如果参数的个数不小于1,则显示第一个参数所指向的文件中的空白行数
#!/bin/bash
test ?# -lt 1 && echo "至少应该给一个参数" && exit 1 || echo $(grep "^[[:space:]]*$" $1 | wc -l)
// 考察点在于怎么判断参数个数是否小于1,注意数值比较用转移符号,千万不要使用 <, > 因为这是字符串比较
egrep 及 bash 中的环境变量
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...