day01 shell 简介
什么是shell
存取权限和安全
shell简单脚本
shell特性
1. /etc/shells 去cat一下
echo $SHELL 看看当前运行的是哪个shell
2. bash的特殊之处:
① 历史记忆功能
② ls+两次Tab键, 就可以查看出以ls开头的所有命令
③ help 回车, 可以查看bash 下面的重要命令
3. b 一般代表块设备文件, 一般放在/dev/ 目录下面
info chmod; 或者 man chmod; 可以查看chmod命令的用法.
4. 文件的存取权限:
setuid (suid/guid) (chmod u+s, g+s file)
chmod 和 chgrp (chown user file / chgrp group file)
umask (umask nnn)
符号链接 (ln [-s] source_path target_path)
chmod [who] operator [permission] filename
who (u, g, o ,a)
operator (+, -, =)
permission (r, w, x, s, t)
chmod u=rwx, g+w, o+r myfile
chmod u+s myfile; //加s位, 会涉及到安全问题.
(这时候 其它用户会以user的身份去做一些事情)
chmod g+s myfile; //其它用户会以组用户的身份去做一些事情
chown root, itlab myfile;
chmod o+t myfile; //t位 表示这个文件在运行时 会放在缓存中去执行.
注: 以上为采用符号模式修改文件权限, 也可以采用绝对模式 如: chmod 740 myfile;
5. ls -l /bin | grep '^...s' 回车; //查找用户具有s位的文件
chmod u+s myfile; 相当于--->chmod 4744 myfle;
chmod 6744 myfile; 给group增加一个S位;
chmod 7744 myfile; 给other增加一个T位;
6. 改变文件的拥有者 和 文件所处的组;
chown 和 chgrp
chown [-R] owner myfile; //当myfile是个目录是会用到-R
chown owner.group myfile;
chown .group myfile;
chgrp [-R] group myfile;
7. umask 命令决定了生成一个文件默认的权限是什么:
/etc/profile ($HOME/.profile $HOME/.bash_profile) //修改umask的地方.
umask
示例: umask 回车; 022 //0代表前三位 即user位, 2代表group位, 2代表other位.
它决定了创建的文件是644; 创建的目录是755;
cat /etc/profile | grep "umask";
8. 符号链接:
硬链接;
软连接;
ln [-s] source_path target_path;
//不加s是建立硬链接, 加s是建立软连接.
1.3 节 Shell脚本
① 使用shell脚本的原因;
功能强大; 节约时间
② shell脚本基本元素;
#!/bin/bash
- 第一行
#
- 除了第一行之外, #表示注释
变量
流程控制语句
③ shell 脚本运行方式.
9. shell编程示例:
#!/bin/bash
#这是一个打印hello world 的shell 脚本
printchar="hello world"
echo ${printchar}; #大括号在这种情况下是可有可无的
echo $HOME
1.4节 Shell的特性
别名;
alias //查看系统中现在都有哪些别名
alias l1='ls -alh'
管道;
命令替换;
重定向;
后台处理;
模式匹配;
变量;
用变量来存储信息
特殊字符.
2. 这些命令一般会放在: cat $HOME/.bashrc
3. 命令替换
myfile的内容:
parm
findfile
ls `cat myfile` -al //反引号, 把执行后的信息 作为参数传递给ls命令
4. 后台处理
一个终端可以同时运行多个程序;
nohup command &
如: nohup tar -czf enerco.tar.gz enerco &
用命令: jobs -l //可以查看到正在后台运行的程序.
5. 管道 (|)
把一个命令的输出连接到另一个命令的输入;
ls | sort
6. 重定向 (< >)
与管道相关, 可以改变程序运行的输入来源和输出地点;
sort < myfile.txt
sort < myfile.txt > myfile_dort.txt
7. 模式匹配
显示以txt为扩展名的文件或显示以a开头的文件, 这种能力就称模式匹配;
正则表达式.
8. 特殊字符
①双引号(""): 用来使shell无法认出空格, 制表符和其它大多数特殊字符.
这样"David Medinets" 表示一个值, 而不是2个值. 同样"David < Medinets"表示一个值.
② 单引号 (' '): 用来使shell无法认出所有特殊字符.
如: touch 'testfile file'
③ 反引号 (` `): 用来替换命令.
④ 反斜杠(\): 用来使shell无法认出其后的特殊字符, 使其后的字符失去了特殊的含义.
如 David\ Medinets
⑤分号(;): 允许在一行上放多个命令;
& : 命令后台执行;
括号 ( ): 创建成组的命令;
大括号{ }: 创建命令快;
竖杠 ( | ): 管道表示符;
< >&: 表示重定向;
*? [ ] ! : 表示模式匹配;
$ : 变量名的开头;
# : 表示注释 (第一行除外);
空格, 制表符, 换行符: 当做空白.
--------------------------------------------------------------
第二章 shell中的变量和运算符
内容:
本地变量; 影响变量的命令; 环境变量; 引号;
变量替换; 运算符; 位置变量; 表达式替换;
标准shell变量; 运算符的优先级; 特殊变量.
2.1 变量
什么是shell变量; 本地变量; 环境变量; 变量替换(显示变量);
位置变量; 标准变量; 特殊变量; 影响变量的命令.
2.1.1 本地变量
① 本地变量在用户现在的shell生命期的脚本中使用.
② variable-name=value
③ set 显示本地所有的变量
④ readonly variable-name
示例: LOCALTEST="test"
echo ${LOCALTEST}
readonly LOCALTEST
LOCALTEST="test4"
readonly
readonly -p
2.1.2 环境变量
① 环境变量用于所有用户进程(经常称为子进程).
登录进程称为父进程. shell中执行的用户进程均称子进程.
不像本地变量(只用于现在的shell), 环境变量可用于所有子进程,
这包括编辑器,脚本和应用程序.
② $HOME/.bash_profile (/etc/profile :对所有用户都有效)
export
env
使用export也可以查看到环境变量有哪些.
2.1.3 变量替换
① 用变量的值替换它的名字
② echo
③ 在变量名前加$, 使用echo命令可以显示单个变量的取值.
④ 示例: testvar="this is a test"
echo ${testvar}
echo ${testvar:+"chinaitlab"}
echo ${testvar1:+"chinaitlab"}
echo ${testvar1:-"chinaitlab"} //未设置的话 返回新的值
echo ${testvar1:-"chinaitlab"} //已设置的话, 则返回原来的值
echo ${testvar:="chinaitlab"} //如果设置了, 则返回原来的值
echo ${testvar2:="chinaitlab"} //如果未设置, 则设置并返回现在的值
2.1.4 变量清除
①unset
unset variable-name
例如: testvar="this is a test"
echo ${testvar}
unset testvar //readonly的变量不能取消它的值
echo ${testvar}
2.1.5 位置变量
① 位置变量表示 $0, $1, ......$9
$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
脚本名字 A B C D E F G
② 向脚本中使用位置参数
③ 向系统命令传递参数
2.
#!/bin/bash
#parm.sh
find /home/chinaitlab/shell -name $1 -print
2.1.6 标准变量 (大部分都是环境变量)
① bash默认建立了一些标准环境变量, 可在 /etc/profile中定义.
EXINIT //定义了初始化vi的一些参数
HOME //指我们的主目录
IFS //设定了 系统中每个域或字段之间的分割是啥
LOGNAME //以哪种用户登录的
MAIL //当前用户存储的邮箱是放在那里
MAILCHECK //每隔多少秒去检查邮箱中是否有邮件过来
2. echo $LOGNAME
set | grep "LOG"
set | grep "MAIL"
③ MAILPATH //当有多个邮箱时 可以用它来指定邮箱的路径
TERM //进入系统之后, 终端的类型是什么
PATH //寻找可执行文件的路径
TZ // 表示时区
PS1 //表示登陆系统之后shell的提示符是什么
PS2 // PS2=`> ` , 当在一行上面运行多个命令时 需要用到.
EDITOR
PWD //表示当前目录
SHELL //当前运行的shell是哪个
MANPATH //系统中帮助文档存放的目录有哪些
TERMINFO //终端类型的一些配置信息
注: set | grep "TERM"
set | grep "PATH"
set | grep "PS"
PS1=`[\u@\h \w]\$ ` //当前用户; 计算机名; 路径
示例: for loop in `cat myfile`
> do
> echo $loop
> done
2.1.7 特殊变量
① $# (传递到脚本的参数列表)
② $* (以一个单字符串显示所有向脚本传递的参数, 与位置比变量不同,
此选项参数可超过9个)
③ $$ (脚本运行的当前进程ID号)
④ $! (后台运行的最后一个进程的进程ID号)
⑤ $@ (与$#相同, 但是使用时加引号, 并在引号中返回每个参数)
⑥ $- (显示shell使用的当前选项, 与set命令功能相同)
(7) $? (显示最后命令的退出状态, 0表示没有错误, 其他任何值表明有错误)
示例:
#!/bin/bash
#parm
echo "这是脚本的名称: #0"
echo "这是脚本的第1个位置参数: $1"
echo "这是脚本的第2个位置参数: $2"
echo "这是脚本的第3个位置参数: $3"
echo "这是脚本的第4个位置参数: $4"
echo "这是脚本的第5个位置参数: $5"
echo "这是脚本的第6个位置参数: $6"
echo "这是脚本的第7个位置参数: $7"
echo "这是脚本的第8个位置参数: $8"
echo "这是脚本的第9个位置参数: $9"
echo "显示参数个数: $#"
echo "显示脚本全部参数: $*"
echo "显示进程ID: $$"
echo "显示前一个命令运行后状态: $?"
2.1.8 影响变量的命令
① declare 设置或显示变量
-f 只显示函数名
-r 创建只读变量(declare和typeset)
-x 创建转出变量 // export
-i 创建整数变量
使用+替代-, 可以颠倒选项的含义
② export 用于创建传给子shell的变量 // 也就是创建环境变量
-- 表明选项结束, 所有后续参数都是实参 //也就是不带参数的
-f 表明在"名-值" 对中的名字是函数名
-n 把全局变量转换成局部变量(即本地变量), 换句话说, 命令的变量不再传给shell
-p 显示全局变量列表
③ 影响变量的命令
readonly 用于显示或设置只读变量
-- 表明选项结束;
-f 创建只读变量;
set 设置或重设各种Shell
④ shift [n]
用于移动位置变量, 调整位置变量, 使$3的值赋予$2, $2的值赋予$1.
typeset
用于显示或设置变量;
是declare的同义词.
unset 用于取消变量的定义.
-- 表明选项结束;
-f 删除只读变量, 但不能从Shell环境中删除指定的变量和函数.
如: PATH, PS1, PS2, PPID, UID, EUID 等的设置.
示例:
#!/bin/bash
#parm
echo "这是脚本的名称: #0"
echo "这是脚本的第1个位置参数: $1"
echo "这是脚本的第2个位置参数: $2"
echo "这是脚本的第3个位置参数: $3"
echo "这是脚本的第4个位置参数: $4"
echo "这是脚本的第5个位置参数: $5"
echo "这是脚本的第6个位置参数: $6"
echo "这是脚本的第7个位置参数: $7"
echo "这是脚本的第8个位置参数: $8"
echo "这是脚本的第9个位置参数: $9"
echo "显示参数个数: $#"
echo "显示脚本全部参数: $*"
echo "显示进程ID: $$"
echo "显示前一个命令运行后状态: $?"
shift
echo "这是脚本的第1个位置参数: $1"
echo "这是脚本的第2个位置参数: $2"
2.2 引号
2.2.1 引用的必要性
变量和替换操作, 在脚本中执行变量替换时最容易犯的一个错误就是引用错误.
如: echo ert *
echo "ert *"
2.2.2 双引号
使用双引号可引用除字符 $, `, \ 外的任意字符或字符串.
如: echo -e "ert, $SHELL '\n* china `echo itlab` ' "
2.2.3 单引号
单引号与双引号类似, 不同的是shell会忽略任何引用值.换句话说, 如果屏蔽了其特殊含义,
会将引号里的所有字符 包括引号都作为一个字符串.
如: echo -e 'ert, $SHELL * china `echo itlab` '
2.2.4 反引号
反引号用于设置系统命令的输出到变量. shell将反引号中的内容作为一个系统命令,
并执行其内容.
如: echo "* china `echo itlab` "
2.2.5 反斜杠
① 如果一个字符有特殊含义, 反斜杠防止shell误解其含义, 即屏蔽其特殊含义.
② 下述字符包含有特殊意义: & * + ^ $ ` " | ?
如: echo * //会列出当前目录下所有的文件名.
echo \*
2.3 运算符
① 运算符是对计算机发的指令.
② 运算对象
--数字, 字符 (字面值);
--变量
--表达式
③ 表达式: 运算符和运算对象的组合体.
2.3.1 运算符类型
① 按位运算符
~, <<, >>, &, |, ^
② $[ ] 表示形式 告诉shell对方括号中的表达式求值.
如: $[ 2+8 ]
#!/bin/bash
# $[ ] 表示形式举例
echo $[ 2+8 ]
赋值运算符:
let $count = $count + $change
let $count + = $change
2.3.2 表达式替换
① $[ ] 和 $( ( ) ) 两者效果一样
-习惯使用$[ ], 所有shell的求值都是用整数完成.
② $[ ]可以接受不同基数的数字
- [ base#n ] n表示基数从2到36的任何基数.
如: echo $[ 10#8 + 1 ] //9 即8进制的10加上1是9
注: $与[] 中间不能有空格
-----------------------------------------------------------
第三章 shell输入与输出
内容:
echo; 文件重定向;
read; 标准输入, 输出和错误;
cat; 管道; 文件重定向;
tee; 合并标准输出和标准错误;
exec; 使用文件描述符.
3.1.1 echo
① echo命令可以显示文本行或变量, 或者把字符串输入到文件.
② echo [option] string
-e 解析转义字符;
-n 回车不换行, linux系统默认回车换行;
--- 转义字符 (\c 回车不换行, \f 表示静止, \t 跳格, \n 回车换行)
3.2.1 read
① read语句可以从键盘或文件的某一行文本中读入信息, 并将其赋给一个变量.
② read varible1 varible2 ...
-- 如果只指定了一个变量, 那么read将会把所有的输入赋给该变量, 直到遇到第一个
文件结束符或回车; 如果给出了多个变量, 他们按顺序分别被赋予不同的变量.
shell将用空格作为变量之间的分隔符.
示例:
#!/bin/bash
#readname
echo -n "First Name:"
read firstname
echo -n "Last Name:"
read lastname
echo -e "Your First Name is :${firstname}\n"
echo -e "Your Last Name is :${lastname}\n"
3.3.1 cat
① cat 是一个简单而通用的命令, 可以用它来显示文件内容, 创建文件, 还可以用它来
显示控制字符.
② cat [option] filename1 ... filename2 ...
-v 显示控制字符;
--- 使用cat命令时要注意, 它不会在文件分页符处停下来; 它会一下显示整个文件.
如果希望每次显示一页, 可以使用more命令或把cat命令的输出通过管道传递到另外
一个具有分页功能的命令(more, less)中。
--- man cat //通过帮助文档查看cat的具体用法
示例: cat file1 file2 file3 //把3个文件的内容一起输出到屏幕上.
cat file1 file2 file3 > myfile123
注: cat -v dos.txt //在C语言编程是, dos下转换过来的文件 要注意把控制字符过滤掉.]
3.4.1 管道 (|)
① 可以通过管道把一个命令的输出传递给另一个命令作为输入. 管道用竖杠 | 表示.
② 格式: 命令1 | 命令2
示例: df -k | awk '{print $1}' | grep -v "Filesystem"
df -k 查看磁盘空间
awk '{print $1}' 查找第一列
grep -v "Filesystem" 过滤掉Filesystem
3.5.1 tee
① tee命令把输出的一个副本输送到标准输出, 另一个副本拷贝到相应的文件中.
② tee -a files //-a 表示将内容追加到文件files内容之后.
- 如果希望在看到输出的同时, 也将其存入一个文件, 那么这个命令再合适不过了.
- 一般用于管道之后
示例: who | tee -a who.out
df -k | awk '{print $1}' | grep -v "Filesystem" | tee partation.txt
> nullfile.txt ; 可以创建一个字节为0的文件
3.7.2文件重定向示例
command << delimiter 举例: (会用到PS2)
cat >>term.txt << CHINAITLAB
>Hello, there I am using a $TERM terminal
>and my username is $LOGNAME
>bye...
>CHINAITLAB (分隔符, 作为输入结束的标志)
② 重定向标准错误
grep "trident" missiles (missiles是一个文件, 在(missiles中查找trident)
grep "trident" missiles 2>/dev/null (会把错误信息重定向到/dev/null 文件中,
但是这里又不会保存任何信息, 是个无底洞)
3.8.1 结合使用标准输出和标准错误
cat account_new.txt \
account_old.txt 1>accounts.out 2>accounts.err //可以把结果和错误信息进行分类
3.9.1 合并标准输出和标准错误
① 合并标准输出和标准错误的时候, 切记shell是从左至右分析相应的命令.
② grep "standard" standard.txt > grep.out 2>&1 //如果遇到错误时输出到屏幕
3.9.2 exec 命令
① exec 命令可以用来替代当前shell; 换句话说, 并没有启动子shell, 使用这一命令时
任何现有环境都将会被清除, 并重新启动一个shell。
② exec command
其中的command通常是一个shell脚本.
③ 对文件描述符进行操作的时候(也只有在这时), 它不会覆盖你当前的shell。
3.10.1 文件描述符
① 3-9 文件描述符
② exec 与文件描述符的结合
示例:
#!/bin/bash
#file_desc
exec 3<&0 0<namke.txt //标准输入变成了3, 该命令打开了3文件描述符
read line1 //从3中读取第一行的信息赋给line1
read line2 //从3中读取第二行的信息赋给line2
exec 0<&3 //把3文件描述符又重定向到了1, 相当于关闭3
echo $line1
echo $line2
-----------------------------------------------------------
第四章 控制流结构
内容:
控制结构; until循环;
if then else语句; while循环;
break控制; case语句;
continue控制; for循环.
4.1.1 控制流结构
① 流控制是什么?
#!/bin/bash
#创建一个目录
make /home/chinaitlab/shell/txt
#复制所有txt文件到 /home/chinaitlab/shell/txt/
cp *.txt /home/chinaitlab/shell/txt
rm -f *.txt
4.1.2 if语句
格式:
if 条件1 //如果条件1为真
then //那么
命令1 //执行命令1
elif 条件2 //如果条件1不成立, 条件2成立
then //那么
命令2 //执行命令2
else //如果条件1, 2均不成立
命令3 //那么执行命令3
fi //完成
示例:
#!/bin/bash
# if test
# this is a comment line, all comment lines start with a #
if[ "10" -lt "12" ]
then
#yes 10 is less than 12
echo "Yes , 10 is less than 12"
fi
注: man test //查看一下帮助文档.
EXPRESSION1 -a EXPRESSION2
-a //and
-o //or
-eq //equal
-ge //greater than or equal to
-gt // greater than
-le //less than or equal to
-lt //less than
= //判断字符串是否相等
-eq //判断两个整数是否相等
-ne //not equal to
FILE1 -ef FILE2 // FILE1 and FILE2 have the same device and inode numbers
FILE1 -nt FILE2 //FILE1 is newer (modification date) than FILE2
FILE1 -ot FILE2 //FILE1 is older than FILE2
-b FILE //FILE exists and is block special
-c FILE //FILE exists and is character special
-d FILE //FILE exists and is a directory
-e FILE //FILE exists
-f FILE //FILE exists and is a regular file
-z STRING //the length of STRING is zero
示例1:
#!/bin/bash
# if test2
echo -n "Enter your name:" //-n 表示回车不换行
read NAME
# did the user just hit return
if [ "$NAME" == "" ]; then
echo "You did not enter any information"
else
echo "Your Name is ${NAME}"
fi
示例2:
#!/bin/bash
# ifcp
if cp myfile.bak myfile ; then
echo "good copy"
else
echo " `basename $0` :error could not copy the files " >&2
fi
4.2.1 case 语句
case 语句为多选择语句. 可以用case语句匹配一个值与一个模式, 如果匹配成功,
执行相匹配的命令.
4.2.2 case语句格式
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
注: case取值后面必须为单词in, 每一模式必须以右括号结束.
取值可以为变量或常数. 匹配发现取值符合某一模式后, 其间
所有命令开始执行直至;; .
模式匹配符* 表示任意字符, ? 表示任意单字符 , [..]表示类或
范围中 任意字符.
示例:
#!/bin/bash
#case select
echo -n "Enter a number from 1 to 3:"
read ANS
case $ANS in
1)
echo "You select 1"
;;
2)
echo "You select 2"
;;
3)
echo "You select 3"
;;
y|Y)
echo "You select $ANS"
;;
*)
echo " `basename $0` : This is not between 1 and 3 " >&2
exit;
;;
esac
4.3.1 for 循环
for 循环 一般格式:
for 变量名 in 列表
do
命令1
命令2
done
注: 当变量值在列表里, for循环即执行一次所有命令, 使用变量名访问列表中取值.
命令可为任何有效的shell命令和语句. 变量名为任何单词. in列表用法是可选的,
如果不用它, for循环使用命令行的位置参数. in 列表可以包含替换, 字符串和文件名.
示例:
#!/bin/bash
#forlist1
for loop in 1 2 3 4 5
do
echo $loop
done
示例2:
#!/bin/bash
#forlist2
for loop in "orange red blue grey" //去掉引号就会分行打印
do
echo $loop
done
注: 有引号时会认为是一个元素, 去掉引号后 会认为是4个元素
4.4.1 until循环 (直到为真时, 就退出循环了. 为假时 一直执行)
until 循环一般格式为:
until 条件
do
命令1
命令2
...
done
注: 条件可为任意测试条件, 测试发生在循环末尾, 因此循环至少执行一次.
示例:
#!/bin/sh
#until_mon
#监控分区
Part="/backup"
# 得到磁盘使用的百分比
LOOK_OUT=` df | grep "$Part" | awk '{print $5}' | sed ' s/%//g ' ` //awk用空格来分割, 打印出第五个域
echo $LOOK_OUT
until [ "$LOOK_OUT" -gt "90" ]
do
echo "Filesystem /backup is nearly full" | mail root
LOOK_OUT=` df | grep "$Part" | awk '{print $5}' | sed ' s/%//g ' `
sleep 3600
done
注: sed ' s/%//g ' s表示替换
nohup ./dfuntil 回车. (让程序放在后台去运行)
4.5.1 while 循环
while 循环一般格式为:
while 命令
do
命令1
命令2
......
done
注: 在while和do之间虽然通常只使用一个命令, 但可以放几个命令,
命令通常用作测试条件.
示例:
#!/bin/sh
#whileread
echo "按住<ctrl>+D 退出输入."
while echo -n "输入你最喜欢的电影: " ; read FILM
do
echo "Yeah , ${FILM} 是一部好电影!"
done
示例2:
#!/bin/sh
#whileread
while read LINE
do
echo $LINE
done < names.txt
4.6.1 break 和 continue 控制
① break [n]
- 退出循环
- 如果是在一个嵌入循环里, 可以指定n 来跳出的循环个数.
② continue
- 跳过循环步
注: continue 命令类似于break命令, 只有一点重要差别, 它不会
跳出循环, 只是跳过这个循环步.
示例:
#!/bin/bash
#breakout
while : //冒号表示永远为真, 这样可以永远循环下去
do
echo -n "Enter any number [1...5] :"
read ANS
case $ANS in
1 | 2 | 3 | 4 | 5 )
echo "You enter a number between 1 and 5."
;;
*)
echo "Wrong number , Bye."
break
;;
esac
done
----------------------------------------------
第五章 文本过滤
内容:
正则表达式; sed 介绍;
find 介绍; (文件)合并与分割 (sort , uniq , join , cut , paste , split);
grep 介绍;
awk 介绍.
5.1 正则表达式
① 一种用来描述文本模式的特殊语法;
② 由普通字符(例如字符 a 到 z) 以及特殊字符 (称为元字符, 如 / , * , ? 等) 组成.
③ 匹配的字符串
④ 文本过滤工具在某种模式下都支持正则表达式.
5.2 基本元字符集及其含义
字符 含义
^ 只匹配行首 (^a 表示只匹配以a开头的文本/文件)
$ 只匹配行尾 (doc$ 表示只匹配以doc结尾的文件)
* 匹配0个或多个此单字符
[ ] 只匹配[]内字符. 可以是一个单字符, 也可以是字符序列.可以使用
-表示[ ]内字符序列范围, 如用[1-5]代替[12345]
\ 只用来屏蔽一个元字符的特殊含义 (如 \*, 还原了*的原本含义)
. 只匹配任意单字符
pattern\{n\} 只用来匹配前面pattern出现的次数. n为次数 (如a\{3\, 匹配a出现3次的情况})
pattern\{n,\} 含义同上, 但次数最少为n
pattern\{n,m\} 含义同上, 但pattern出现次数在n与m之间
示例:
① 句点"." 可以匹配任意单字符
...x..x..x
-rwx-r-xr-x 匹配
....XC....
3452XC763D 匹配
② ^ 只允许在一行的开始匹配字符或字符串
^d
drwxrwxrw- 匹配
^...1
3D11XC9871 匹配
③ $ 在行尾匹配字符串或字符, $放在匹配单词之后
trouble$ -- 匹配以单词trouble结尾的所有字符
^$ -- 匹配空行
^.$ -- 匹配包含一个字符的行
④ * 匹配单字符或 多字符的重复序列
匹配任意字符零次或 多次重复表达
10133*1
101331 匹配
10133921 匹配
10133As1 匹配
⑤ [ ] 匹配一个范围或集合
逗号将括弧内要匹配的不同字符串分开;
用"-"表示一个字符串范围;
[a-z] : 任意一个小写字母
[S,s] : 匹配大, 小写s
⑥ \{\} 匹配模式结果出现的次数
[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\} : 匹配IP地址
(使用到正则表达式的一些命令)
5.10 find 命令
一个查找命令;
查找具有某些特征文件的命令; (如 时间, 大小, 权限)
可遍历当前目录甚至于整个文件系统来查找某些文件或目录;
遍历大的文件系统时, 一般放在后台执行. (把结果重定向到一个文件中去)
5.11 find 命令形式
find 命令的一般形式:
find pathname -options [-print -exec -ok]
pathname find命令所查找的目录路径. 例如 用/ 来表示系统根目录
- print 将匹配的文件输出到标准输出
- exec 对匹配的文件执行该参数所给出的shell命令, 相应命令的形式
为 'command' { } \ ; 注意{}和\之间的空格
-ok 和 -exec 的作用相同, 只不过以一种更为安全的模式来执行该参数
所给出的shell命令, 让用户来确定是否执行.
5.11 find 命令选项
find 命令的一般形式:
-name 按照文件名查找文件;
-perm 按照文件权限来查找文件;
-user 按照文件属主来查找文件;
-group 按照文件所属的组来查找文件;
-mtime -n +n 按照文件的更改时间来查找文件, -n 表示文件更改时间距现在n天以内,
+n 表示文件更改时间距现在n天以前. find命令还有 - atime(访问时间) 和
- ctime (创建时间)选项, 但他们都和 - mtime 选项相似.
- size n[c] 查找文件长度为n块的文件, 带有c时 表示文件长度以字节计.
- nogroup 查找无有效所属组的文件, 即该文件所属的组在 /etc/groups 中不存在
- nouser 查找无有效属主的文件, 即该文件的属主在 /etc/passwd 中不存在
- newer file1 !file2 查找更改时间比文件file1新 但比文件file2旧的文件
- type 查找某一类型的文件, 诸如:
b 块设备文件
d 目录
c 字符设备文件
p 管道文件
l 符号链接文件
f 普通文件
- man find //查看一下帮助文档
5.12 find 命令举例
① 使用name选项
可以使用某种文件名模式来匹配文件, 记住要使用引号将文件名模式引起来
find -name "*.txt" -print (默认就是当前路径)
find ./ -name "*.txt" -print
find ./ -name "[A-Z]*" -print (查看以大写字母开头的所有文件)
find /etc -name "host*" -print
② 使用perm选项
find . -perm 755 -print
③ 使用user和nouser 选项
find `pwd` -user root -print
find `pwd` -nouser -print
注: 放在后台进行查找
nohup find / -nouser -print > nouser.out &
④ 使用group 和 nogroup 选项
find . / -group itlab -print
find / -nogroup -print
⑤ 按照更改时间查找文件
find /var -mtime -5 -print (改变时间在5天之内的打印出来)
find /var/ -mtime +3 -print
⑥ 查找比某个文件新或旧的文件
find `pwd` -newer "myfile" ! -newer "myfile123" -print
(7) 使用type选项
find /etc -type d -print
find /etc -type l -print
注: date 回车 // 查看今天的时间
(8) 使用size选项
find . -size +1000000c -print (c 字符, 表示字节数. +表示大于)
find . -size +10 -print (+ 表示块block)
(9) 使用depth选项
使用find 命令时, 可能希望先匹配所有的文件, 再在子目录中查找
find / -name "CON.FILE" -depth -print
(10) 用exec 或ok 来执行 shell命令
find . -type f -exec ls -l {} \; (先查找普通文件, 再执行后面的命令)
find . -name "*.log" -mtime +5 -ok rm{} \;
注: ls -hl file.txt //会显示文件大小的单位信息
(11) xargs (单一的进程, 可以减少系统资源的消耗)
在使用find 命令的 -exec 选项处理匹配的文件时, find 命令将所有匹配到的文件
一起传递给 exec . 不幸的是, 有些系统对能够传递给 exec 的参数长度有限制,
这样在find命令运行几分钟之后, 就会出现溢出错误. 错误信息通常是"参数列太长"
或"参数列溢出". 这就是xargs命令的用处所在, 特别是与find 命令一起使用.
exec 会发起多个进程, 而xargs不会多个, 只有一个.
find ./ -perm -7 -print | xargs chmod o-w
find ./ -type f -print | xargs file (查看文件类型)
注: xargs 表示把前面命令的结果 作为参数传递给后面的命令来处理
5.13 grep介绍
① grep 是UNIX和LINUX中使用最广泛的命令之一
② 对文本文件进行模式查找
③ grep有三种变形
Grep: 标准grep命令
Egrep: 扩展grep, 支持基本及扩展的正则表达式
Fgrep: 快速grep
④ grep 一般格式:
grep [选项] 基本正则表达式 [文件]
字符串参数最好采用双引号括起来, 一是以防被误解为shell命令, 二是可以
用来查找多个单词组成的字符串.
5.13 grep命令选项
-c 只输出匹配行的计数
-i 不区分大小写 (只适用于单字符)
-h 查询多文件时不显示文件名
-H 显示文件名
-l 查询多文件时只输出包含匹配字符的文件名
-n 显示匹配行及行号
-s 不显示不存在或无匹配文本的错误信息
-v 显示不包含匹配文本的所有行
示例:
grep "jenny" *.txt //从所有的txt文件中查找含有jenny的文件
grep "2004" myfile
grep -v "2004:22" myfile //过滤掉2004:22
grep "^[^210]" myfile // [^210] 表示以 210开头的行有哪些,
^[^210] 即开头既不是2 也不是1 也不是0
grep "H*P" myfile
grep "[5-8][6-9][0-3]" myfile
grep "4\{2\}" myfile
grep "^d" lsout.txt //以d开始的 即目录文件有哪些
grep "^[^d]" lsout.txt //不是以d开始的 即非目录文件有哪些
5.13 grep命令类名 (通过一些类名来表示一些特定的正则表达式)
类 等价的正则表达式
[[:upper:]] [A-Z]
[[:alnum:]] [0-9a-zA-Z]
[[:lower:]] [a-z]
[[:space:]] 空格或tab键
[[:digit:]] [0-9]
[[:alpha:]] [a-zA-Z]
grep "5[[:digit:]][[:digit:]]" myfile //中间不能有空格
[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\} : 匹配IP地址
grep "php" myfile | wc -l //统计有多少行
5.14 awk 介绍 --(一个工具, 一种语言. 它有自己的变量 有自己的语法结构)
① 可从文件或字符串中基于指定规则浏览和抽取信息
② 是一种自解释的编程语言
③ 三种方式调用awk:
- 命令行方式:
awk [-F filed -spearator] 'command' input -files
- awk脚本
所有awk命令插入一个文件, 并使awk程序可执行, 然后用awk命令解释器
作为脚本的首行, 以便通过键入脚本名称来调用它.
- awk 命令插入一个单独文件
awk -f awk -script -file input -files
④ awk脚本由各种操作和模式组成
⑤ 模式和动作
- 模式部分决定动作语句何时触发及触发事件. (BEGIN, END)
- 动作对数据进行处理, 放在大括号{}内指明. (print)
⑥ 分隔符, 域和记录 (awk用来提取各个域的数据)
- awk执行时, 其浏览域标记为 $1, $2...$n . 这种方法称为域标识. $0为所有域
- 注意执行时不要混淆符号$和shell提示符$, 它们是不同的
注: $0就是这条记录;
shell中的$ 意思是在指明一个变量, 而awk中的$ 在指明一个域 (用分割符分割出来的一个个域);
动作通常是对域进行操作;
示例:
awk '{print $0}' score.txt | tee score.out //把 文件中的所有信息打印出来 (默认是以空格来分割)
awk -F : '{print $1"\t" $4}' score.txt | tee score.out
//以冒号来分割. "\t"是字符的话 必须以引号引起来
awk -F +0800 '{print $1"\t" $4}' score.txt | tee score.out
//-F +0800 以+0800来作为分割符
awk 'BEGIN {print "IP Date\n---------"} {print $1"\t"$4} END {print "end-of-report"}' score.txt
注: 所有awk的模式和操作都是放在单引号' '中, 命令都是放在大括号{}中执行;
BEGIN, END 是为了产生一些 报告头和报告尾 的信息;
5.14 awk介绍
awk 中的特殊元字符: + ? // + 表示匹配任意字符; ? 表示匹配单个字符
匹配操作符: ~ !~ // ~ 表示匹配; !~ 表示不匹配
cat score.txt | awk '$0 ~ /218.79.131.96/' //表示从记录中匹配匹配 IP是218.79.131.96的所有行
匹配的内容放在两个双斜杠之间.
cat score.txt | awk '$0 ~/218.79.131.96/' | grep "php" | wc -l //统计 是php页面 的行数
//注: ~/218.79.131.96/ 之间没有空格
awk '$0 !~/218.79.131.96/' score.txt //awk 中的流控制, 所有的操作都是在单引号之间
// 大括号内 . awk 中域的默认分割是空格.
awk '{if($1=="218.79.131.96") print $0}' score.txt
man awk
info awk //得到一些关于awk的帮助信息
5.15 sed 介绍
① sed 不与初始化文件打交道, 它操作的只是一个拷贝, 然后所有的改动如果
没有重定向到一个文件, 将输出到屏幕.
② sed 是一种重要的文本过滤工具, 使用一行命令或者使用管道与grep 与awk相结合.
③ 非交互性文本流编辑.
④ 调用sed有三种方式:
- 使用sed命令行格式为:
sed [选项] sed命令 输入文件
- 使用sed脚本文件, 格式为:
sed [选项] -f sed脚本文件 输入文件.
- 不管是使用shell命令行方式或脚本文件方式,
如果没有指定输入文件, sed从标准输入中接受输入,
一般是键盘或重定向结果.
⑤ sed命令选项如下:
- n 不打印 没有匹配到的信息
- c 下一命令是编辑命令
- f 如果正在调用sed脚本文件
5.15 sed 介绍
① sed 在文件中查询文本的方式
- 使用行号, 可以是一个简单的数字, 或是一个行号范围.
- 使用正则表达式
x x为一行号
x, y 表示行号范围从x到y
/pattern/ 查询包含模式的行
/pattern/pattern/ 查询包含两个模式的行
pattern/, x 在给定行号上查询包含模式的行
x, /pattern/ 通过行号和模式查询匹配行
x, y! 查询不包含指定行号x和y的行
② 基本sed编辑命令
p 打印匹配行
= 显示文件行号
a\ 在定位行号后追加新文本信息
i\ 在定位行号后插入新文本信息
d 删除定位行
c\ 用新文本替换定位文本
s 使用替换模式替换相应模式
r 从另一个文件中读文本
w 写文本到一个文件
q 第一个模式匹配完成后退出或立即退出
l 显示与八进制ASCII代码等价的控制字符
{} 在定位行执行的命令组
n 从另一个文件中读取文本下一行, 并附加在下一行
g 将模式2粘贴到 /pattern n/
y 传送字符
5.15 示例:
sed '2p' score.txt //打印出文件中第二行的信息 (不匹配的也会打印)
sed -n '2p' score.txt //打印出文件中第二行的信息 (-n 表示不匹配的 不打印)
sed -n '1,4p' score.txtb //打印出文件中的1-4行
sed -n '/los/p' myfile.txt //从文件myfile.txt中模式匹配到los 就打印出来
sed -n '4,/los/' myfile.txt //从第4行开始, 匹配到los就结束
sed -n '/^$/=' myfile //打印出文件中 空行的行号
sed -n -e '/^$/p' -e '/^$/=' myfile //即打印出空白行 又打印出行号
sed -n '/chinaitlab/a\shenzhen' myfile.txt //a 表示在文件中chinaitlab后面添加什么样的字符,
//老版本的会出现运行时错误. 应该分成两行来写:
//sed -n '/chinaitlab/a \
shenzhen' myfile.txt
sed -n '/chinaitlab/i\shenzhen' myfile.txt //同上, 但是会插入在chinaitlab的前面
//sed -n '/chinaitlab/i\shenzhen' myfile.txt >myfileout.txt
//这样可以把信息保留下来
sed -n '/chinaitlab/c\chinaitlab shenzhen' myfile.txt
//表示把chinaitlab替换为chinaitlab shenzhen
sed '1,2d' myfile.txt //把第1,2行 全部删除
sed 's/chinaitlab/chinaitlab shenzhen/g' myfile.txt //s 代表替换, g表示如果有多个会全部进行替换
sed -n 's/chinaitlab/& hello /p' myfile.txt //匹配上chinaitlab后 会加上 hello , 并打印出来
sed -n 's/chinaitlab/hello &/p' myfile.txt //在匹配字符chinaitlab之前插入字符hello 并打印
sed 'lr ctrl.txt' myfile.txt
sed '/china/q' myfile.txt //匹配到china 马上退出
sed -n '/china/l' myfile.txt
info sed 和 man sed
5.16 合并与分割
① sort [options] files //按照不同的域来进行排序, 分割
许多不同的域按不同的顺序分类;
-c 测试文件是否已经分类
-m 合并两个分类文件
-u 删除所有复制行
-o 存储sort结果的输出文件名
-t 域分隔符, 用非空格或tab键分割域
+n n为域号, 使用此域号开始分类
n指定分类是域上的数字分类项
-r 比较求逆
man sort
示例:
sort -c myfile //检查这个文件是否排序
sort -u myfile //排序之后再合并. 行与行之间 有重复的话 要进行合并 再打印输出
sort -r myfile //以相反的顺序进行排序
sort -t"/" +2 myfile //-t"/" 表示分隔符. 以第2个域来进行排序
sort -t"/" +2n myfile //以第2个域 的数字大小 来进行排序
注: 域的计数 是从0开始的 0,1,2,3........
5.16 合并与分割
① uniq [option] files
从一个文本文件中去除或禁止重复行;
-u 只显示不重复行;
-d 只显示有重复数据行,每种重复行只显示其中一行;
-c 打印每一重复行出现次数 (不在临近的两行是不会进行统计的)
-f n 为数字, 前n个域被忽略
man uniq
示例:
uniq -c myfile.txt
uniq -d myfile.txt
uniq -f 2 myfile.txt
uniq -d myfile.txt
sort myfile.txt | uniq -c //这样才能统计的到 不相邻的重复行
awk '{print $1}' myfile | sort | uniq -c //统计每个IP访问我页面的次数
grep "php" myfile | awk '{print $1}' | sort | uniq -c //每个IP访问我php页面的次数
5.16 合并与分割
① join [options] file1 file2
用来将来自两个分类文本文件的行连在一起;
-an, n 为一数字, 用于连接时从文件n中显示不匹配行;
-o n.m ,连接域, n为文件号, m为域号;
-j n m, n为文件号, m为域号. 使用其他域做连接域;
t 域分割符. 用来设置非空格或tab键的域分隔符
示例:
join -a1 -a2 address.txt town
join -o 2.2,1.1 address.txt town
join -j1 1 -j2 1 address.txt town
5.16 合并与分割
① split用来将大文件分割成小文件
② split命令一般格式:
split -output_file -size input -filename output -filename
-b n, 每个分割文件的大小n (k,m)
-C n,每个分割文件一行最多n字节数;
-l n, 每个分割文件的行数
-n, 同-l n.
split -10 ls_out.txt split //把文件分割成每个10行 以前缀是split的文件
//ls -l split* | wc -l
man split
5.16 合并与分割
① cut用来从标准输入或文本文件中剪切列或域
man cut
② paste 按行将不同文件行信息放在一起
man paste
cat ls_out.txt | wc -l //统计文件的行数
----------------------------------------------------------------------------
第六章 shell函数
内容:
定义函数; 函数文件;
函数调用; 载入和删除函数;
参数传递; 函数返回状态.
6.1 函数定义
① shell允许将一组命令集或语句形成一个可用块, 这些块称为shell函数.
② 定义函数的格式为:
函数名( )
{
命令1
.........
}
function 函数名( )
{
......
}
③ 函数可以放在同一个文件中作为一段代码, 也可以放在只包含函数
的单独文件中.
#!/bin/bash
#hellofun
function hello( )
{
echo "Hello, today is `date`"
return 1
}
6.1 函数的调用
#!/bin/bash
#func
function hello( )
{
echo "Hello, today is `date`"
}
echo "now going to the function hello"
hello
echo "back from the function"
//注: 写上函数名即可 进行函数调用
6.2 参数传递
① 向函数传递参数就像在脚本中使用位置变量 $1, $2 ...... $9
#!/bin/bash
#func
function hello( )
{
echo "Hello, $1 today is `date`"
}
echo "now going to the function hello"
hello chinaitlab
echo "back from the function"
6.3 函数文件
文件1:
#!/bin/bash
#func
#Source function
. hellofun //表示载入一个文件, 这个文件可以是脚本 也可以是函数
echo "now going to the function hello"
hello
echo "back from the function"
文件2:
#!/bin/bash
#hellofun
function hello( )
{
echo "Hello, today is `date`"
return 1
}
//注: 可以去查看一下 more /etc/rc.d/init.d/network
more /etc/rc.d/init.d/functions
怎样查看一个函数已经载入(调入)到脚本中:
6.4 检查载入函数和删除函数
① 查看载入函数
--- set
② 删除函数
--- unset
示例:
#!/bin/bash
#func
#Source function
. hellofun //表示载入一个文件, 这个文件可以是脚本 也可以是函数
set
echo "now going to the function hello"
hello
echo "back from the function"
6.6 函数返回状态值
文件1:
#!/bin/bash
#hellofunction
function hello( )
{
echo "Hello, today is `date`"
return 0 //它返回的是状态值, 而不是得到一个值
}
文件2:
#!/bin/bash
#func
echo "now going to the function hello"
hello
echo $? //返回的状态值是 用$? 这个特殊变量来表示的
echo "back from the function"
----------------------------------------------------------------------
第七章 脚本中的参数传递
内容:
shift命令; //改变参数的位置变量的值, 传递不同的值给相应的位置变量,
//达到影响位置变量的目的.
//可以让位置变量的个数 多于9个
getopts .
7.1 shift n //n 表示向左移多少位
① 每次将参数位置向左偏移n位.
#!/bin/bash
#opt2
usage( )
{
//basename $0 : 表示打印出这个脚本程序的名称. filenames: 表示文件名
echo "usage:`basename $0` filenames"
}
totalline=0
if[$# -lt 2]; then //$# : 表示参数的个数, 即位置变量的个数
usage
fi
while [$# -ne 0] //当脚本的参数的个数不等于0的时候
do
line=`cat $1 | wc -l`
echo "$1 : ${line}"
totalline=$[$totalline+$line]
shift //位置变量左移一位, 如把$2的值赋给$1
done
echo "------"
echo "total:${totalline}"
7.2 getopts
① 获得多个命令行参数
#!/bin/bash
ALL=false
HELP=false
FILE=false
VERBOSE=false
while getopts ahfvc: OPTION //从字符集ahfvc中 依次读出每个字符 赋给变量OPTION
//ahfvc: 说明冒号前面的那个参数是带有值的参数
do
case $OPTION in
a)
ALL=true
echo "ALL IS $ALL"
;;
h)
HELP=true
echo "HELP is $HELP"
;;
f)
FILE=true
echo "FILE is $FILE"
;;
v)
VERBOSE=true
echo "VERBOSE is $VERBOSE"
;;
c)
c=$OPTARG
echo "c value is $c"
;;
\?) //匹配时 遇到异常情况会到这里
echo "`basename $0` -[a h f v] -[c value] file"
;;
esac
done
//注: ./optgets -a -h -c ff