Linux-《Linux命令行与shell脚本编程大全》阅读笔记

1.内核负责的主要功能

  系统内存管理、软件程序管理、硬件设备管理、文件系统管理

2.GNU工具链

  Linux内核是系统的核心,控制着内存、程序和硬件等是如何与对方交互的。内核还需要工具链来执行一些标准功能,比如控制文件、文本和进程等。

3.terminfo数据库

  Linux需要知道你模拟的哪个终端,及在和终端模拟器通信时使用哪些控制码,terminfo数据库是一组文件,系统将每种终端类型的terminfo数据作为单独文件存储在terminfo数据库目录(随发行版不同而不同,有可能为/usr/share/terminfo、/etc/terminfo、/lib/terminfo)。特定终端的单独文件被存储在其名称对应的字母目录下,比如/usr/share/terminfo/v里是VT终端模拟器

4.大多数Linux发行版默认shell都是 GNU bash shell,能够提供对Linux系统的交互式访问,它是作为常规程序运行的,通常都是在用户登录终端时启动。登录时启动的shell依赖于用户账户的配置(/etc/passwd每行的最后一列为启动时默认的shell)。

5.硬链接相当于变量别名(有相同的索引节点号,inode 文件元数据和 block 文件内容使用同一个),一改全改,但是删除一个,另一个还可以访问;软链接相当于快捷方式,当目标文件删除时,快捷方式失效。

6.启动bash shell有3中方式:

  1).登录时当做默认登录shell

  2).作为非登录shell的交互式shell

  3).作为运行脚本的非交互shell

7.用户管理命令useradd,userdel,usermod,passwd,chsh;用户组管理命令groupadd,groupdel,groupmod

8.useradd -D 查看添加用户时的默认配置信息,后跟参数可以修改系统默认配置信息

$ useradd -D
GROUP=100 #用户所属组
HOME=/home #用户家目录所在目录
INACTIVE=-1 #账号密码过期后是否禁用此用户
EXPIRE= #过期时间
SHELL=/bin/bash #用户登录后的默认shell
SKEL=/etc/skel #系统会将/etc/sekl目录下的文件复制到用户home目录下
CREATE_MAIL_SPOOL=yes #是否为用户创建一个用于接收邮件的文件

  修改参数

  比如

useradd -D -s /bin/tsch

9./etc/passwd,/etc/shadow,/etc/group

10.sudo

  用来以其他身份来执行命令, 预设的身份为root, 在/etc/sudoers中设置了可执行sudo指令的用户, 若其未经授权的用户企图使用sudo, 则会发出警告的邮件给管理员, 先输入密码, 之后有5分钟的有效期限, 超过期限则必须重新输入密码

  配置sudo必须通过编辑/etc/sudoers文件, 而且只有超级用户才可以修改它, 还必须使用visudo命令编辑, 之所以使用visudo有两个原因, 一是它能够防止两个用户同时修改它, 二是它也能进行有限的语法检查, 所以, 即使只有你一个超级用户, 你也最好用visudo来检查一下语法

11.read, 如果输入个数多于指定变量的个数, 最后一个指定变量将存放剩余所有输入, 如果没有指定变量, 则把输入存放到 REPLY 全局变量

  -p 指定打印

  -t 设定超时时间

  -s 是否隐藏输入

12.当使用重定向符号时, Linux会用重定向指定的文件描述符来替换原有文件描述符

13.大多数Linux操作系统在重启时会自动删除/tmp中的所有文件

14.所有账户都有权限在/tmp文件夹中读写, 而且不用管理清除

15./etc/cron.*ly 如果不精确的定时执行, 可以把执行文件放在其目录中, 比如 cron.dayly 目录, 其内文件每天执行一次

