linux命令行和shell编程大全 学习笔记

【所有相关命令的基本语法可以通过man查看,善用man

第三章:基本的bash shell命令

1:关于bash 手册

通过man可以调出bash手册,包含了一些帮助信息。

【man -k关键字】不记得命令名的时候可以这样使用

Linux手册页的内容区域,CAT(1)也就是括号中的数字,一共有九个内容区域


2:文件系统

Linux文件存储在单个目录结构中,这个目录称为【虚拟目录】;

安装的第一块硬盘称为跟驱动器,Linux会在根驱动器上创建一些特别的目录,称之为【挂载点,(挂载点是虚拟目录中用于分配额外存储设备的目录)】

了解一些Linux常见顶层目录,常见的目录名基于【文件系统层级标准filesystem hierarchy standard FHS】


ls输出的列表按照字母升序排列的,并且是按照列排列的,支持过滤器,请了解通配符

-i可以查看inode编号

ll输出的相关说明:

【文件类型,文件权限,硬链接总数,文件属主用户名,文件属组组名,文件大小(单位是字节),文件上次修改时间,文件名】

【-F】标识文件类型,目录还是文件等等bi

【-h】大小易读


touch创建一个空文件,如果已经存在一个文件名为file1,touch file1后只会更改文件的修改时间,不会修改内容,只想改变文件访问时间,指定 -a 参数,此时使用【ls -l --time=atime 文件名】就可以看到文件的访问时间


【cp source destination】文件的复制,目的地是目录时最好加上【/】,【-i】可以发出询问是否进行覆盖。cp -r dir ... 或者 cp -r dir/ ...都会包括目录名进行复制,只想复制内容可以在目录名下是用*


链接文件:【链接是目录中指向真实位置的占位符】

·符号链接:一个实实在在的文件,指向虚拟目录中的某一个文件。为一个文件创建符号链接,该文件必须存在。创建方式【ln -s file sl_file】

·硬链接:只能对处于同一存储媒体的文件创建硬链接。本质上和源文件是同一个文件。指向同一个iNode,所以删除源文件后还是可以通过硬链接访问源文件。无法对目录生成硬链接。硬链接不会占用磁盘空间。

不要为软链接文件创建软链接


【mv oldname newname】进行文件改名,并且只会影响文件名,不改变iNode编号和时间戳。

也可以用来移动文件的位置。


【rm options filename】删除文件


【mkdir dirname】创建目录,创建多级目录使用参数【-p】


rmdir默认只能删除空目录,可以使用rm -r 删除目录



file用来查看文件的类型,可以在访问之前稍微了解下文件,尤其是二进制文件时,贸然直接访问可能会使终端仿真器挂起


查看文件的几个命令

cat -n显示行号,-b有文本的才显示行号。

more支持分页显示文件,回车或者空格逐行移动,只支持基本移动,更多高级功能需要使用less

less

tail查看结尾的文本,默认最后10行,【-n 行数】控制显示倒数多少行,也可以直接【-行数】。【-f】参数可以在其他进程使用文件时查看文件的内容。进行实时监控

head查看文本的开头,默认显示开头10行。


第四章:更多地bash shell命令

1:监测进程程序

ps探查进程,参数很多,【-e】显示当前系统正在运行的进程,【-f进程信息的扩展输出】,BSD格式的参数l可以显示更为详细的进程状态。进程状态STAT,R表示正在运行,S表示睡眠,Z表示僵化,进程已经结束但父进程不存在,T代表停止,第二个参数<:运行在高优先级上,N:运行在低优先级上,L:进程所有页面锁定在内存中,s:进程为控制进程,l:进程是多线程的,+:进程运行在前台

【--forest可以显示进程层级关系】


top进行实时监测,第一部分输出系统概况。分别是:

第一行输出当前时间,系统运行时间,登录用户数,以及系统平均负载,平均负载三个值分别为最近1分钟,5分钟和15分钟。

第二行显示进程概要信息,第三行显示CPU概要信息,第四行显示物理内存信息,第五行显示交换空间信息。

PID:进程的id,USER:进程属主的名字,PR:进程优先级,NI:进程谦让程度

VIRT:进程占用虚拟内存总量 RES:进程占用物理内存总量

SHR:进程和其他进程共享的内存总量

S:进程状态(D表示可中断的休眠,R运行,S休眠,T跟踪或者停止,Z僵化)

%CPU:进程使用的CPU时间比例

%MEM:进程使用内存占可用内存的比例

TIME+:进程启动到目前为止CPU时间总量

COMMAND:进程启动的程序名


结束进程,进程之间的通信是通过信号来进行的。Linux进程信号:

1~HUP~挂起 2~INT~中断 3~QUIT~结束运行 9~KILL~无条件终止

11~SEGV~段错误 15~TERM~尽可能终止 17~STOP~无条件停止运行,但不终止

18~TSTP~停止或者暂停,但继续在后台运行

19~CONT~在STOP或者TSTP之后恢复执行


向运行中的进程发出进程信号有两个命令【发出进程信号必须是进程的属主或者root用户】

kill 只能通过PID给进程发送信号P,【-s】指定特定的信号,kill -s HUP PID

killall支持通过进程名结束进程


2:监测磁盘空间

1):挂载存储媒体

mount,默认输出当前系统上挂载的设备列表,提供的信息是:媒体的设备文件名,虚拟目录挂载点,文件系统类型,访问状态

手动挂载设备需要root权限。mount -t type device directory

type表示设备的文件系统类型,pc常用的有:vfat~windows长文件系统,ntfs~windows高级文件系统,iso9660~标准CD-ROM文件系统

