shell的基本概念
shell的功能只是提供用户操作系统的一个接口
设置变量: 变量=变量内容
命令别名设置功能:alias 自定义命令='shell命令',如: alias lm = 'ls -al'
变量设置规则:,如下列出重点记忆的,其他与其他语言的变量设置规则类似
- 等号两边不能直接接空格符,如下是错误的
myname = VBird
- 变量内容若有空格符可使用双引号或单引号将变量内容结合起来
- 双引号内的特殊字符如
$
等,可以保有原本的特性 - 单引号内的特殊字符则仅为一般字符(纯文本)
- 若该变量为了增加原变量内容时,则可用
$变量名称,"$变量名称"或${变量}
,如PATH=$PATH:/home/bin,PATH="$PATH":/home/bin,PATH=${PATH}:/home/bin
- 若该变量还需其他变量可以使用
$(命令),如: version=$(uname -r)
- 使用export使变量变成环境变量
- 取消变量的方法为使用
unset 变量名称
子进程: 在目前这个shell情况下,去打开另一个新的shell,新的那个shell就是子进程。在一般的状态下,父进程的自定义变量是无法在子进程内使用的,但是通过export将变量变成环境变量后,就能够在子进程下使用
在变量的设置中,单引号与双引号的不同用处。双引号可以保有变量的内容,但单引号内仅能是一般字符,而不会有特殊符号。
env查看环境变量
set查看所有变量(含环境变量与自定义变量),环境变量与自定义变量的区别:该变量是否会被子进程所继续引用。子进程仅会继承父进程的环境变量,子进程不会继承父进程的自定义变量
本shell的PID echo $$
shell进入和退出子进程: bash
,exit
shell命令执行顺序查看: type -a shell命令
shell 配置文件读取过程
- login shell(需要输入用户的账号和密码取得的bash)
/etc/profile –> ~/.bash_profile(~/.bashrc) –> 开始操作bash
- non-login shell(进入一个bash,该bash不需要输入账户和密码)
~/.bashrc
直接读取环境配置文件而不注销登录的命令: source 配置文件名
bash 默认的组合键
[Ctrl]+C 终止目前命令 [Ctrl]+D 输入结束(EOF) [Ctrl]+Z 暂停目前的命令
bash 特殊符号
>,>> 数据流重定向,输出导向,分别是”替换”与”累加”
2>> 标准错误输出
<, << 数据流重定向,输入导向
; 连续命令执行分隔符
/dev/null 为黑洞设备,可以吃掉任何导向这个设备的信息
将正确与错误数据通通写入同一个文件,例如:find /home -name .bashrc > list 2>&1
不考虑命令相关性的连续命令执行,使用;
若连续命令之间存在依赖关系(即有顺序),使用&&或者||
管道命令(pipe)
管道命令的重点是它仅会处理standard output,对于standard error output会予以忽略
cut(以行为单位)
cut -d '分隔字符' -f fields
cut -c 字符范围
-d: 后面接分隔字符,与-f一起使用
-f: 依据-d的分隔字符将一段信息切割成为数段,用-f取出第几段的意思,段数从第一段开始
-c: 以字符为单位取出固定字符区间
如: export | cut -c 12-
,截取从第十二的字符开始到结尾。
grep(以行为单位来分析)
grep [acinv] [--color=auto] '查找字符串' [filename]
-a: 将binary文件以text文件的方式查找数据
-c: 计算找到查找字符串的次数
-i: 忽略大小写的不同
-n: 输出行号
-v: 反向选择,显示出没有查找字符串内容的那一行
- 查找test或taste这两个单词时:
grep -n 't[ae]st' 文件名
- 不想要oo前面有g:
grep -n '[^g]oo' 文件名
- 查找行首字符为^,查找行首为the的行:
grep -n '^the' 文件名
- 查找不想要开头是英文字母,[]内代表反向选择,[]外代表定位在首行(等价于没有[]的情况):
grep -n ^[^a-zA-Z]
文件名 - 查找行尾字符为$,查找行尾结束为小数点(.)的那一行:
grep -n '\.$' 文件名
- 查找空白行:
grep -n '^$' 文件名
- .(小数点)代表一定有一个任意字符,*(星号)代表重复前一个 0到多次,.*代表零个或多个字符。查找至少两个o以上的字符串。
grep -n 'ooo*' 文件名
- 查找g开头和g结尾的字符串。 ``grep -n ‘g.*g’ 文件名
- 限定连续RE字符范围{},{}需要使用转义字符。查找出g后面接2到5个o,然后再接一个g的字符串。
grep -n 'go\{2,5\}g' 文件名
通配符与正则表达式的区别
ls不支持正则表达式,对于列出以a为开头的任何文件名的文件:
通配符: ls -l a*
正则表达式: ls | grep '^a.*'
排序命令 sort(默认是字符串升序,即a…z)
sort [-fbMnrtuk] [file or stdin]
-f: 忽略大小写排序
-b: 忽略最前面的空格符部分
-n: 使用”纯数字”进行排序
-f: 反向排序(即字符串降序)
-t: 分隔符,默认是[Tab]
-k: 已那个区间(field)来进行排序
如:cat /etc/passwd | sort -t ':' -k 3
,以:分隔的第三列
排序命令 uniq(相同的数据,仅显示一行)
uniq [-ic]
-i: 忽略大小写字符的不同
-c: 进行计数
如: last | cut -d ' ' -f 1 | sort | uniq -c
排序命令 wc(默认显示信息的行数,字数和字符数)
wc [-lwm]
-l: 仅列出行
-w: 仅列出多少字
-m: 列出多少字符
双向重定向 tee(即输出到文件的同时也输出到屏幕)
tee [-a] file
-a: 以累加的方式将数据加入file当中
如: last | tee last.list | cut -d " " f 1
,输入到文件last.list,屏幕显示cut之后的信息
切割命令 split
split [-bl] file PREFIX
-b: 后面可接欲切割成的文件大小,可加单位,例如b,k,m等
-l: 以行数来进行切割
PREFIX: 代表前导符,即新文件文件名前缀
例如:
- 将/etc/termcap分割成300KB的一个文件:
split -b 300k /etc/termcap termcap
- 将生成的文件合成一个文件:
cat termcap* >> termcapback
- 将ls输出的信息每10行记录成一个文件,其中-表示stdin:
ls -al / | split -l 10 - lsroot
,
参数代换 xargs
xargs [-0epn] command
xargs就是读入stdin的数据,并且以空格符或断行字符进行分辨,将stdin的数据分割成为arguments,这些arguments就是command的参数
-e: EOF(end of file),后面可以接一个字符串,当xargs分析到这个字符串时,就会停止继续工作
-p: 在执行灭个命令的参数时,都会询问用户的意思
-n: 后面接次数,每次command命令执行时,要使用几个参数的意思
例如: cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs finger
为什么要使用xargs ?
由于很多命令并不支持管道命令,使用xargs可以来提供该命令的命令行参数
管道沟通的是 标准输入输出(stdin/stdout),ls命令接受的路径是 命令行参数
对比 find /sbin -perm +7000 | ls -l
和find /sbin -perm +7000 | xargs ls -l
关于减号-的用途
stdin与stdout可以利用减号”-“来替代
sed工具
sed本身是一个管道命令,可以分析standard input,而且sed还可以将数据进行替换,删除,新增和选取特定行等的功能。即一般sed只对文件输出在屏幕上的数据进行操作而本身并不修改文件,若增加-i则是对文件进行修改。
sed [-nefr] [动作]
-n: 使用安静模式,只有经过sed特殊处理的操作才会被列出,否则所有的STDIN的数据都会被列出到屏幕上
-e:默认模式,直接在命令行上模式上进行sed的动作编辑
-i: 直接修改读取文件的内容,而不是由屏幕输出,**尤其对于大文件中修改其中几行很有用**
对动作的说明,动作需要加'':
[n1[,n2]] function
function有下面这些参数:
a:新增,a的后面接字符串,并出现在下一行
c: 替换,c的后面接字符串,这些字符串可以替换n1,n2之间的行
d: 删除,d后面不接任何参数
i: 插入,i的后面接字符串,出现在上一行
p: 打印,通常与sed -n 一起运行
s: 替换,一般为's/要被替换的字符串/新的字符串/g'
删除2-5行: nl /etc/passwd | sed '2,5d'
在第二行后加入加入两行,以’\‘来进行新行的增加: nl /etc/passwd | sed '2a Drink a tea...\ drink beer ?'
仅列出/etc/passed文件内的第5-7行: nl /etc/passwd | sed -n '5,7p'
直接修改文件内容(危险操作),将文件的每一行行尾的.换成!
sed -i 's/\.$/\!/g' 文件名
扩展正则表达式
- + 重复一个或一个以上的前一个RE字符
egrep -n 'go+d' 文件名
,输出’god,good,goood’ - ? 零个或一个的前RE字符
egrep -n 'go?d' 文件名
,输出’gd,god’ - | 用或的方式找出数个字符串
egrep -n 'gd|good' 文件名
- ()+ 多个重复组的判别
egrep -n 'A(xyz)+C' 文件名
格式化打印printf
printf '打印格式' 实际内容
将printf.txt的内容列出(用[tab]分隔)printf '%s\t %s\t %s\t %s\t %s\t \n' $(cat printf.txt)
$( )中放的是命令,如:a=$(ls /home) 可将括号内命令执行结果赋值给a,有先执行命令的意思
${ }中放的是变量,例如echo ${PATH}取PATH变量的值并打印,也可以不加括号比如$PATH。
awk
sed常常作用于一整行的处理,awk则比较倾向于将一行分成数个’字段’来处理
awk '条件类型1{动作1}条件类型2{动作2}...' filename
其中: 条件类型中会用到逻辑运算,如”>,<,==,!=”
awk的内置变量:
- NF 每一行($0)拥有的字段总数
- NR 目前awk所处理的是”第几行”数据
- FS 目前的分隔字符,默认是空格键
- $0表示一整行的数据,$1表示该行的第一列数据(从第一列数据开始),$3表示该行的第三列数据
想取出账号和登陆者IP,且账号与IP之间以[Tab]隔开,则会变成
last -n 5 | awk '{print $1 "\t" $3}'
列出每一行的账号,列出目前处理的行数,并且说明该行有多少字段
last -n 5 | awk '{print $1 "\t lines: " NR "\t columns: " NF}'
/etc/passwd当中以冒号”:“来作为字段分隔,第一个字段为账号,第三个字段为UID,假设第三列小于10以下的数据,并且仅列出账号与第三列。只能从第二行开始显示。
cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1 "\t " $3}'
如上题,能从第一行开始显示
cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'
,即在{}内的动作,如果需要多个命令辅助时,可利用分号”;“分隔,或者直接以[Enter]按键来隔开每个命令
打补丁
diff -Naur 旧文件 新文件 > 补丁文件.patch
patch -pN < 补丁文件.patch
,其中N表示不同目录间的层数,若新旧版数据在同一个目录下,则N=0