16.

  boot的含义,boot是bootstraps(鞋带)的缩写,启动就好像拎着鞋带把自己提起来那么纠结(Pull oneself up by one's bootstraps),必须先运行程序,然后计算机才能启动,但是计算机不启动就无法运行程序

  按下电源

  BIOS(Basic Input/Output System,是存储在ROM(Read Only Memory)上的一段程序)系统通电自检(Power-On Self-Test即POST)

    1.会检查各种硬件是否正常,比如内存松动就会报错无法启动,如果没有问题,屏幕就会显示出CPU、内存、硬盘等信息

    2.根据我们在BIOS中设置的系统启动顺序(比如Windows中BIOS系统中设置磁盘/CD/DVD/...为第一启动)把控制权转交给排在第一位的储存设备,计算机读取该设备的第一个扇区,也就是读取最前面的512个字节。如果这512个字节的最后两个字节是0x55和0xAA,表明这个设备可以用于启动;如果不是,表明设备不能用于启动,控制权于是被转交给"启动顺序"中的下一个设备,这最前面的512个字节,就叫做"主引导记录"(Master boot record,缩写为MBR)

    3.就会将MBR内容复制到0×7c00地址所在的物理内存中。其实被复制到物理内存的内容就是Boot Loader,而具体到你的电脑,那就是lilo或者grub了,以下以grub为例

  启动内核,grub会解析grub的配置文件/boot/grub/grub.conf,然后加载内核镜像到内存中,并将控制权转交给内核

  

init进程,是一个由内核启动的用户级进程,内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。所以,init始终是第一个进程(其进程编号始终为1)。会读取/etc/inittab文件获取运行级别

  rc.d: run control directory

  最先运行的服务是放在/etc/rc.d 目录下的文件

17.sed(stream editor)被称作流编辑器,与文本编辑器(比如Vim)不同,不是以键盘命令来交互式的插入、删除或替换数据中的文本,而是基于预先提供的一组规则来编辑数据流。

  《用法实例

  sed编辑器每次从输入中读取一行,用提供的编辑器命令匹配数据、安命令中制定的方式修改流中的数据,然后将生成的数据输出到STDOUT,在流编辑器将所有命令与一行数据进行匹配完成后,会读取下一行数据并重复这个过程。sed只支持基本正则表达式(BRE)、而不支持扩展正则表达式(ERE,有"问括花管加")。

  sed不是在原输入上直接进行处理的,而是先将读入的行放到缓冲区中,对缓冲区里的内容进行处理,处理完毕后也不会写回原文件(除非用shell的输出重定向来保存结果),而是直接输出到屏幕上。sed运行过程中维护着两个缓冲区,一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“暂存缓冲区(holding space)”。一般情况下,每当运行sed,sed首先把第一行装入模式空间,进行处理后输出到屏幕,然后将第二行装入模式空间替换掉模式空间里原来的内容,然后进行处理,以此类推。 一般情况下暂存缓冲区是用不到的,但有特殊的命令可以在模式空间与暂存缓冲区之间交换数据(H命令把模式空间里的内容追加到暂存缓冲区 ,以用x命令将暂存缓冲区的内容交换至模式空间,从而打印出来)。由于sed对文本的所有操作都是在缓冲区里进行的,所以不会对原文件造成任何破坏。

sed options script file

  option script 由 "地址范围 + 操作" 组成

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

  -n 不打印,通常与 p 命令配合使用,可以调用p命令打印匹配行。默认情况下,sed每读入一行到模式空间,无论是否对其进行处理,在读入下一行之前多要将模式空间中的内容输出到屏幕上,如果使用 p 而未用 -n 则会打印两个相同的行。

  -e 可用于同时执行多个 script,如 sed -e '1,5d' -e 's/test/check/' file.txt。其实若想执行多条命令,也可匹配到行后,使用 {} 包含多个命令即可,效果与 -e 一致。如 sed '/NR/{s/=/+/;s/1/2/;}' file.sh。

  script 可以使用单引号,也可以使用双引号,但是如果 script 想使用外部变量,则只能使用双引号,如 echo hello WORLD | sed "s/$test/HELLO"

#s替换(substitute)
#d删除(delete)
#c更换(change)
#y转换(transform)
#i\添加(insert),添加到匹配行上
#a\添加(append),添加到匹配行下 #p打印(print)
#q退出(quit),不再继续处理后面的行
#n切换到下一行,清空sed编辑器的工作空间,将数据流中的下一文本行移动到其中,空间中只保持一行(next)
#N多行处理命令,不清空sed编辑器的工作空间,把数据流中的下一行文本添加到空间中,会把将两行当做一行进行处理(但是两行之间依旧有 \n 换行符)
#D多行删除命令,在多行时,只删除空间中的匹配行 sed '/^${N; /header/D}' filename
#P多行打印命令,在多行时,p只打印多行工作空间中的第一行,P打印多行
#h将模式空间复制到保持空间(hold space)
#H将模式空间附加到保持空间
#g将保持空间复制到模式空间
#G将保持空间附加到模式空间
#x交换模式空间和保持空间的内容 sed -n '/first/{h;p;n;p;g;p}'
#r读取文件(read),如 sed '/test/r file.txt' filename.txt,遇到匹配行时,读取 file.txt 追加到匹配行之后 #w写入文件(
write),如 sed -n '/test/w file.txt' filename.txt,遇到匹配行时,将匹配行写入到 file.txt
#l打印不可见字符(list)
#寻址方式(address) #
"行号", $表示末尾行 #"行号,行号" #"/匹配行/" #"/匹配行/,/匹配行/"
#"行号,/匹配行/" #插入以下的i可以更改为a,i、a分表表示address前和后插入 #[address]i\newline #删除 #[address]d #修改行 #[address]c\newline #多行时会合并为一行newline #替换行 #[address]s/oldchars/newchars/ #转换行 #[address]y/inchars/outchars/ #指定行多命令模式 #[address]{command1; command2; command3}