卸载存储媒体

umount [dir|device]


2)查看磁盘信息

df输出相关说明

设备文件位置,能容纳多少个1kB大小的块,已经用了多少个1kB的块,还有多少个块可用,已用空间占用的比例,设备挂载到了哪个挂载点上。

【-h】会使输出信息易于阅读

显示的是Linux系统认为的当前值,有可能运行的进程对文件做了一些改动,但是没有释放文件,这个值是不会算进闲置空间的


du,直接输出为当前目录的相关信息。左边表示占用的磁盘块数,常用的参数:

-c:显示所有已经列出文件总大小

-h:易读

-s:显示每个输出参数的总计

-a:不仅仅是显示目录


3:处理数据文件

[if !supportLists]1)[endif]排序数据

sort默认按照会话指定的默认语言的排序规则进行排序,【-n】识别数字进行排序

【-M】识别三字符的月份,按照月份进行排序

【-t】指定分隔字符

【-k】指定排序的字段

【-r】倒序排列

sort -t ‘:’ -k 3 -n /etc/passwd


[if !supportLists]2)[endif]搜索数据

grep options pattern file

【-v】反向搜索(输出不匹配的记录)

【-n】匹配的行所在的行号

【-c】显示多少行含有匹配的模式

【-e】指定匹配模式 grep -e t -e f file,输出file中所有包含t或者f的行

支持正则表达式

更多的搜索工具还有egrep,fgrep等

[if !supportLists]3)[endif]:压缩数据

gzip为Linux上最流行的压缩工具

gzip用来压缩文件,gzcat查看压缩过的文本文件的内容,gunzip解压文件


[if !supportLists]4)[endif]:归档数据

tar

常见功能选项

-c:创建一个新的归档文件

-t:列出归档文件的内容

-x:从tar归档文件中提取文件

常见命令选项

-f file:输出结果到文件或者设备

-v:处理文件时显示文件

-z:输出重定向给gzip进行压缩


第五章:理解shell

【(command;command;command;...)】这是一个进程列表,会生成一个子shell

$BASH_SUBSHELL用来保存当前的shell是什么shell,0是父shell

另一种进程列表创建方法是{command;},这个并不会生成一个子shell


后台模式

命令后使用&进入后台执行

jobs会显示所有的后台进程,【-l】参数会显示更多的信息

将进程列表置于后台模式,既可以在子shell中进行繁重的处理工作,也不会让子shell的I/O受制于终端


协程

协程同时处理两件事情,在后台生成一个子shell并且在这个子shell中执行命令

使用【coproc command】 进行协程处理

将协程和可生成子shell的进程列表一起使用,可以产生嵌套子shell


[if !supportLists]1)[endif]:外部命令

也被称为文件系统命令,通常位于【/bin,/usr/bin,/sbin,/usr/sbin】

外部命令执行时,会创建出一个子进程,这种操作称之为“衍生(forking)”

正因为如此,外部命令还是有些许代价的


2):内建命令

内建命令不需要使用子进程来执行

查看一个命令是否是内建命令使用:type command

type -a command显示命令的多种类型,如echo和pwd既有内建命令也有外部命令

【!!能够执行上一条指令】

【!编号】可以执行历史记录中的相应编号的命令

命令历史记录先保存在内存中,shell退出时才会写进用户目录下的隐藏文件.bash_history.

将历史命令记录强制写入文件需要使用【-a】




alias命令别名

【-p】查看当前可用的别名

创建别名【alias newname=’commandschakan’】

命令别名属于内部命令,一个别名只在它所被定义的shell进程中有效

取消别名unalias name


本章小结:能够创建子进程的命令:外部命令

能够创建子shell的方法:执行相关shell程序,如bash,tcsh,...;使用进程列表,使用协程


第六章:使用Linux环境变量

环境变量分为两类:局部环境变量和全局环境变量;全局环境变量对于shell会话和所有生成的子shell都是可见的,局部环境变量只对创建他们的shell可见。

【全局环境变量对那些所创建的子shell获取父shell信息的程序来说非常有用】


1):全局环境变量

查看:【printenv】或者【env】查看特定的环境变量使用前者,如printenv JAVA_HOME

使用【echo $varName】也可以显示变量值


【set】显示为某个特定进程设置的所有环境变量,包括局部变量,全局变量,和用户自定义变量。没有特殊的命令可以显示局部环境变量


创建自定义全局环境变量【export】

【修改子shell中全局环境变量并不会影响父shell中该变量的值,即使使用export也不行】

删除环境变量【unset varName】

【一般;关于$的使用:如果要用到变量,需要使用;操作变量,不需要使用】

同样,子shell中删除一个环境变量父shell中依然不受影响

父shell中的局部变量子shell中也无法使用


2):path环境变量

可以临时修改path变量;PATH=....


3):定位系统环境变量

启动bash shell的三种方式

登录时作为默认登录shell

作为非登录shell的交互式shell

作为运行脚本的非交互shell


作为默认登录shell启动时,登录shell会从五个不同的启动文件中读取;分别是

/etc/profile

$HOME/.bash_profile

$HOME/.bashrc

$HOME/.bash_login

$HOME/.profile


交互式shell进程启动时,比如在命令行下执行bash,就会启动一个交互式shell,只会检查$HOME/.bashrc文件


非交互式shell时,例如运行shell脚本,这个时候会检查BASH_ENV这个环境变量。


4):关于环境变量持久化

【直接在/etc/profile中修改变量不是一个好主意,因为会随着发行版的升级而更新从而导致自己修改的变量设置失效】

