《鸟哥的Linux私房菜》自学笔记
1.Bash shell 的功能
BASH的优点:
• 命令编辑 对应设置文件~/.bash_history
• 命令与文件自动补全:
• [Tab] 接在一串指令的第一个字的后面,则为命令补全
• [Tab] 接在一串指令的第二个字以后时,则为文件补全
• 命令别名(alias)设定:alias lm='ls -al'
• 工作控制(jobs)、前后台控制
• Shell scripts
• 万用字符
2.Bash shell 的内建命令:type
用于识别指令是来自于外部指令(指其它非 bash 套件所提供的指令) 或是内建在 bash 中的指令。
[root@linux ~]# type [-tpa] name
:不加任何参数时, type 会显示出name 是外部指令还是 bash 内建指令
-t :当加入 -t 参数时,type 会将 name 以底下这些字眼显示出他的意义:
file :表示外部指令
alias :表示指令是命令别名
builtin :表示指令是 bash 内建指令
-p :如果name 为指令时,会显示该指令的完整路径(外部指令)或显示为内建指令
-a :PATH 变量定义的路径中,将所有含有 name 的指令都列出来,包含别名
[root@linux ~]# type ls
ls is aliased to `ls --color=tty'
[root@linux ~]# type -t ls
alias
3.执行指令的方法
[root@linux ~]# command [-options] parameter1 parameter2 ...
1.加入参数时,通常为 - 号,例如 –h ,完整参数名称会输入 -- 符号,例如 --help
2.按下 [Enter] 按键,该指令立即执行。[Enter] 按键为 <CR> 字符,代表一行指令开始执行
3.当指令太长时,可以使用 / 符号转义[Enter],使指令延续到下一行
4.在 Linux 系统中,大小写字母敏感, cd 与 CD 不相同
4.Shell 变量的定义
变量是指用一组文字或符号,来取代一些设定或者一串保留的数据
5.变量的设定:echo, 变量设定规则, unset
[root@linux ~]# echo $PATH #显示已设定变量
/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin
[root@linux ~]# echo ${PATH} #另一种调用方式
[root@linux ~]# echo $myname #定义一个新变量
[root@linux ~]# myname=Vygn #为新变量赋值
[root@linux ~]# echo $myname #显示新变量内容
1. 变量与变量内容用等号 = 连结
2. 等号两边不能直接接空格
3. 变量名称只能是英文字母和数字,但是数字不能是开头字符
4. 若需要空格符可以使用双引号 " 或单引号 ‘ 与变量内容结合,但是双引号内的特殊字符保持变量特性,单引号内的特殊字符仅为一般字符
5. 必要时需要以跳脱字符 / 来将特殊符号 ( 如 Enter, $, /, 空格符, ' 等 ) 变成一般符号
6. 在指令中,如果需要藉由其它指令的输出提供信息,可以使用 quote `command` (注意, ` 是键盘上方数字键 1 左边那个按键)
7. 若该变量为累加变量内容时,必须用双引号及 $变量名称 如: "$PATH":/home继续累加内容
8. 若该变量需要在其它子程序中执行,需要用 export 使该变量成为环境变量,如export PATH
9. 通常大写字符为系统默认变量,自定义变量可以使用小写字符,方便判断
10. 取消变量:unset 变量名称
[root@linux ~]# name=Vygn
[root@linux ~]# name="Vygn's name" #借助双引号设置变量
[root@linux ~]# name=Vygn/'s/ name #转义特殊字符
[root@linux ~]# PATH="$PATH":/home/ygn/bin #在 PATH 变量中追加目录:/home/ygn/bin
[root@linux ~]# PATH=${PATH}:/home/ygn/bin #追加内容的另一种方式
[root@linux ~]# cd /lib/modules/`uname -r`/kernel #进入核心的模块目录
[root@linux ~]# unset name #取消变量
6.环境变量的功能
• 显示当前环境变量:env
[root@linux ~]# env #显示当前 shell 环境下的所有环境变量
HOSTNAME=CentOS.YangGN #主机名称
SHELL=/bin/bash #当前环境使用的shell
TERM=linux #终端机使用的环境
HISTSIZE=1000 #历史命令默认记录笔数
USER=root #当前用户
ENV=/root/.bashrc #个人环境设定文件
MAIL=/var/spool/mail/root #当前用户的 mailbox 位置
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin: /root/bin #执行文件指令搜索路径
INPUTRC=/etc/inputrc #设定键盘特殊功能
PWD=/root #当前用户的工作目录
LANG=en_US.UTF-8 #语系设定
HOME=/root #当前用户的家目录
_=/bin/env #上一次使用的指令的最后一个参数或指令本身
*RANDOM :随机数变量,可以通过/dev/random这个随机数文件及相关变量 ($RANDOM) 来随机取得随机值。在 BASH 的环境下, RANDOM 变量的范围,介于 0~32767 之间,如果需要使用 0~9 之间的数值,可以利用 declare 宣告数值类型:
[root@linux ~]# declare -i number=$RANDOM*10/32767 ; echo $number
• 显示当前所有变量:set
[root@linux ~]# set
BASH=/bin/bash #bash 主程序路径
BASH_VERSINFO=([0]="3" [1]="2" [2]="25" [3]="1" [4]="release" [5]="i686-redhat-linux-gnu"
#bash 版本
BASH_VERSION='3.2.25(1)-release' #bash 版本
COLORS=/etc/DIR_COLORS.xterm #使用的颜色纪录文件
COLUMNS=115 #当前终端机环境下,使用的字段长度
HISTFILE=/root/.bash_history #历史命令记录的放置文件,隐藏文件
HISTFILESIZE=1000 #历史命令默认记录笔数
HISTSIZE=1000 #可记录的历史命令最大笔数
HOSTTYPE=i686 #主机安装软件主要类
IFS=$' /t/n' #默认分隔符
LINES=35 #当前终端机下的最大行数
MACHTYPE=i686-redhat-linux-gnu #安装的机器类型
MAILCHECK=60 #每 60 秒扫瞄一次信箱有无新邮件
OLDPWD=/home #上一个工作目录,也可以用 cd - 取用这个变量
OSTYPE=linux-gnu #操作系统类型
PPID=20046 #父程序的 PID
PS1='[/u@/h /W]/$ ' #命令提示字符,例如 [root@linux ~]#
LANG=en_US.UTF-8 #语系设定
name=Vygn #用户自定义变量
$ #当前shell 的 PID ,可以执行echo $$查看
? #上个执行指令的回传值
等等
• PS1:
o /d :代表日期,格式为 Weekday Month Date,例如 "Mon Aug 1"
o /H :完整的主机名称
o /h :仅取主机名称的第一个名字,例如CentOS.YangGN 仅取CentOS
o /t :显示时间,为 24 小时格式,如: HH:MM:SS
o /T :显示时间,12 小时的时间格式
o /A :显示时间,24 小时格式, HH:MM
o /u :当前用户的账号名称
o /v :BASH 的版本信息
o /w :完整工作目录名称,家目录以 ~ 取代
o /W :利用 basename 取得工作目录名称,仅列出最后一个目录名
o /# :下达的第几个指令
o /$ :提示字符,如果是 root 时,提示字符为 # ,一般用户为 $
• ?:当执行某些指令时,指令会回传一个执行后的代码。一般,如果成功的执行,返回 0 值,如果执行过程中发生错误,会返回错误代码,一般以非为 0 的数值代替
·私有变量转成环境变量: export
将私有变量转化威环境变量,子程序就可以引用父程序的私有变量
[root@linux ~]# export #列出所有的环境变量
declare -x ENV="/root/.bashrc"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="linux.ygn.tw"
declare -x INPUTRC="/etc/inputrc"
declare -x LANG="en_US.UTF-8"
declare -x MAIL="/var/spool/mail/root"
declare -x SHELL="/bin/bash"
等等
·语系文件变量:locale
[root@linux ~]# locale –a #列出当前主机所有的语系文件,放置在:/usr/lib/locale/
[root@linux ~]# LANG #设定语系环境
[root@linux ~]# LC_CTYPE #字符辨识的编码
[root@linux ~]# LC_NUMERIC #数字显示讯息
[root@linux ~]# LC_TIME #时间显示数据
[root@linux ~]# LC_COLLATE #字符串的比较和排序
[root@linux ~]# LC_MONETARY #币值格式的显示
[root@linux ~]# LC_MESSAGES #讯息显示的内容,如菜单、错误讯息等
[root@linux ~]# LC_ALL #语言环境的整体设定
[root@linux ~]# vim /etc/sysconfig/i18n #修改系统语系支持
LANG="zh_CN.UTF-8:en_US.UTF-8"
7.变量的有效范围
执行 export 后的变量,可以称为环境变量,环境变量可以被子程序引用的原因是:
• 当启动一个 shell时 ,操作系统会分配一块区域给 shell 使用,此区域的变量可以让子程序使用
• 利用 export 功能,可以让变量的内容写到上述的区域块中(环境变量)
• 当加载另一个 shell 时,子 shell 可以将父 shell 的环境变量所在的区域块导入自己的环境变量中
8.变量键盘读取、数组与宣告: read, array, declare
• read (读取来自键盘输入的变量)
[root@linux ~]# read [-pt] variable
-p :接提示字符
-t :接等待的秒数
[root@linux ~]# read test #由键盘输入内容,将该内容变成 atest 变量
This is a test
[root@linux ~]# echo $test
This is a test
[root@linux ~]# read -p "Please input your name: " -t 30 named
Please input your name: Vygn Test
[root@linux ~]# echo $named
Vygn Test
• declare / typeset (宣告变量的属性)
[root@linux ~]# declare [-aixr] variable
参数:
-a :将variable 定义为数组 (array)
-i :将variable 定义为整数 (integer)
-x :用法与 export 一样,将variable 变成环境变量
-r :将一个 variable 的变量设定成为 readonly ,该变量不可更改,也不能 unset
[root@linux ~]# sum=100+300+50
[root@linux ~]# echo $sum
100+300+50 #没有宣告变量属性,只输出文字值
[root@linux ~]# declare -i sum=100+300+50
[root@linux ~]# echo $sum
450 #正确结果
[root@linux ~]# declare -x sum #将 sum 变成环境变量
[root@linux ~]# declare -r sum #将 sum 变成只读属性
[root@linux ~]# sum=testing #当为sum赋值时,提示只读
-bash: sum: readonly variable
• 数组属性 array
数组的设定方式:var[index]=content
[root@linux ~]# var[1]="small"
[root@linux ~]# var[2]="big"
[root@linux ~]# var[3]="large"
[root@linux ~]# echo "${var[1]}, ${var[2]}, ${var[3]}"
Samll,big,large
9.文件系统及程序的限制关系: ulimit (限制用户使用系统资源)
[root@linux ~]# ulimit [-SHacdflmnpstuv] [配额]
参数:
-H :hard limit ,严格的设定,不能超过设定值
-S :soft limit ,警告的设定,可以超过设定值,会有警告讯息,但是无法超过 hard limit
-a :列出所有的限制额度
-c :可建立的最大核心文件容量 (core files)
-d :程序数据可使用的最大容量
-f :此 shell 可以建立的最大文件容量 (一般可能设定为 2GB)单位为 Kbytes
-l :可用于锁定 (lock) 的内存量
-p :可用以管道处理 (pipe) 的数量
-t :可使用的最大 CPU 时间 (单位为秒)
-u :单一用户可以使用的最大程序(process)数量。
[root@linux ~]# ulimit -a
[root@linux ~]# ulimit -f 1024
10.额外的变量设定功能
1. 完整显示 Vygn变量的内容
[root@linux ~]# Vygn="/home/Vygn/test/test.x.sh"
[root@linux ~]# echo ${Vygn}
/home/Vygn/test/test.x.sh
2. 在 Vygn 变量中,如果从最前面开始比对,若开头为 / ,则删除两个 / 之间的所有数据,即 /*/
[root@linux ~]# echo ${Vygn##/*/} // ## 表示后面的字符串取最长的那一段
test.x.sh
[root@linux ~]# echo ${Vygn#/*/} // # 表示后面的字符串取最短的那一段
Vygn/test/test.x.sh
3. 在 Vygn 变量中,如果从后面开始比对,删除 /*
[root@linux ~]# echo ${Vygn%%/*/}
/home/Vygn/test/test.x.sh //完整输出了,没有删除,错误方式
[root@linux ~]# echo ${Vygn%%/*}
//完全删除了
[root@linux ~]# echo ${Vygn%/*}
/home/Vygn/test //只删除了 /test.x.sh 部分
% 表示从最后面开始比对字符,第一个方式Vygn 变量的最后是 h 而不是 / ,所以是错误的; %%/* 表示删除最长的/* ,而 %/* 表示删除最短的/*
4. 将 Vygn 变量中的 test 替代为 TEST
[root@linux ~]# echo ${Vygn/test/TEST} # / 表示用后面的字符仅替代一次前面的字符
/home/Vygn/TEST/test.x.sh
[root@linux ~]# echo ${Vygn//test/TEST} # // 表示用后面的字符全部替代前面的字符
/home/Vygn/TEST/TEST.x.sh
11.命令别名: alias, unalias
[root@linux ~]# alias #查询当前所有别名
[root@linux ~]# alias lm='ls -l | more #新建别名
[root@linux ~]# unalias lm #取消指定别名
12.历史命令:history
[root@linux ~]# history [n]
[root@linux ~]# history [-c]
[root@linux ~]# history [-raw] histfiles
n :表示数字,列出最近 n 笔命令的记录
-c :消除当前的 shell 中所有 history 记录内容
-a :将当前新增 history 指令加入 histfiles 中,若没有指定 histfiles ,默认写入 ~/.bash_history
-r :将指定的 histfiles 内容读取到当前 shell 的 history 记录中
-w :将当前的 history 记录内容写入 histfiles 中
[root@linux ~]# history #列出当前内存中的所有 history记录
[root@linux ~]# history 3 #列出当前最近的 3 笔 history 记录
[root@linux ~]# history –a histfiles #将当前新增history 记录写入 histfiles
[root@linux ~]# history –w histfiles #立即将当前history 记录写入 histfiles
[root@linux ~]# echo $HISTSIZE #默认会将历史记录写入 ~/.bash_history
1000
相关功能:
[root@linux ~]# !number
[root@linux ~]# !command
[root@linux ~]# !!
number :表示数字,执行第几笔指令
command :由最近的指令向前搜索开头为 command的那条指令,并执行
!! :执行上一条指令
13.登录信息显示: /etc/issue, /etc/motd
[root@linux ~]# cat /etc/issue #终端登陆中出现的提示信息
CentOS release 5.3 (Final)
Kernel /r on an /m
/d 显示本地日期
/l 显示终端接口编号
/m 显示硬件等级
/n 显示主机网络名称
/o 显示域名
/r 显示系统版本
/t 显示本地时间
/s 系统名称
/v 系统版本
[root@linux ~]# vi /etc/motd #显示用户自定义登陆信息,默认为空
14.环境设定文件:bashrc ; ~/.bashrc ; ~/.profile ; profile... ;/etc/inputrc ;source
• 系统设定值
1./etc/sysconfig/i18n #定义语系
2./etc/profile
#设定了PATH、USER、MAIL、 HOSTNAME、HISTSIZE、umask等重要变量,同时规划了 /etc/inputrc 键盘热建#设定的文件数据内容。可以在这里设定总体的 PATH 等信息,同时,这个文件也规划了 /etc/profile.d 和 #/etc/inputrc 这两个目录与文件
3./etc/bashrc #规划了 umask 功能,同时规划出提示字符PS1
4./etc/profile.d/*.sh
#/etc/profile.d 是目录,针对 bash 及 C-shell 规范了一些数据,这个目录的由来其实是在/etc/profile
#文件内规划的,可以自定义 *.sh 文件设定个性化系统
5./etc/man.config #规划man page 路径
15.个人设定值
1.~/.bash_profile ; ~/.bash_login ; ~/.profile
#通常选择其中一个即可,此文件可以定义个性化的路径 (PATH) 和环境变量,bash 启动时,会优先读取#~/.bash_profile,如果找不到,就读取 ~/.bash_login ,如果仍然找不到,最后读取 ~/.profile
2.~/.bashrc
#此文件在每次执行 shell script 时都会被重新读取一次,所以是最完整的,上面的~/.bash_profile 只在
#登陆时会被读取一次
3.~/.bash_history #记录历史命令
4.~/.bash_logout #当注销 bash 时,系统自动执行指令
登陆 bash ,设定文件的读取顺序:
1. 先读取 /etc/profile ,再根据 /etc/profile 内容读取其它设定文件, 例如 /etc/profile.d 和 /etc/inputrc 等设定文件
2. 根据不同用户,到用户家目录去读取 ~/.bash_profile 或 ~/.bash_login 或 ~/.profile 等设定文件
3. 根据不同用户,到用户家目录去读取 ~/.bashrc ,注意这个文件的设定值是最终设定
使设定文件生效:logout 然后 login 或者使用下面的方式使设定文件立即生效:
[root@linux ~]# source file
[root@linux ~]# source ~/.bashrc
[root@linux ~]# . ~/.bashrc # . 命令等同于source,脚本中常见此用法
16.login shell 与 non-login shell
login shell 是指当用户登陆 Linux 时,取得的 shell 称为 login shell。登陆后,再去执行其它的 shell 时,其它的 shell 就是 non-login shell。Login shell 与 non-login shell 的区别除了取得的时机不同外,它们读取的环境设定文件也相同。当登陆 Linux 时,即取得 login shell 时,会读~/.bash_profile ;~/.bash_login ;~/.profile,而取得login shell后继续使用其它的 non-login shell ,只读~/.bashrc
17.终端机环境设定: stty, set
[root@linux ~]# stty [-a]
-a #列出所有 stty 参数
其中,^ 表示 [Ctrl],例如 intr = ^C 表示利用 [ctrl] + c
重要的输出项目有:
• eof : End of file ,表示结束输入
• erase : 向后删除字符
• intr : 发出 interrupt (中断) 信号给当前正在运行的程序
• kill : 删除在目前指令列上的所有文字
• quit : 发出 quit 信号给当前正在运行的程序
• start : 在某个程序停止后,重新启动这个程序的输出
• stop : 停止当前屏幕的输出
• susp : 发出 terminal stop 信号给正在运行的程序
如果想要设置 [ctrl]+h 作为删除字符的快捷键,可以:
[root@linux ~]# stty erase ^h
[root@linux ~]# set [-uvCHhmBx] #显示变量,设定整个指令输出/输入环境
-u :默认不启用。若启用后,当使用未设定变量时,会显示错误讯息
-v :默认不启用。若启用后,在讯息被输出前,会先显示讯息的原始内容
-x :默认不启用。若启用后,在指令被执行前,会显示指令内容(前面有 ++ 符号)
-h :默认启用。与历史命令有关
-H :默认启用。与历史命令有关
-m :默认启用。与工作管理有关
-B :默认启用。与中括号 [] 的作用有关
-C :默认不启用。若使用 > 等,则若文件存在时,该文件不会被覆盖
[root@linux ~]# echo $- #显示当前所有set 设定值
himBH
[root@linux ~]# set -u #设定 "若使用未定义变量时,显示错误讯息"
[root@linux ~]# echo $Vygning
-bash: Vygning: unbound variable
默认情况下,未设定或未宣告的变量都会输出为空,若设定 -u 参数,当使用未设定的变量时,就会报错。很多的 shell 都默认启用 -u 参数。 若要取消这个参数, set +u 即可。
[root@linux ~]# set –x #执行前,显示该指令内容
[root@linux ~]# echo $HOME
+ echo /root
/root
++ echo -ne '/033]0;root@linux:~/007'
#输出的指令会被打印到屏幕上
[root@linux ~]# cat /etc/inputrc #设定其它的按键功能
#正常情况下最好不要修改终端的环境设定
18.万用字符、特殊符号、常用快捷键
* #万用字符,代表一个或多个字符或数字
? #万用字符,代表一个字母
# #批注说明
/ #转义符号,将特殊字符或万用字符还原成一般字符
| #分隔两个管道命令的界定
; #连续性命令的界定,在一行输入多条命令
~ #用户家目录
$ #变量前需要加的变量取代值
& #将指令移动到后台执行
! #逻辑运算符非
/ #路径分隔符
>, >> #输出重导向,分别是 取代 和 累加
' #单引号,没有变量置换功能
" #双引号,有变量置换功能
` ` #两个 ` (Esc下面的按键)中间的指令优先执行
( ) #在中间作为子 shell 的起始和结束
[ ] #在中间作为字符的组合
{ } #在中间作为命令块的组合
Ctrl + C #终止当前正在运行的指令
Ctrl + D #输入结束(EOF)
Ctrl + M #就是 Enter
Ctrl + S #暂停屏幕输出
Ctrl + Q #恢复屏幕的输出
Ctrl + U #删除整列命令
Ctrl + Z #暂停当前正在执行的指令
范例:
[root@linux ~]# ls test* # * 表示后面可以接受任意个字符
[root@linux ~]# ls test? # ? 表示后面能且只能接受一个字符
[root@linux ~]# ls test??? # ??? 表示后面能且只能接受三个字符
[root@linux ~]# cp test[1-5] /tmp #如果 test1, test2, test3, test4, test5 存在
#就复制到 /tmp 目录下
[root@linux ~]# cp test[!1-5] /tmp #除了 test1, test2, test3, test4, test5 之外的#test? 如果存在,就复制到 /tmp
[root@linux ~]# cd /lib/modules/`uname -r`/kernel/drivers # `uname -r`会优先执行
19.数据流重导向
指令执行过程中的数据输出流程:
File Standard input Command Standard output file/device
Standard error
File/device
1. 标准输入(stdin) : 代码为 0 ,使用 < 或 <<
2. 标准输出(stdout): 代码为 1 ,使用 > 或 >>
3. 标准错误输出(stderr): 代码为 2 ,使用 2> 或 2>>
[root@linux ~]# ls -l / > ~/rootfile #指令的输出被重导向到文件 ~/rootfile
[root@linux ~]#ls -l /home > ~/rootfile #指令的输出被重导向到文件 ~/rootfile
#并且只有ls -l /home 的输出内容
重导向数据的建立方式:
若文件不存在,系统会自动建立,若文件存在,系统会先将此文件清空,再将数据写入。即若以 > 输出到一个已存在的文件,此文件会被覆盖,如果想将数据继续累加,而不删除旧的数据,可以利用 >> :
[root@linux ~]#ls -l / >> ~/rootfile
指令下达方式:
Command > / 1> / 2> / 2>> / < 文件或设备
• 1> :将正确的数据输出到指定的地方
• 2> :将错误的数据输出到指定的地方
[root@linux ~]# find /home -name testing > list_right 2> list_error #错误数据输出到指定文件
[root@linux ~]# find /home -name testing > list_right 2> /dev/null #只输出正确数据
[root@linux ~]# find /home -name testing > list 2>&1 #正确和错误输出到一个文件
< 表示通过指定文件读入数据
[root@linux ~]# cat > testfile < somefile #somefile文件内容作为 cat > testfile 的输入
<< 表示结束输入字符
[root@linux ~]# cat > testfile <<eof
> This is a test #任意输入字符
> eof #当输入eof后,立即结束输入
输出重导向的重要性:
• 保存屏幕的输出数据
• 后台执行的程序,不干扰前台屏幕正常的输出
• 保存系统例行命令(/etc/crontab)的执行结果
• 丢弃某些程序输出的错误信息,使用 2> /dev/null
• 错误信息和正确信息需要分别输出
20.指令执行的判断: ; && ||
[root@linux ~]# sync; sync; init 6 # ; 分号用于分割多条指令
[root@linux ~]# ls /tmp && touch /tmp/test #只有ls /tmp 执行成功touch /tmp/test 才执行
[root@linux ~]# ls /tmp/test || touch /tmp/test1 #只有ls /tmp 执行失败touch /tmp/test1 才执行
[root@linux ~]# ls /tmp/test && echo "exist" || echo "not exist"
#如果存在输出exist否则输出not exist
[root@linux ~]# ls /tmp/test || echo "not exist" && echo "exist"
#这是错误写法,因为指令是按顺序执行的
command1 && command2 || command3 #判断指令正确下达方式
21.管道命令
[root@linux ~]# ls -al /etc | less # less 读取ls 输出后的内容
管道命令 | 只能处理由前面指令输出的正确信息,即 standard output ( STDOUT ) 的信息,对于 stdandard error 没有处理能力。每个管道的前后部分都是指令,前面指令的输出作为后面指令的输入。信息的处理通常是以行为单位,即是否具有 [Enter] 标志 (CR) 作为一段处理的依据
STDOUT STDIN STDOUT STDIN
Command1 | Command2 | Command3
基本管道指令:cut ; grep
• cut
[root@linux ~]# cut –d '分隔字符' -f fields
[root@linux ~]# cut -c 字符区间
-d :后接分隔字符。与 -f 一起使用
-f :根据 -d 的分隔字符将一段信息分割成为数列,-f 表示取出第几列
-c :以字符 (characters) 的单位取出固定字符区间
范例一:将 PATH 变量取出,我要找出第三个路径。
[root@linux ~]# echo $PATH
/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin
[root@linux ~]# echo $PATH | cut -d ':' -f 3 #取出PATH变量的第三列,:作为分隔字符
/sbin
[root@linux ~]# echo $PATH | cut–d ':' -f 3,5 #取出PATH变量的第三和第五列
/sbin: /usr/local/bin
[root@linux ~]# echo $PATH | cut -c 5- #取出export输出的第 5 个字符后的所有字符串
#包含第5个字符
:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin
[root@linux ~]# last #取出本月登陆用户信息
root tty1 192.168.0.200 Thu Jul 2 16:35 - 17:48 (02:06)
root tty1 192.168.0.200 Thu Jul 2 16:40 - 11:54 (02:07)
[root@linux ~]# last | cut -d ' ' -f 1 #只取出第一列用户名信息
• grep
[root@linux ~]# grep [-acinv] '字符串' filename
-a :将二进制文件以文本文件的形式进行搜索
-c :统计找到 '字符串' 的次数
-i :忽略大小写
-n :输出行号
-v :反向搜索’字符串’,即只输出不包含’字符串’的行
[root@linux ~]# last | grep 'root' #取出只包含root字符串的行
[root@linux ~]# last | grep -v 'root' #取出不包含root字符串的行
[root@linux ~]# last | grep -v '^$' #取出不包含空行的行
[root@linux ~]# last | grep 'root' | cut -d ' ' –f 1 #取出只包含root字符串的行且只取第一列
排序指令: sort ; wc ; uniq
• sort
[root@linux ~]# sort [-fbMnrtuk] [file or stdin]
-f :忽略大小写
-b :忽略最前面的空格符
-M :按月份排序
-n :按纯数字排序(默认是按字符排序)
-r :反向排序
-u :就是指令 uniq ,不输出重复行
-t :分隔符,默认是 tab 键
-k :按指定列 (field) 进行排序
[root@linux ~]# cat /etc/passwd | sort #排序用户
[root@linux ~]# cat /etc/passwd | sort -t ':' -k 3 #按第三列的内容排序
[root@linux ~]# cat /etc/passwd | sort -t ':' -k 3 –n #指定按纯数字排序,默认是字符
[root@linux ~]# last | cut -d ' ' –f 1 | sort #只取用户名排序
• uniq
[root@linux ~]# uniq [-ic]
-i :忽略大小写
-c :统计次数
[root@linux ~]# last | cut -d ' ' –f 1 | sort | uniq #只取用户名排序且不输出重复行
[root@linux ~]# last | cut -d ' ' –f 1 | sort | uniq –c #只取用户名排序且不输出重复行并统计次数
• wc
[root@linux ~]# wc [-lwm]
-l :只计算行
-w :只计算单词
-m :只计算字符
[root@linux ~]# cat /etc/man.config | wc
141 722 4617
[root@linux ~]# last | cut –d ’’-f 1 | grep -v 'wtmp' | grep –v ’^$’| sort | uniq | wc –l
#取出登陆的用户名,排除wtmp用户和空行,排除重复行,计算总用户数
22.双向重定向: tee
Standard input tee Screen
file
#同时将数据流输出到文件和屏幕
[root@linux ~]# tee [-a] file
-a :以累加的方式,将数据重定向到 file 文件
[root@linux ~]# last | tee teetest | cut -d ’’–f 1 #同时输出到屏幕和文件
[root@linux ~]# ls -l / | tee -a teetest | more #以累加方式输出到文件
23.字符转换命令: tr ; col ; join ; paste ; expand
• tr #删除一段信息中的文字,或者文字信息的替换
[root@linux ~]# tr [-ds] SET1 ...
-d :删除信息中的 SET1 字符串
-s :替代重复字符
[root@linux ~]# last | tr '[a-z]' '[A-Z]' #将小写转换成大写
[root@linux ~]# cat /etc/passwd | tr –d ':' #删除输出信息中的:冒号
[root@linux ~]# cat /home/test/dostxt | tr -d '/r' > dostxt-noM
#删除DOS 文件的断行字符 ^M
#/r 指 DOS 的断行符
• col
[root@linux ~]# col [-x]
-x :将 tab 键转换成空格键
[root@linux ~]# cat -A /etc/man.config #输出中显示的^I 符号,表示 tab
[root@linux ~]# cat /etc/man.config | col -x | cat -A | more
• join #将两个文件中,指定列内容相同的行连接起来
[root@linux ~]# join [-ti12] file1 file2
-t :join 默认以空格符分隔列,且比较第一列数据 如果相同,就将两行数据联成一行,且第一列放在行首
-i :忽略大小写
-1 -2 :数字1和2,比较文件1指定的某一列及文件2指定的某一列
[root@linux ~]# join -t ':' /etc/passwd /etc/shadow #整合/etc/passwd和/etc/shadow
[root@linux ~]# join -t ':' -1 4 /etc/passwd -2 3 /etc/group #整合/etc/passwd和/etc/group
• paste #将两行连接,以 [tab] 符分隔
[root@linux ~]# paste [-d] file1 file2
-d :后接分隔符。默认是[tab]
- :表示文件来自 standard input
[root@linux ~]# paste /etc/passwd /etc/shadow #连接/etc/passwd和/etc/shadow相同行
[root@linux ~]# cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3
# - 表示cat 的stdout 作为 paste 的 stdin
• expand #将 [tab]转换成空格
[root@linux ~]# expand [-t] file
-t :接数字,默认tab 可以用 8 个空格替代,可以自定义[tab]代表的字符数
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3
MANPATH /usr/man
MANPATH /usr/share/man
MANPATH /usr/local/man
#取出行首为MANPATH的行且只取前三行 , ^ 是行首标志
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3 |cat -A
MANPATH^I/usr/man$
MANPATH^I/usr/share/man$
MANPATH^I/usr/local/man$
#取出行首为MANPATH的行且只取前三行 ,并显示特殊标记
范例三:承上,我将 [tab] 按键设定成 6 个字符
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3 | expand -t 6 | cat -A
MANPATH /usr/man$
MANPATH /usr/share/man$
MANPATH /usr/local/man$
123456123456123456 #显示时会自动调节,如果expand –t 9 :
MANPATH /usr/man$
MANPATH /usr/share/man$
MANPATH /usr/local/man$ #从MANPATH的M开始到/之间是9个空格
123456789
24.分割指令: split
[root@linux ~]# split [-bl] file PREFIX
-b :分割尺寸,单位是 b, K, M
-l :按行进行分割
[root@linux ~]# cd /tmp; split -b 300k /etc/termcap termcap
[root@linux tmp]# ls -l termcap*
-rw-rw-r-- 1 root root 307200 8月 17 00:25 termcapaa
-rw-rw-r-- 1 root root 307200 8月 17 00:25 termcapab
-rw-rw-r-- 1 root root 184848 8月 17 00:25 termcapac
#分割/etc/termcap,分割尺寸为300K
[root@linux tmp]# cat termcap* >> termcapback
#通过数据流重定向将三个文件合并成一个文件
[root@linux tmp]# ls -al / | split -l 10 - lsroot
#将ls –al的输出每十行记录成一个文件,如果没有stdout/stdin,但是又需要 stdout/stdin 时,使用 #– 替代stdout/stdin
25.参数代换: xargs
[root@linux ~]# xargs [-0epn] command
-0 :如果stdin 含有特殊字符,例如 `, /, 空格键等, -0 参数可以把这些特殊字符还原成一般字符
-e :就是 EOF,后接字符串,当 xargs 分析到这个字符串时,就会停止
-p :在执行每个指令的 argument 时,都询问用户意见
-n :后接次数,表示每次 command 指令执行时,要使用到几个参数
当 xargs 后面没有接任何的指令时,默认以 echo 进行输出
[root@linux ~]# cut –d ':' –f 1 < /etc/passwd | head -n 3 | xargs finger
#取出etc/passwd的第一列账号且只取三行,此三行作为参数传递给finger,显示每个账号的具体内容
[root@linux ~]# cut –d ':' –f 1 < /etc/passwd | head -n 3 | xargs -p finger
finger root bin daemon ?...y
范例三:将所有的 /etc/passwd 内的账号都以 finger 查阅,但一次仅查阅五个账号
[root@linux ~]# cut –d ':' –f 1 < /etc/passwd | xargs -p -n 5 finger
#取出etc/passwd的第一列账号作为finger的参数且每次只查看5个账号
[root@linux ~]# cut –d ':' –f 1 < /etc/passwd | xargs -p -e'lp' finger
#当分析到 lp 时就停止执行
26.关于减号 - 的用途
#在管道指令中,经常使用前一个指令的 stdout 作为后一个指令的 stdin ,某些指令需要用到文件名称 (例#如 tar) 来进行处理时,stdin 和 stdout 可以用减号 "-" 替代:
[root@linux ~]# tar -cvf - /home | tar -xvf -
#将 /home 目录里的文件打包,但打包的数据不生成文件,而是将 tar -cvf - /home 的 stdout 经过管道后#传递给后面的指令 tar -xvf - ,- 取用前一个指令的 stdout,所以就不需要使用 file 了。