#对匹配行的下一行进行操作
#[address]{n;d} #删除匹配行的下一行

#对匹配行和下一行进行操作,即当成一行来处理
#[address]{N;s/\n/ /} #合并匹配行和下一行
#sed 'N;s/System.Administrator/Desktop User/' filename #查找和替换被分隔成两行的两个单词

#每行多命令模式
#-e 'command1; command2'

#向文件写入
#[address]w filename

#从文件中读取,其中address只能是行号或者匹配,不能是范围
#[address]r filename #注意是单引号,注意最后的
"/" echo "This is the test" |sed 's/test/big test/' #多条命令用 -e 选项,并且用 ";" 隔开 echo "This is the test" |sed -e 's/This/That/; s/test/big test/' #从文件中读取命令 echo "This is the test" |sed -f 'mysed.script' #处理指定数量行 echo "This is the test" |sed '1s/test/big test/' #处理指定匹配行 echo "This is the test" |sed '/test/s/test/big test/' #在单行上执行多条处理命令 echo "This is the test" |sed "1{s/This/That/; s/test/big test/}" #删除行 sed 1d filename #删除1行 sed 2,3d filename #删除2-3行 sed 6,$ filename #删除从6行到结尾行 sed /test/d filename #删除匹配行 sed /test1/,/test2/d filename #删除两个匹配行之间的行 #添加行 echo 'aaaaa' |sed 'i\bbbbb' #在前插入一行 注意此处是反斜线 echo 'aaaaa' |sed 'a\bbbbb' #在后插入一行 sed '3i\bbbbb' filename #在第3行前插入一行 sed '3a\bbbbb' filename #在第3行之后插入一行 sed '$i\bbbbb' filename #在最后一行之前插入一行 sed '$a\bbbbb' filename #在最后一行之后插入一行

#替换
echo 'abcdabcdabcd' |sed 's/a/xxx/' #只替换第一个
echo 'abcdabcdabcd' |sed 's/a/xxx/2' #只替换第二个
echo 'abcdabcdabcd' |sed 's/a/xxx/g' #全部替换
echo 'abcdabcdabcd' |sed 's/a/xxx/2g' #从第二个开始全部替换
echo 'abcdabcdabcd' |sed 's/bc/&cb/' #替换为 bccb,&代表原值
echo 'abcdabcdabcd' |sed 's/\(bc\)/\1cb/' #替换为 bccb,\1代表第一个括号内容
#修改行 sed '3c\This is a changed line of text' filename #把文件的第三行修改为如上内容 sed '/test/c\This is a changed line of text' filename #把文件中所有能匹配"test"的行替换为如上内容 sed '2,3c\This is a new line of text' filename #把2~3行替换为一行如上内容 #转换 sed 'y/123/789/' filename #把文件中每一行中1、2、3分别转换为7、89 #打印指定行 sed -n '2,6p' filename sed -n '/3/{p; s/line/test/p}' filename #含有数字3的 #打印行,并且列出不可打印的ASCII字符 sed -n 'l' filename #This\tline\tcontains\ttabs.$ #向文件中写入 [address]w filename sed '2,3w mydata.txt' filename #从文件中读取 [address]r filename sed '3r mydata.txt' filename