好的方法是在/etc/profile.d下创建一个.sh结尾的文件,将所有的新的或者修改过的全局变量设置放在这个文件中.


5):数组变量

varName=(varValue0 varValue1 varValue2),将变量值放在小括号中,中间使用空格隔开

数组下标从0开始,如echo ${varName[1]}将输出varValue1,显示整个数组,索引使用[*]


第七章:Linux的安全性

1):用户控制,主要通过两个文件

/etc/passwd文件,各个字段的信息如下

登录用户名;用户密码;用户账户UID,用户账户GID,用户账户文本描述,用户HOME目录位置,用户默认shell

/etc/shadow

登录名,加密后的密码,自上次修改密码之后过去的天数密码,多少天后才能更改密码,多少天后必须更改密码,密码过期前提前多少天提醒用户更改密码,密码过期多少天后禁用账户,账户被禁用日期,预留字段.


2):添加新用户

useradd,可以一次性创建新用户账户以及设置用户home目录

如:[useradd -u 544 -d /usr/testuser1  -g users -m  testuser1 ]建立一个新用户账户testuser1,并设置UID为544,主目录为/usr/testuser1,属于users组

[-D]可以查看创建用户时的一些默认值

-m创建用户的home目录

-p指定用户密码


3):删除用户

userdel,默认只会删除/etc/passwd文件中的用户信息,并不会删除系统中属于这个账户的任何文件

[-r]可以删除用户目录,但是可能会有一些问题,在删除用户主目录时请一定慎重


[关于改变文件属主属组

chown user:group  file

chgrp group file

]

4):修改用户

usermod:修改用户账户的字段

[-g]修改默认的登录组

[-l]修改登录名

[-L]锁定账户,用户将无法登录

[-p]修改账户密码

[-U]解除锁定zifu


passwd user root用户用来修改别人的密码,用户自己只能修改自己的密码

chpasswd可以为大量用户修改密码,能够从标准输入读取登录名密码对(冒号分隔),进行相应的设置

注意,如果一个用户在/etc/passwd文件中指定某个组为默认用户组时,这个时候用户账户不会作为该组成员再次出现在/etc/group中

groupadd groupname可以增加一个新组

添加用户到一个组中可以使用usermod  -g groupname username,注意,-g表示指定的组将会成为整个用户的默认组,如果使用-G,则不会影响用户的默认组


5):理解文件权限

- 文件

d 目录

l 链接

c 字符型设备

b 块设备

n 网络设备

ll显示的链接数是指对inode的硬链接数目

用户创建文件的默认权限可以由umask进行设置,命令行输入umask会显示当前用户创建文件的umask,注意,umask的值是对象的全权限减掉的那个值,目录的全权限是777,文件的全权限是666;

umask xxx可以设置新的umask值


chmod改变文件权限 -R参数可以进行递归修改

u 用户

g 组

o 其他

a 上述所有


第七章:Linux的文件系统









第九章:熟悉常用的编辑器

vim,emacs,kde,gnome

vim常用的命令

hjkl:左下上右

ctrl+F下一屏

Ctrl+B上一屏

gg第一行

G 最后一行


冒号后可以使用的命令

q! 强制退出,取消所有对缓冲区数据的修改

w filename 保存到文件名

wq 将缓冲区数据保存到文件中并且退出


编辑数据时使用的命令

x 删除当前光标所在位置的字符

dd 删除当前光标所在的行

dw 删除当前光标所在位置的单词

d$ 删除当前光标所在位置到行尾的内容

J 删除当前光标所在行行尾的换行符

u 撤销前一个编辑命令,如删除,插入等

a 在当前光标后追加数据

A 在当前光标所在行的行尾追加数据

r char 用char替换当前光标所在位置的单个字符

R text 用text覆盖当前光标所在位置的数据,直至按下esc


注意:有些命令允许在前面加上数字,表示重复执行命令的次数

剪切实际上就是删除之后在拿回来,实际上删除的数据会保存在一个单独的寄存器中,使用p可以取出寄存器中的内容,实际上就完成了粘贴.

yw表示复制一个单词

y$表示复制到行尾

同样使用p取出


查找和替换

普通模式下按下斜线

输入想要查找的内容,n切换下一个


替换

:s/old/new/跳到第一次出现的地方并且使用new替换

:s/old/new/g 替换所有的old

:n.ms/old/new/g 替换行号n和m之间的所有old

:%s/old/new/g 替换整个文件中的所有old

:%s/old/new/gc 替换整个文件中的所有old,但是每次替换会需要确认


第二部分:shell脚本编程基础

第十章:构建基本脚本

双引号中可以使用转义,可以解析变量

shell中自定义用户变量区分大小写

变量等号和值之间不能出现空格

在shell脚本整个生命周期变量都会保持他们的值,在脚本完成时删除

反引号允许将命令的执行结果赋值给变量


1):重定向

>输出重定向,会覆盖重定向文件中的原来数据

>>追加重定向,会在重定向文件的末尾追加数据

<输入重定向

<<内联输入重定向,需要制定一个分隔符,之后会提示一直输入字符,直到输入分隔符


2):管道操作符

|管道的两个命令不是一个一个地运行,而是同时运行,在系统内部将他们连接起来.在的第一个命令产生输出的同时,输出会被立即送到第二个命令,不会用到任何中间文件或者缓冲区域


3):对数字进行操作

$[math expression]可以进行数学运算

注意,bash shell的这种运算只会进行整数运算,不能进行浮点数运算

bash的浮点解决方案--bash计算器,即bc

bc可以识别:数字,变量,注释#或者/**/.表达式,编程语句,函数

