Linux Shell

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进入和退出子进程: bashexit

shell命令执行顺序查看: type -a shell命令

shell 配置文件读取过程

  1. login shell(需要输入用户的账号和密码取得的bash)

/etc/profile –> ~/.bash_profile(~/.bashrc) –> 开始操作bash

  1. 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: 反向选择,显示出没有查找字符串内容的那一行

  1. 查找test或taste这两个单词时: grep -n 't[ae]st' 文件名
  2. 不想要oo前面有g: grep -n '[^g]oo' 文件名
  3. 查找行首字符为^,查找行首为the的行: grep -n '^the' 文件名
  4. 查找不想要开头是英文字母,[]内代表反向选择,[]外代表定位在首行(等价于没有[]的情况)grep -n ^[^a-zA-Z] 文件名
  5. 查找行尾字符为$,查找行尾结束为小数点(.)的那一行: grep -n '\.$' 文件名
  6. 查找空白行grep -n '^$' 文件名
  7. .(小数点)代表一定有一个任意字符,*(星号)代表重复前一个 0到多次,.*代表零个或多个字符。查找至少两个o以上的字符串。 grep -n 'ooo*' 文件名
  8. 查找g开头和g结尾的字符串。 ``grep -n ‘g.*g’ 文件名
  9. 限定连续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: 代表前导符,即新文件文件名前缀

例如:

  1. 将/etc/termcap分割成300KB的一个文件: split -b 300k /etc/termcap termcap
  2. 将生成的文件合成一个文件: cat termcap* >> termcapback
  3. 将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 -lfind /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' 文件名

扩展正则表达式

  1. + 重复一个或一个以上的前一个RE字符 egrep -n 'go+d' 文件名,输出’god,good,goood’
  2. ? 零个或一个的前RE字符 egrep -n 'go?d' 文件名,输出’gd,god’
  3. | 用或的方式找出数个字符串 egrep -n 'gd|good' 文件名
  4. ()+ 多个重复组的判别 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的内置变量:

  1. NF 每一行($0)拥有的字段总数
  2. NR 目前awk所处理的是”第几行”数据
  3. FS 目前的分隔字符,默认是空格键
  4. $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]按键来隔开每个命令

打补丁

  1. diff -Naur 旧文件 新文件 > 补丁文件.patch
  2. patch -pN < 补丁文件.patch,其中N表示不同目录间的层数,若新旧版数据在同一个目录下,则N=0
Share