18.awk 提供一个类编程环境,修改和重新组织文件中的数据,它提供了一种编程语言而不只是编辑器命令,相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题

awk options program file

  option program 格式为 "BEGIN{xxx}expr{xxxx}expr{xxx}...END{xxx}"

  -F 指定分隔符

  -v var=value 将外部变量传入,也可以直接使用 '$varname',注意变量外必须带上单引号!

  -f 将file中制定的命令添加到运行的命令中

  变量: $0表示本行数据,$1表示第一个字段,也可以修改,如下:

echo "My name is Rich" | awk '{$1="Chinese"; print $1;}'
awk options 'BEGIN{...}pattern{...}END{...}' file
  '  '          引用代码块
  BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
  模式分为三种,既能当匹配条件,也能当执行条件:
    1).正则表达式匹配 /xxx/
    2).关系表达式 条件操作符<、<=、==、!=、>=
    3).模式匹配表达式 ~匹配正则表达式、!~不匹配正则表达式
匹配:awk '{if ($4~/ASIMA/) print $0}' temp 表示如果第四个域包含ASIMA,就打印整条
精确匹配:awk '$3=="48" {print $0}' temp    只打印第3域等于"48"的记录,防止字符串与变量混淆,字符串使用""
不匹配:  awk '$0 !~ /ASIMA/' temp      打印整条不包含ASIMA的记录
不等于:  awk '$1 != "asima"' temp
小于:    awk '{if ($1<$2) print $1 "is smaller"}' temp
设置大小写: awk '/[Gg]reen/' temp      打印整条包含Green,或者green的记录
任意字符: awk '$1 ~/^...a/' temp    打印第1域中第四个字符是a的记录,符号’^’代表行首,符合’.’代表任意字符
或关系匹配: awk '$0~/(abc)|(efg)/' temp   使用|时,语句需要括起来
AND与关系:  awk '{if ( $1=="a" && $2=="b" ) print $0}' temp
OR或关系:   awk '{if ($1=="a" || $1=="b") print $0}' temp
  {}           命令代码块,包含一条或多条命令
  ;          多条命令使用分号分隔
  END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
 
  $0           表示整个当前行
  $1           每行第一个字段
  NF          字段数量变量
  NR          每行的记录号,多文件记录递增
  FNR        与NR类似,不过多文件记录不递增,每个文件都从1开始
  \t            制表符
  \n           换行符
  FS          BEGIN时定义分隔符
  RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
  ~            匹配,与==相比不是精确比较
  !~           不匹配,不精确比较
  ==         等于,必须全部相等,精确比较
  !=           不等于,精确比较
  &&      逻辑与
  ||             逻辑或
  +            匹配时表示1个或1个以上
  /[0-9][0-9]+/   两个或两个以上数字
  /[0-9][0-9]*/    一个或一个以上数字
  FILENAME 当前处理的文件名
  ARGIND 当前处理的文件的顺序编号( awk 'xxxx' file1 file2)
  ARGV 类似 C 中的 argv,ARGV[n] 表示第 n 个参数
  OFS      输出字段分隔符, 默认也是空格,可以改为制表符等
  ORS        输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
  -F'[:#/]'   定义三个分隔符
 
  next 直接执行下一行循环
#只会打印偶数行(没有用if)
awk 'NR%2==1{next}{print NR,$0;}' text.txt 
  getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入,它负责从输入获得下一行的内容,并给NF,NR和FNR等内建变量赋值。
awk 'BEGIN{ "date" | getline out; print out }' test

  输出重定向

echo | awk '{print ("hello word!n") > "datafile"}'echo | awk '{printf("hello word!n") >> "datafile"}'
#注意:重定向符号后面的文件名必须带上双引号,因为awk类型中是字符串
awk '{print > "file"}' file

  把shell中的变量带入awk中执行

a=10
awk 'BEGIN{print '$a'}'

  把 /etc/passwd 中的第二列 "x" 改为 /etc/shadow 中的用户密码