命令行执行bc,小数位数由bc的内建变量scale控制,必须设置这个变量值才可以显示想要的结果;

退出bc请使用quit


4):如何退出脚本

退出状态码:

0成功结束

1通用未知错误

2误用shell命令

126命令不可执行

127没找到命令

128无效退出参数

128+x信号x的严重错误

130命令通过ctrl+c终止

255退出状态码越界

使用[exit数字] 自定义退出状态码


第十一章:使用结构化命令

1):if-then语句

if command

then

command

fi

if之后的对象是个命令,如果这个命令成功运行(退出码是0),那么相当于判断为真

注意:if后的命令是会执行的!!!


2):if-then-else语句

if command

then

command

else

command

fi


3):嵌套if,使用elif


4):test命令

test condition如果条件成立,退出返回状态码0,不成立退出返回状态码1

可以判断三类条件:

数值比较,字符串比较和文件比较.

if test condititon或者 if [ condition ]注意,方括号两端需要有空格


数值比较:

x -eq yx和y 是否相等

-ge大于或者等于

-gt大于

-le小于或者等于

-lt小于

-ne不等于


字符串比较

=!=<>-n检测字符串长度是否不为0 -z检测字符串长度是否为0

比较相等时,所有的标点和大小写均处于考虑之中

比较大小时,

大于或者小于号必须进行转义,避免和重定向符号冲突;大于小于顺序和sort采用的并不相同,test命令使用的是标准ASCII排序, 但是sort使用的是本地化的设置


文件比较



-d file检测file是否存在并且是一个目录

-f file检测file是够存在并且是一个文件

-e file检测file是否存在

-s file检测file是否存在并且非空

-r w x file检测file是否存在并且可读可写可执行

-O file检测file是否存在并且属于当前用户

-G file检测file是否存在并且默认组合当前用户相同

file1 -nt file2检测file1是否比file2新

file1 -ot file2检测file1是否比file2旧


既然使用了test,那么就可以使用逻辑运算符&&和||


5):使用双括号

((expression))可以进行各种运算,自增,自减,位运算等等

可以用在if语句中


6):使用双方括号

[[ expression ]],提供了针对字符串比较的高级特性,可以使用模式匹配

可以用在if语句中


7):使用case

case variable in

pattern1|pattern2) commands;;

pattern3) commands;;

*) default commands;;

esac

注意,上面的命令结束之处是分号


8):for循环语句

for var in list

do

commands

done


list中的每个量之间使用空格隔开,如果list中某个值需要空格,请使用双引号


[IFS:内部字段分隔符,默认是空格,制表符和换行.可以修改,IFS=$’\n’,将只会识别换行符,请注意,修改之前请备份这个环境变量,以便之后进行恢复.]


9):while循环

while test command

do

commands

done

while可以指定多个测试命令,只有最后一个命令的返回码产生效果


10):until命令

until test condition

do

commands

done


只有test返回的退出状态码是0时才结束循环,这一点恰好和while相反


11):break,跳出一个循环

break n可以指定跳出哪一层循环,默认是1,也就是当前循环,2表示跳出外层循环

12):continue忽略一次循环体的执行,同样可以指定外部还是内部循环


在done之后使用重定向符号可以将循环体中的输出重定向到指定的文件或者设备中,而不是直接显示在屏幕上,同样,也可以使用管道符号


第十三章:处理用户输入

1):命令行参数

称为位置参数,$0表示当前运行的程序名,basename $0 可以过滤掉路径名,只显示程序的名称.


几个特殊的参数

$#记录命令行参数的个数

$*将所有参数当做一个参数

$@将所有参数看做独立的参数,可以进行遍历


shift n将参数向前移动n位,也就是前面的参数会被后面的参数取代,参数长度变短


2):getopt命令

getopt可以将命令行的输入参数进行标准化,将合并在一起的选项进行拆分,参数和选项之间采用--分隔,使用时,将可能在一合并的选项列出,多个则中间使用:连接

getopt -q ab:cd -a -b test -cd test1 test2

-a -b test -c -d -- test1 test2

-q表示忽略前面没有指定的合并选项,使之不会产生错误


3):getopts

是对getopt的功能的扩展

getopts optstring variable,例如 getopts :ab:c opt

:表示忽略错误

解析命令行选项时,会过滤其中的-,只会显示选项的字母

可以识别含有空格的参数

将未定义的选项解析成?


4):通用的Linux选项

-a显示所有对象

-c生成一个计数

-d指定一个目录

-e扩展一个对象

-f指定读入数据的文件

-h显示命令的帮助信息

-i忽略文本大小写

-l产生输出的长格式输出

-n使用非交互模式

-o指定将所有输出重定向到的文件

-q安静模式运行

-r递归处理目录和文件

-v生成详细输出

-x排除某个对象

-y对所有问题回答yes


5):获取用户的输入

read varName

用户输入的内容会保存在varName中

read -p提示字符 varName1 varName2 ...

如果不指定变量,那么会将数据放在特殊环境变量REPLY中


可以使用[-t]指定计时器,在到达时间后,指令会以非零退出状态码退出.

-t之后参数为整数,表示等待输入的秒数

-nl指定接受单个字符之后退出,无需enter键

-s以隐藏方式进行读取,实际上是将文本颜色和背景颜色调节成一致的

read还可以读取文件,一次读一行,利用管道技术


第十四章:呈现数据

1:理解输入和输出

Linux中的所有对象都被认为是文件,每次会话过程最多可以有九个文件描述符,bash保留了最早的三个,0,1,2,分别是标准输入,标准输出,标准错误

1>标准输出重定向

2>标准错误重定向

&>标准输入和错误重定向,错误信息显示的优先级更高shu

&1重定向到标准输出的文件描述符,在脚本使用之后,指定脚本,所有出现这个符号的都会重定向到执行脚本时1>指定的文件

如:echo“this is a error message”>&2 (>&中间没有空格)为a.sh

执行sh a.sh 2> a.txt,那么这行信息将会到a.txt中

&2同理


2):永久重定向

exec 1>file

接下来的所有标准输出全部都会重定向到指定的文件

同理,重定向输入 exec 0< file,只要脚本需要输入,输入的数据都来自file


2:创建文件描述符

1):创建输出文件描述符

使用exec进行指定,例如 exec 3>test3out,接下来只要是重定向到3的输出,都会重定向到test3out里

2):可以重定向文件描述符

exec 3>&1

exec 1>file

exec 1>&3

相当于输出到3将会显示在屏幕上,标准输出将会写入文件,最后复原

这中间使用到了其他的文件描述符作为中间量


关闭问价描述符;如[exec 3>&-] 将会关闭文件3这个文件描述符

查看当前系统打开的所有文件描述符lsof -a -p $$ -d 0,1,2,3,4,...

-p指定进程号,-d指定文件描述符


2:阻止命令输出

当脚本运行在后台时,一般不希望脚本输出

可以将stderr重定向到/dev/null文件,你这样脚本的错误信息将会被丢弃,因为null文件不会保存任何数据


3:创建临时文件

mktemp创建临时文件,一定要在文件名结尾输入6个X,如:mktemp testXXXXXX

[-t]将会强制在/tmp下创建临时文件

[-d]创建临时目录

此命令会返回创建的文件的全路径


4:同时记录

tee file这个命令将会把标准输入的数据发送到标准输出和file

[-a]追加模式


第十五章:控制脚本

进程信号重温

1 SIGHUP挂起

2 SIGINT终止

3 SIGQUIT停止进程

9 SIGKILL无条件终止

15 SIGTERM可能的话终止进程

17 SIGSTOP无条件停止进程

18 SIGTSTP停止或者暂停进程

19 SIGCONT继续运行停止的进程

bash默认会忽略3和15信号.

1:产生信号

1):终止进程 ctrl+c 生成SIGINT信号,终止信号

2):暂停进程 ctrl+z 生成SIGTSTP信号,停止shell中运行的任何进程

[停止进程会让进程继续保留在内存中,并且可以从上次停止的位置继续运行]


2:捕捉信号

trap commands signals

如: trap“echo ‘ i can trap the signal ’”SIGINT,在键盘ctrl+C时,并不会终止脚本的运行,而是会执行上面指定的语句,打印输出


移除捕捉信号trap - EXIT ...


3:后台进程

执行时在进程后面加上&

如果想要在退出终端会话后后台进程依然能够运行,使用nohup

nohup command &会将产生的输出重定向到脚本同级目录下的nohup.out


4:作业控制

1):查看作业

jobs查看shell当前正在运行的作业

[-l]列出进程的pid以及作业号

[-n] 只列出上次shell发出的通知后改变了状态的作业

[-p] 只列出作业的pid

[-r] 只列出运行中的作业

[-s] 只列出已停止的作业

输出中的加号和减号表示:加号会被当做默认作业,在使用作业控制命令时,如果未在命令行指定任何作业号,该作业会被当成操作对象,带减号的作业会在当前默认作业完成处理时称为下一个默认作业.任何时候都只有一个加号作业和一个减号作业.


2):重启停止的作业

以后台模式重启[bg作业号]

前台模式启动[fg作业号]


5:调整谦让度

优先级是个整数值,范围:-20~20,数字越大,优先级越小

默认,bash以优先级0启动所有进程


nice改变优先级

nice -n -优先级数字 command

nice会阻止普通系统用户增加命令的优先级.



renice改变已经在运行的命令的优先级,通过进程pid

renice优先级数字 -p pid

只能对属于你的进程执行

只能通过renice降低进程的优先级,root用户没有限制


6:定时任务

at允许指定Linux系统何时运行脚本,at命令会将作业提交到队列中,at的守护进程atd会以后台模式运行.

at [ -f filename ] time

默认将标准输入放到队列,-f可以指定文件,time指定运行时间

可识别的时间格式:

标准的小时分钟格式,如02:44

~AM/~PM指示符,比如02:44~PM

特定可命名的时间,比如now,noon,midnight,teatime

如果指定了一个过去的时间,会在第二天该时间运行

还可以指定各种日期格式,或者时间增量


针对不同的优先级,存在26种不同的作业队列,使用小写字母a-z进行表示,作业队列字母排序越高,作业运行的优先级就越低

[-q]指定作业的队列


atq查看当前系统中哪些作业正在等待


atrm删除作业

[atrm作业号],只能删除自己提交的作业


7:定期执行

cron时间表

cron唯一问题是假定系统是7*24小时运行的


8:启动时运行




第三部分:高级shell脚本编程

第十六章:创建函数

1:创建函数

风格1

function name {commands}

风格2

name(){commands}

2:返回值

bash会吧函数当做一个小型脚本,运行结束后会有一个退出状态码.,三种方法可以为函数生成退出状态码.默认是函数中最后一条命令的退出状态码,这是很危险的.

1):使用return

return可以退出函数并返回特定的退出状态码.允许指定一个整数值定义函数的退出状态码,但是受到返回状态码限制,返回状态码不能超过255;


2):将函数的输出给变量赋值

a=`fun`,会将函数fun中的echo 输出赋值给a


3:函数中变量的使用