awk 'BEGIN{OFS=FS=":"}NR=FNR{a[$1]=$2}NR>FNR{$2=a[$1]; print}' /etc/shadow /etc/passwd

  continue,break 用于 for in,for,while 等循环

  exit 语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。   

  a in array,判断 a键名是否在array中

  字符串函数:sub、gsub、lenth、index、match、split、substr、tolower、toupper、sprintf

  时间函数:systime()、mktime(YYYY mm dd HH MM ss)、strftime(format[, timestamp])

19.后台任务

  后台任务有两个特点:

    1.继承当前 session (对话)的标准输出(stdout)和标准错误(stderr),因此,后台任务的所有输出依然会同步地在命令行下显示

    2.不再继承当前 session 的标准输入(stdin),你无法向这个任务输入指令了,如果它试图读取标准输入,就会暂停执行(halt)

  可以看到,”后台任务”与”前台任务”的本质区别只有一个:是否继承标准输入,所以,执行后台任务的同时,用户还可以输入其他命令

  Linux系统是这样设计的:

    1.用户准备退出 session

    2.系统向该 session 发出SIGHUP信号

    3.session 将SIGHUP信号发给所有子进程

    4.子进程收到SIGHUP信号后,自动退出

  上面的流程解释了,为什么”前台任务”会随着 session 的退出而退出:因为它收到了SIGHUP信号

  那么,”后台任务”是否也会收到SIGHUP信号?  这由 Shell 的huponexit参数决定的

shopt |grep huponexit

  大多数Linux系统,这个参数默认关闭(off),因此,session 退出的时候,不会把SIGHUP信号发给”后台任务”,所以,一般来说,”后台任务”不会随着 session 一起退出

  通过”后台任务”启动”守护进程”并不保险,因为有的系统的huponexit参数可能是打开的(on),更保险的方法是使用disown命令,它可以将指定任务从”后台任务”列表(jobs命令的返回结果)之中移除,一个”后台任务”只要不在这个列表之中,session 就肯定不会向它发出SIGHUP信号

# 移出最近一个正在执行的后台任务
$ disown

# 移出所有正在执行的后台任务
$ disown -r

# 移出所有后台任务
$ disown -a

# 不移出后台任务,但是让它们不会收到SIGHUP信号
$ disown -h

# 根据jobId,移出指定的后台任务
$ disown %2
$ disown -h %2

  使用disown命令之后,还有一个问题,那就是,退出 session 以后,如果后台进程与标准I/O有交互,它还是会挂掉,这是因为”后台任务”的标准 I/O 继承自当前 session,disown命令并没有改变这一点,一旦”后台任务”读写标准 I/O,就会发现它已经不存在了,所以就报错终止执行,为了解决这个问题,需要对”后台任务”的标准 I/O 进行重定向

python test.py>result 2>&1

  还有比disown更方便的命令,就是nohup

  nohup命令会对进程做三件事

    1.阻止SIGHUP信号发到这个进程

    2.关闭标准输入,该进程不再能够接收任何输入,即使运行在前台

    3.重定向标准输出和标准错误到文件nohup.out。

  也就是说,nohup命令实际上将子进程与它所在的 session 分离了,但是,nohup命令不会自动把进程变为”后台任务”,所以必须加上&符号

  另一种思路是使用 terminal multiplexer (终端复用器:在同一个终端里面,管理多个session),典型的就是 Screen 命令和 Tmux 命令,它们可以在当前 session 里面,新建另一个 session,这样的话,当前 session 一旦结束,不影响其他 session,而且,以后重新登录,还可以再连上早先新建的 session

  除了专用工具以外,Linux系统有自己的守护进程管理工具 Systemd ,它是操作系统的一部分,直接与内核交互,性能出色,功能极其强大,我们完全可以将程序交给 Systemd ,让系统统一管理,成为真正意义上的系统服务

查看环境变量

env

系统提示符变量

PS1

查看当前内存详细信息

cat /proc/meminfo

查看文件类型

file filename

查看文件详细信息

stat filename

a

posted on 2015-08-31 11:06  John_ABC  阅读(529)  评论(0编辑  收藏  举报

导航