把函数当做一个脚本,如何给脚本传递参数,就如何给函数传递参数.,必须在使用函数的当时传递参数

1):函数中使用的变量类型:全局变量和局部变量

设置局部变量,使用 [local 变量名]

2):数组变量

不能把数组变量直接作为函数的参数

可用的方法是将数组打散作为参数,在函数内部进行组合

3)从函数返回数组,只要输出数组中的所有元素,再用一个变量接受函数赋值

4):函数递归


4:创建库

创建函数库文件,可以在多个脚本需要使用该功能时进行调用

调用库文件时,会在一个新的shell中,这就涉及到作用域的问题

使用source,会在当前上下文中执行,source可以使用[.]代替


5:命令行上创建函数

一行创建时必须每个命令结束时候使用分号,多行创建时不需要


6:在.bashrc文件中定义函数,这样,每次启动shell时候都会加载,不论交互式还是从现有的shell中启动一个新的shell

(1):直接定义函数

(2):读取函数文件,只要在shell脚本中都可以使用source或者点操作符来将已有的库文件加入到当前脚本中

(3):shell会将定义好的函数传给子shell进程,这样这些函数在该shell会话的任何shell脚本中都可以使用


第十七章:图形化桌面上的脚本编程

1:创建文本菜单

可以使用echo输出一些字符串,作为菜单,然后使用read读取用户的输入,根据输入执行对应的函数.

2:创建菜单函数

通常我们会为还没有实现的函数创建一个桩函数(没有任何命令或者只有echo语句说明的函数)

一般,可以将菜单布局本身作为一个函数来创建

如: function menu{

clear

echo

echo -e “\t\t sys admin menu”

echo -e “\t1. display disk space”

echo -e “\t2. display logged on  usage”

echo -e “\t3. display memory usag”

echo -e “\t0. exit program”

echo -en “\t\t  enter your option”

read -n 1 option

}


创建菜单布局可以使用select命令

select variable in list

do

commands

done

其中,list是菜单中要显示的字符串


第十八章:初识sed和gawk

1:文本处理

1):sed编辑器(流编辑器stream editor),数据的处理过程是按照行来读取的,对每一行都采用相同的一套定义的规则.

[sed options script file]

-e script在处理输入时,将script中指定的命令添加到运行的命令中

-f file处理输入时,将file中指定的命令添加到运行的命令中

-n 不要为每个命令生成输出,等待print命令来输出

sed命令不会修改原始文件,只是将修改后的文件显示在标准输出上

sed可以同时指定多个命令 如sed  -e ‘s/xxx/xxx/ ;s/xxx/xxx/’file,注意,命令之间必须使用分号间隔,命令末尾和分号之间不能有空格.

可以把多个命令写在一个文件中,使用echo -f scriptfile file


2):gawk,原始awk的GNU版本

提供了一种编程语言而不只是编辑器命令,在这种编程语言中,你可以:

定义变量来保存数据;

使用算数和字符串操作符来处理数据;

使用结构化编程概念,如if-then语句和循环为数据处理增加逻辑

提取数据文件中的数据元素并将他们按照另一顺序或格式重新放置,生成格式化报告

[gawk options program file]

-F fs指定行中分隔数据字段的字段分隔符

-f file指定读取程序的文件名

-v var=value 定义gawk程序中的一个变量及其默认值

-mf N 指定要处理的数据文件中的最大字段数

-mr N 指定数据文件中最大数据行数

-W keyword 指定gawk的兼容模式或者警告等级


<1>从命令行读取程序脚本

程序脚本使用一堆花括号定义,必须将脚本命令放到两个括号中.gawk命令行假定脚本是单个文本字符串,必须将脚本放到单引号中

ctrl+D会产生一个EOF字符

<2>使用数据字段变量

gawk会自动给每行中每个数据元素分配一个变量,默认情况下,变量分配如下:

$0代表整个文本行

$n代表第n个数据字段

数据字段通过字段分隔符进行划分.gawk默认的字段分隔符是任意空白字符(制表符,空格)

可以执行多个命令,中间使用分号隔开,如:gawk ‘{print $1;$2=”hell”}’ data

同样可以把命令写入文件再进行引用,gawk -f commandfile file

gawk可以设置变量,使用变量不需要使用美元符

<3>:在处理数据之前运行脚本

BEGIN会强制gawk在读取数据之前至执行BEGIN后面的第一个程序脚本,执行后直接退出 gawk ‘BEGIN{print “hello”}’

如果要继续执行处理脚本中的数据,继续使用脚本

gawk ‘BEGIN{xxx}{yyyy}’file  yyyy就是执行数据处理的脚本

同样,END用来指定其后的一个脚本是在数据处理结束后需要执行的


2:sed编辑器基础

(1):更多地替换选项

<1>替换标记

默认的替换只会替换每行出现的第一个匹配的字符

使用替换标记让替换命令对一行中不同地方出现的文本都起作用

4种替换标记

数字,表明新文本将会替换第几处模式匹配的地方

g,替换所有已有文本出现的地方

p,显示替换之后结果的行,习惯和-n(安静模式,不输出) 一起使用,

w file,将替换的结果写到文件中

sed ‘s/pattern/replace/标记’ file

<2>替换字符

sed编辑器允许其他字符作为substitute命令中的字符串分隔符:如使用感叹号

sed ‘s!pattern!replacement!’ file


(2)使用地址

默认sed中的命令会作用于文本数据的所有行,如果只想将命令作用于特定的某些行,需要使用行寻址

两种形式的行寻址:

行的数字范围

文本模式过滤出某行

两种形式都使用相同的格式指定地址

[address]command

address {commands}


sed ‘2,3s/pattrn/replace/’file行范围,只替换指定行的匹配的内容

2,$表示从第二行到结尾行


文本模式过滤器

/pattern/command

必须使用正斜线将要指定的pattern封起来.命令将只会作用在匹配的行

如:sed‘/qrs/s/bash/csh/’ /etc/passwd


(2):删除行

命令d为删除行的命令,如 sed ‘3d’data删除第三行

删除时需要谨慎,因为很可能会发生一些不想要的结果


(3):插入和附加文本

i指定行之前增加一个新行

a指定行之后增加一个新行

[不能在单个命令行上使用这两条命令,必须指定要将行插入还是附加到另一行]

sed ‘[address]command\’

new line

如: sed‘2i\test line’data将会在第二行数据之前插入指定的行


(4)修改行

格式同增加或者插入相同,命令为 c

如:sed‘3c\a chage line’data将会改变data的第三行内容为 a change line


(5)转换命令

唯一可以处理单个字符的sed编辑器命令,

[address]y/inchars/outchars/,inchars和outchars的长度需要一致,因为两者为字符一一映射

如:sed‘y/th/ht/’ data

不同于s命令,转换会对全行每一个匹配的内容进行操作


(6)打印

小写p命令打印文本行

等号打印行号

小写L用来列出行,将数据流中的文本和不可打印的ASCII字符进行显示,对于不可打印字符,使用它们的八进制值钱加一个反斜线或者标准C风格的命名法


3:sed和文件一起工作(利用sed对文件进行写操作

(1)向文件写入

[address]w file

无论采用数字寻址还是模式寻址都可以

执行命令的账户需要对file具有写权限,如果file之前不存在,将会创建

(2)从文件读取数据


r命令允许将一个独立文件中的数据插入到数据流中.

[address]r file

如sed‘3r data1’data2,将在data2的输出流第三行之后插入data1中的数据


第十九章:正则表达式

1:什么是正则表达式?

你所定义的,Linux用来过滤文本的模式模板

2:正则表达式不止一种类型,不同的应用程序可能会使用不同类型的正则表达式

正则表达式是用正则表达式引擎实现的,正则表达式引擎是解释正则表达式模式并使用这些模式进行文本匹配的底层软件

Linux中两种流行的正则表达式引擎

POSIX基本正则表达式(BRE)引擎

POSIX扩展正则表达式(ERE)引擎

正则表达式对大小写敏感

3:特殊字符

.*[]^${}\+?|()

不能在文本模式中直接使用这些字符,需要进行转义才能使用,用于转义的特殊字符是\

.用来匹配任意的单字符,除了换行符,点字符的位置必须要有字符,否则失效



4:锚字符

^定义了从数据流中文本行的行首开始的模式,必须将脱字符放在模式最前面

$锁定行尾,必须用在模式最后面

两个锚字符可以组合使用


5:字符组

匹配一组字符,需要用到方括号来定义匹配模式[ad]cc,将匹配acc 和 dcc出现的文本行


可以反转字符组的作用,寻找组中不存的字符,在字符组的开头加上脱字符,如[^xx]

使用区间,[0-9],[a-ch-s]等等


特殊字符组:

[[:alpha:]]匹配任意字母字符,无论大小写

[[:alnum:]]匹配任意字母和数字

[[:blank:]]匹配空格或者制表符

[[:digit:]]匹配0-9之间的数字

[[:lower:]]匹配小写字母

[[:print:]]匹配任意可打印字符

[[:punct:]]匹配标点符号

[[:space:]]匹配任意空白字符

[[:upper:]]匹配任意大写字母

这些特殊字符组可以直接用作sed命令的模式寻址中

*说明该字符会在匹配模式的文本中出现0次或者多次


7:扩展正则表达式

sed编辑器不能识别扩展正则表达式,gawk可以

下面是在gawk程序脚本中常见的ere模式符号

?表明前面的字符可以出现0次或者1次

+表明前面的字符至少出现一次

{n,m}指定前面的字符出现的次数的区间,使用区间,需要使用 --re-intrval选项

如gawk --re-interval‘/be{1}t/{print $0}’,匹配含有bet的行

字符组可以和这样的区间一起使用.

管道符|, reg1|reg2,如果任何一个模式匹配了数据流文本,文本就通过了


聚合表达式(xxx)称为聚合表达式,这一整个可以当做一个正常字符进行使用

聚合表达式可以结合管道符使用,功能更强大


第二十章:sed进阶

1:多行处理

sed默认是一行一行进行处理的,但是有时候会出现一个短语划分成两行

用于处理多行文本的特殊命令:

N:将数据流的下一行加进来创建一个多行组进行处理

D:删除多行组中的一行

P:打印多行组中的一行

(1):next命令

单行中的next命令

[通常sed编辑器会在移动到数据流中的下一行文本之前在这行上执行所有定义好的命令]

例如:一个五行文本,二四行是空行,现在要删除第二行,第一行中有字符 head ,可以使用

 sed ‘/head/{n,d}’ data


如果查找这样一段话:

the first meeting of the linux desktop

user’s group will be held on Tuesday.

All desktop users should attend this meeting.


sed ‘s/desktop user/linux/; N; s/desktop\nuser/linux’ file

可以完成替换功能


(2):多行删除命令

D只会删除模式空间中的第一行,删除到换行符(包括换行符)

(3)多行打印命令

P只会打印模式空间中的第一行


2:保持空间

模式空间是一块活动缓冲区,sed执行命令时会保存sed编辑器要校验的文本,但是它并不是sed编辑器保存文本的唯一空间

sed编辑器利用了另外一块缓冲区域,叫做保持空间.

保持空间的命令如下:

h将模式空间复制到保持空间

H将模式空间附加到保持空间

g将保持空间复制到模式空间

G将保持空间附加到模式空间

x交换模式空间和保持空间中的内容


3:排除命令

!在命令之前添加感叹号,可以取消一次命令的执行


4:改变流

(1):跳转命令b

[address]b [label]

address决定了哪些行的数据会触发跳转命令,label定义了要跳转的位置,没有label,就会跳转到脚本结尾,也就是不执行后面的命令

sed ‘{/first/b jump1;s/x/y/;:jump1;s/k/f/}’file,单匹配到first所在的行时,将会跳转到那一行,执行jump1之后的命令

(2):测试命令t

基于替换命令的输出跳转到一个标签,而不是基于地址跳转到下一个标签

[address]t [label]

没指定标签,测试成功会跳转到脚本结尾jiaoben


5:模式替代

(1):and符号&,用来代替替换命令中的匹配模式,会替换整个匹配模式

当文本中出现了匹配的内容时,保持问文本中所匹配的原本的单词

echo "the cat sleeps in the hat" | sed 's/.at/*&*/g'

the *cat* sleeps in the *hat*

(2):替换单独的单词

sed编辑器用圆括号定义替换模式的子字符串,之后可以用替代模式中的特殊字符引用每个子字符串.

替代字符[\+数字],将匹配模式进行部分替换


6:脚本中使用sed

(1):使用包装脚本

就是将sed命令写在脚本中,这样就可以不用重复编写,这样的脚本称为包装脚本

(2):重定向sed脚本

将sed命令的的输出赋值给一个变量,就可以了


7:创建sed实用脚本

(1)加倍行间距,利用保持空间默认有一个空行

sed ‘$!G’file将在file文件中每一行之间插入一个空行

(2)对可能含有空白行的文件加倍行间距

先删除空白行,再增加空白行

sed ‘/^$/d;$!G’ file]

[sed读取每一行,对每一行执行一遍命令,在读取下一行之前,将会清空模式空间]

(3)给文件中的行进行编号

sed ‘=’ file | sed ‘N;s/\n/ /’将在行号后面写上行的内容,而不是行号后换行再显示

(4)打印末尾若干行

利用滚动窗口,也就是一个循环,不断地向模式空间中增加数据行,超过一定值将第一行删除

sed ‘{:start;$q;N,11,$D}’ file

(5)删除行

删除数据流中不需要的空白行.

<1>:删除连续的空白行

/./,/^$/!d实际上是保留一行内容和空行

<2>删除开头的空白行

/./,$!d

<3>删除结尾的空白行

{:ss;/\n *$/{$d;N;b ss}}

(6)删除html标签

sed ‘s/<[^>]*>//g;/^$/d’ htmlfile


第二十一章:gawk进阶

1:使用变量

(1)内建变量

内建变量用来引用程序数据中的一些特殊功能.

<1>:字段和数据行分隔符字段

FIELDWIDTHS空格隔开的定义了每个数据字段确切宽度的一列数字

FS输入字段分隔符 OFS 输出字段分隔符

RS输入数据行分隔符 ORS 输出数据行分隔符

默认FS, OFS为空格

当指定FIELDWIDTHs时,gawk就会忽略FS变量,根据你设定的宽度大小进行字段的划分

gawk ‘BEGIN{FIELDWIDTHS=”3 5 2 2”} {print $1.$2.$3.$4}’,


默认RS,ORS为换行符,同样可以进行修改

<2>数据变量

很多,man gawk可以进行查看

ARGC当前命令行参数个数

ARGV当前命令行参数数组

ENVIRON[“sehll环境变量”]提取shell的环境变量

NF当前数据行中的字段总数

FNR当前数据文件中数据行数

NR已处理的数据行数

gawk '{print $0,"NF="NF,"NR="NR,"FNR="FNR}' file file

this is first line  NF=4 NR=1 FNR=1

this is second line  NF=4 NR=2 FNR=2

this is third line  NF=4 NR=3 FNR=3

this is forth line NF=4 NR=4 FNR=4

this is fifth line NF=4 NR=5 FNR=5

this is first line  NF=4 NR=6 FNR=1

this is second line  NF=4 NR=7 FNR=2

this is third line  NF=4 NR=8 FNR=3

this is forth line NF=4 NR=9 FNR=4

this is fifth line NF=4 NR=10 FNR=5


(2)自定义变量

<1>给变量赋值

gawk ‘BEGIN{a=”this is a”;print a}’

变量类型自动确认,可以进行数学计算

<2>命令行上给变量赋值

可以将脚本代码写在文件中,-f指定文件,并且输入参数

gawk -f script x=x file

值在BEGIN的代码中不可用,需要在指定脚本之前执行-v

gawk -v x=x -f script file


2:处理数组

gawk采用关联数组,它的索引值可以是任意文本字符串

(1)定义数组变量

var[index] = element

如arr[“hello”] = “hello world”

(2)遍历数组

for (var  in  array)

{

statements

}

注意:var是索引值而不是元素值,并且不是按照顺序的

(3)删除数组变量

delete array[index]将会从数组中删掉关联索引值和相关的数据元素值


3:使用模式

BEGIN和END就是特殊的模式

(1)正则表达式

gawk ‘/pattern/{commands}’ file

正则表达式必须出现在它要控制的程序脚本左花括号之前

�j�݃�1

你可能感兴趣的:(linux命令行和shell编程大全 学习笔记)