【笔记总结】Unix命令汇总_unix命令大全-程序员宅基地

技术标签: linux  vim  # 计算机知识归纳  unix  

1&2 Unix操作系统


1-计算机主板及结构

PC机的主板与结构

组成: 北桥/南桥、CPU、RAM、USB插槽、PCI插槽、SATA接口
结构:
结构

2-Unix的特点

  • 可移植
  • 多用户
  • 多任务
  • 分级系统
  • 与设备独立的输入和输出操作
  • 用户界面shell
  • 一系列系统工具

3-Unix的发展历程

Linux是Unix的克隆,但不是Unix

3 Unix入门


1-登录与退出

登录:

login:username
password:*******//不会显示

修改密码:passwd

新旧口令要求至少3个字符不同

至少长6个字符且要有两个字母一个数字

口令不能与用户标识相同

退出:[Ctrl+d]或exit

2-常见命令格式

【$ 命令 -选项 参数】
命令名要求小写,可以是一个可执行程序、脚本程序、shell内置程序等
- 字符
-- 单词

3-基本命令

日期和时间:date

用户信息:who

who am i //我登录的情况
who -q 或 --count //只显示用户名和用户数量
who -H 或 --heading //显示Header
who -b //显示系统的启动日期和时间(boot)

日历:cal

cal //当前年月
cal 2020
cal 3 2020
/*cal 10: wrong*/

4-帮助

learn help man (manual)

分卷、分节:卷节

man 3 printf //3指明查找的卷号

4-shell种类

字符界面下,用户登录系统后,由shell负责与用户交互

  • sh
  • ksh
  • csh
  • bash
  • dash

安装dash:

su

apt install dash

切换shell:

dash

chsh //改变登录的缺省shell(change shell)

用户的相关消息记录在/etc/passwd

cat /etc/passwd //查看

5-登录与退出过程

Unix系统启动后,int/systemd进程负责拉起用户进程
登录与退出

考察:

ps //打印系统当前进程
ps -ejH //按树形结构打印

init进程是1号进程,systemd=init,是所有进程的父进程

agetty=getty

A fork B,AB一样,但B是由A创建的

B exec login B执行login程序

6-其他

[ctrl-h]删除一个字符

[ctrl-u]删除整个命令行

[del][ctrl-c]中断运行

4 Vi编辑器入门


1-编辑器基础知识

编辑器是用于制作文档或文本的程序
eg.文档:word
文本:vscode sublime atom

  • 图形化文本编辑器
  • 字符界面文本编辑器
    • 行编辑器
      全屏编辑器
    • vi/vim(全屏)
    • emacs(行)
    • nano

2-vi编辑器

启动:vi或view(只读) 可加参数(文档名)
工作模式

  • 命令模式
  • 插入模式
  • 命令行模式
  • visual模式

状态行(第24行)
状态切换

退出:q!
升级版vi:vim
安装:

su  
apt install vim

3-vi编辑器基本命令

  1. 切换模式
    默认进入命令模式,按ZZ从命令模式退出程序;
    :进入命令行模式,回车退出到命令模式,按:q!/:wq/q退出程序;
    从命令模式进入文本模式:

    • i 在光标前插入文本
    • I 在光标所在行首插入文本
    • a 在光标后加入文本
    • A 在光标所在行尾插入文本
    • o 在光标所在行下增加一行
    • O 在光标所在行上增加一行

    ESC退出到命令模式;

  2. 创建和编辑文件:vi+文档名

  3. 移动光标:命令模式下

    • h j k l 左下上右,不会正文回绕
    • 0/^ 行首,不会正文回绕
    • $ 行尾,不会正文回绕
    • w 向后移动一个word,会正文回绕
    • b 向前到word开头,会正文回绕
    • e 向后到word尾部,会正文回绕
    • 空格 向后一格
    • 回车 下一行行首,不会正文回绕
    • 退格 向前一格

    文本输入模式

    • 空格 插入一个空格
    • 回车 新建一行
    • 退格 回退一格
  4. 插入文本:即由命令模式输入i I a A o O字符进入输入模式

  5. 删除文本:命令模式下

    • x 删除光标所在字符 (5x删除5个字符)
    • dd 删除光标所在行 (3dd删除3行)
    • u 撤销最近修改
    • U 撤销当前行所有修改
    • r 替换光标所在字符
    • R 替换从光标开始的字符,++进入输入模式++
    • . 重复上次修改
  6. 搜索文本:命令模式下

    • / 向后搜索
    • ? 向前搜素
    • n 按搜索方向搜索下一个匹配项
  7. 保存文本:

    • :wq 保存后退出
    • :q 未修改退出
    • :q! 不保存退出
    • :w 保存不退出,后面加文件名可另存为一个新文件
    • ZZ 保存后退出
  8. 帮助:命令模式下(冒号进入命令行模式)
    :help x 搜索命令模式下的x命令
    :helpgrep 以grep方式搜索
    help中按ctrl+[可以跳转至对应章节
    :q!退出help

    vimtutor:vi教程
    $ vimtutor进入

作业:阅读vim :help
作业:使用vimtutor练习

4-vi缓冲原理

VI缓冲

5 文件系统介绍


1-磁盘与文件

磁盘上的数据以文件形式组织
文件是操作系统对io设备的一个抽象,进程/线程是对执行过程的抽象
文件分类:

  • 普通文件:文本、脚本、程序
  • 目录文件:目录以树的形式组织文件,本身是一个文件
  • 特殊文件:io设备等

目录结构以层次形式组织,称为层次结构

2-目录与文件

  1. Unix重要的目录
    • / 根目录
    • /usr 用户目录,可能是/home
    • /usr/include 库头文件位置
    • /usr/bin 用户可执行文件
    • /usr/local 自行编译安装目录
    • /root 管理员目录
    • /boot 自举目录
    • /bin 可执行文件
    • /dev 设备文件
    • /sbin 管理程序目录
    • /etc 配置文件目录
    • /home 用户目录
    • /var 常变动文件,如数据库、日志
  2. 正在使用的目录:工作目录或当前目录
  3. 绝对路径:从是以/开头,从根目录开始,相对路径:从当前目录开始直到文件,开头不会是/
    注:dos下用\
  4. .当前目录 ..父目录
  5. 文件命名规范
    • 避免使用:<>,(),[],{},*,?,",',-,$,^
    • 使用扩展名提升可读性
    • 大小写敏感,目录和文件可以同名,不同目录下文件可同名

3-目录操作

  1. pwd 打印当前工作目录的绝对路径

  2. cd 改变当前工作目录(缺参数默认回到主目录)

    • cd - 返回上次工作目录
    • cd ~ 返回主目录
  3. mkdir 创建目录

    • mkdir -p xx/yy/zz 创建多层目录
  4. rmdir 删除目录

    • 空目录无法删除
    • 要在父目录或更高层的目录下才可删除子目录
  5. ls 打印目录下的子目录与文件(缺参数默认打印当前目录)

    • ls -a 打印含隐藏文件的所有文件
    • ls -C 列排序
    • ls -x 行排序
    • ls -F 目录后加/,可执行文件后加*
    • ls -p 目录后加/
    • ls -l 详细信息
    • ls -m 按页宽列出文件,逗号隔开
    • ls -r 反字母顺序
    • ls -R 循环列出子目录内容
    • ls -s 按块为单位列出文件大小
  6. 注意:
    (1) 多重选项 eg.ls -alr ls -a -l -r
    (2) ls-l的结果分析:
    文件类型:-普通文件、d目录、c字符设备(打印机)、b块设备(磁盘)、I符号连接
    权限:r读、w写、x执行(文件)或访问(目录)、-无权限
    人物:文件所有者、同组用户、其他用户
    链接数、创建人、组名、文件大小、日期时间、文件名
    (3) 隐藏文件:以.开头的文件,排序是按去点后的字母顺序排序

4-文件操作

  1. cat 显示文件(创建和连接)

    • cat file1 显示当前目录中的file1
    • cat file1 file2 相继显示当前目录中的file1、file2
    • 显示最后23行,其他内容上翻过去了。
      停止上翻Crtl-s,继续上翻Ctrl-q
  2. touch 创建一个空文件

  3. lp 打印文件

    • 未指定文件名时打印键盘输入内容,Ctrl-d结束键盘输入
    • lp -d 打印机 文件名 指定打印机打印
    • lp -m 打印完发送邮件
    • lp -n 打印指定份数 eg.lp -n5
    • lp -s 取消反馈信息
    • lp -t 字符串 文件名 在输出标题页上打印指定标题(第一页)
    • lp -w 打印完成向终端发送消息
    • lpr Lunix命令
  4. cancel 取消打印文件

    • 指定打印机(只取消正在打印的作业,其余仍进行)或打印作业Id名
  5. lpstat 获取打印机消息

    • lpstat -d 找出系统默认打印机
  6. rm 删除文件

    • rm -i 删除前给出确认消息(y确认n取消)
    • rm -r 删除指定目录下所有子目录和文件
    • rm -r *删除从工作目录开始的所有目录和文件
    • rm -f 忽略不存在文件且不给提示

6 VI高级用法


1-vi的启动选项

  1. vi是ex编辑器得一部分,:Q切换到ex编辑器;q退出回到shell;vi回到vi。
  2. 不提供文件名启动vi(新建文件)
vi 
:w myfile(文件名)
:wq myfile(文件名)

注意:不可覆盖同名已存在文件,:w!强制覆盖。

vi myfile
:w yourfile(新文件名) //保存到新文件,编辑文件仍为myfile
:wq yourfile(新文件名) //保存到新文件,原文件不变
  1. 启动选项:
    • -R只读
      • 但可以通过:wq!强制保存用户自己的只读文件,系统文件不可强制更改。
      • view模式
    • -c 允许用户将指定的vi命令作为命令行一部分
      如:$ vi -c /most myfile搜索most移动光标至第一个most处

2-多文件编辑

  1. vim内部每个buffer打开一个文件,多个buffer可以打开同一个文件
    可以只有一个窗口,也可以有多个tab标签。每个tab对应一个buffer,一个buffer可以对应多个tab。
  2. 启动时给出多个文件名,编辑完一个后自动进入下一个
    • :n 打开下一个文件
    • :n! 不保存当前文件打开下一个
    • :ar 查看文件名列表
    • :e +文件名编辑另一个文件
    • :r 引入另一个文件内容到当前文件光标后一行
    • :5 100 w newfile 将当前文件的5~100行写入新文件中(w!可以覆盖同名已存在文件)
  3. 每个buffer开一个文件、多个buffer可以打开同一文件,编辑会同步展示。(缓冲区)
    可以只有一个窗口,也可以有多个tab标签。每个tab对应一个buffer,一个buffer可以对应多个tab。(窗口)
  4. 这里描述的vim使用方式,是希望能在vim中完成大多数工作,而不是频繁的退出vim。
    • :tabnew 创建一个标签
    • :e 打开一个文件 //:o也可以
    • :tabnext 在窗口上打开下一个tab
    • :tabprevious 在窗口上打开前一个tab
    • :q或者:tabclose 关闭tab
  5. 设置tab标签快捷键(自定义)
nnoremap<C-Left>:tabprevious<CR>
nnoremap<C-Right>:tabnext<CR>
nnoremap<Tab>:tab sball<CR>

3-寄存器

vim中设计了特别的暂存机制——寄存器,用于保存拷贝和删除的文本
在命令模式下:以 " 双引号开头 引用这些寄存器
命令行模式:registers或:reg显示寄存器
eg.:reg "1 :reg 1:查看寄存器1的内容,:1p也可以

  • 有名寄存器:a-z,一共26个,供用户使用
    • "+小写字母+指令:完成指令,并将对应区域文本存在寄存器中,不需要按回车。
  • 编号寄存器:0-9,10个,vim自己使用,存放删除和拷贝的文本,保存内容无大小限制
    • "0号寄存器是visual模式下拷贝的问题,如yy拷贝的行文本
    • "1-"9号寄存器是dd删除的行文本
    • "+数字+p或P:找回数字编号下缓冲区内容
  • 缺省寄存器
    • % 当前窗口对应的文件名
    • # 当前窗口的其它文件名
    • : 命令行模式最近输入的命令
    • . 最近插入的文本
    • " 最近删除或拷贝的文本,put时从这里出

4-Motion与range

  1. motion是指移动光标的命令(域)
    命令=操作符+motion
    • $ 域为光标至行尾
    • 0或^ 域为光标至行首
    • e或w 域为光标至当前字尾
    • b 域为光标至当前字首
  2. 想将作为命令的域,按两次操作符键
  3. range是指行数
    • 寄存器+[range]+d/y+[motion]:完成拷贝/删除动作->寄存器
      eg.
      • “wdd 删除当前行到”w寄存器
      • “z7yy 拷贝从当前光标开始算,一共7行,到”z寄存器
    • 寄存器+p:将寄存器内容拷贝到光标后的位置上,完成寄存器->缓冲动作
  4. 3dw vi删除3个字和后面的空格

5-剪切与粘贴

  1. 命令模式下:
    • d删除指定位置文本,同时拷贝到””和”1寄存器,并且下压2-9号寄存器
    • y拷贝指定位置文本,同时复制到””和”0寄存器
    • p 将缺省寄存器””内容拷贝到光标位置之后
    • P 将缺省寄存器””内容拷贝到光标位置之前
    • c 删除文件并进入文本输入模式
  2. 命令模式下v进入visual模式:
    • khjl或方向键 移动光标,从初始光标位置开始到移动终点部分文字被选中
    • y 将选择内容拷贝到””和”0寄存器,y表示yank
  3. 拷贝与删除命令可与motion组合

6-光标快速定位

命令行模式:

  • :n 定位到第n行的行首
  • :0或:1 定位到第1行的行首
  • :$ 定位到最后一行的行首
    注意:命令模式下按$定位到该行的行尾。

命令模式:

  • G或0G 定位到最后一行的行首
  • nG 定位到第n行的行首
  • Ctrl-g 或 := 在命令行区域输出当前行
  • Ctrl-End 或 G$ 跳到最后一个字符
  • Ctrl-d 下移光标12行down
  • Ctrl-u 上移光标12行up
  • Ctrl-f 下移光标24行forward
  • Ctrl-b 上移光标24行

7-vim定制

  1. 让vim更舒服一些,修改.exrc或者.vimrc
  2. :set命令
    • :set all 显示所有选项
    • :set 显示被修改的选项
    • :set X? 显示选项X的值
  3. 选项的分类:布尔、数字式、串
    • 布尔:set X set noX
    • 数字:set X=n(数字)
    • 串:set=XX
  4. 常见的vi环境选项:(要求不高)
    • autoindent 新行与上一行首对齐
    • ignorecase 搜索忽略大小写
    • magic 允许搜索时用特殊字符
    • number 显示行号
    • report 通知用户上一个命令影响的行号
    • scroll 设定CTRL+d翻动的页数
    • shiftwidth 缩进空格数
    • tabstep tab的空格数
  5. 折叠{}代码块*(不考)*
set foldenable
set foldmethod=indent 
zc  关闭折叠
zo  打开折叠
  1. 深度定制:缩写与宏*(不考,略)*

8-执行shell命令

:shell 切换到shell界面,exit回到vim
:! 执行shell命令,切换到shell界面,但不会提示下一步输入
:r! 将shell命令输出粘贴到当前位置

7.1 Emacs编辑器


  1. Emacs内部集成lisp脚本语言,高度定制化 eg.spacemacs
    Emacs是一种生活,打开emacs在其中可以完成一切工作
  2. apt install emacs-nox

7.2 正则表达式


  1. Unix系统偏好于以可读的文本处理

    • vi、emacs、grep、sed、awk都支持正则表达式
    • systemd
  2. 正则表达式RE(Regular Expression)是一种语言,这种语言表现为一种的表达式
    RE可以完全的表示有限自动机DFA、NFA
    RE主要用于定义词法

  3. Posix标准中RE分为BRE(基础)、ERE(拓展)

  4. RE字符集
    RE字符集

    特别的

    • [[:alnum:]] 字符+数字
    • [[:alpha:]] 字符
    • [[:digit:]] 数字
    • [[:lower:]] 小写字符
    • [[:upper:]] 大写字符
    • [[:space:]] 空白字符
    • 注:若写为[[:alnum:]_!]等方式,表示除字符和数字外还可以取_或!。
  5. 详细内容与实例
    注意:行匹配,结尾\n结束一行。

    • . 匹配单个字符
      r.         //r后加任一字符
      .x.        //任何两个字符中间夹一个x,不要求两个字符相同
      
    • ^ 锚定行首,从行首开始匹配^后的内容。
      ^George    //匹配出现在行首的George
      ^\.        //匹配出现在行首的.
      ^.         //匹配出现在行首的任意一个字符
      
    • $ 锚定行尾,从行尾开始匹配$前的内容。
      today$     //匹配出现在行尾的today
      \.$        //匹配出现在行尾的.
      .$         //匹配出现在行尾的任意一个字符
      ^$         //匹配不含字符的行(无意义)
      ^ $        //匹配只有单个空格的行
      
    • [] 匹配括号内的某个字符。(或的关系)
      [tT]he     //匹配the和The
      [0-9]      //匹配数字0~9
      [A-Z]      //匹配大写的字母
      [A-Za-z]   //匹配大写或小写字母
      [^A-Z]     //匹配除大写字母以外的任何字符
      [^A-Za-z]  //匹配非字母的字符
      [-0-9]     //匹配一个连字符-或数字
      []a-z]     //匹配一个右方括弧或小写字母
      注意:右方括号必须放在最前面的[(或^)后,连字符必须放在最前面的[(或^)后或者最后的]前
      
    • * 匹配任意个(包括0个)紧靠在*前的字符,表示匹配的次数
      X*         //匹配 0、1、2……个X
      XX*        //匹配 1、2、3……个X
      .*         //表示0或若干个任何字符
      注意:正则表达式总是寻求最大匹配,因此上式多匹配一行。
      e.*e       //匹配一行中第一个e和最后一个e间的所有内容
      [A-Za-z][A-Za-z]*   //匹配任何1个或多个字母
      
    • \{…\} 匹配精确数目的字符串
      {min,max}
      X\{1,10\}           //匹配 1~10 个连续的X
      注意:正则表达式总是寻求最大匹配,即有11个连续的X视为匹配了两个项,一个10个X,一个1个X//?
      [A-Za-z]\{4,7\}     //匹配 4~7 个字母序列
      \{10\}              //匹配的必须是10个字符长度
      .\{10\}             //匹配10个字符
      [A-Za-z]\{10\}      //匹配10个字母
      +\{5,\}             //匹配至少5个连续的+号
      
    • \(…\) 保存匹配的字符串,\n引用定义的位置,n的范围从1~9
      ^\(.\)              //将行首的第一个字符并保存
      ^\(.\)\1            //匹配行首的第一个字符并保存到寄存器1,与第二个字符对比,相等则匹配
      ^\(.\).*\1$         //匹配行首字母和行尾字母相同的行,中间夹着的字符数量不受限制
      ^\(...\)\(...\)     //将行中头三个字符存在1号寄存器中,接着3个字符存在2号寄存器中
      

应用实例:
c[aeiouy]t 匹配可以是cat、cet、cot等
[0123456789] 可表示为`[0-9]
[.] 匹配或\或.
[].] 匹配]或或\或.
[-.] 匹配-或或\或.
[].-] 匹配]或或\或.或-
(ab)(cd)[def]\2\1 匹配abcdecdab或abcdfcdab或bcddcdab
(why).
\1 匹配whyXXwhy
([[:alpha:]][[:alnum:]]*) = \1 一个语言赋值语句,如a_3 = b4c_c
^ABC 行首有ABC的行被匹配
Def$ 行尾有Def的行被匹配

7.3 vi的正则表达式搜索


首先检查magic变量:set magic?,一般默认magic。
help magic可查看下表了解vi中的正则表达式规则

应用:

  • 搜索:/或?后跟一个RE表达式
  • 替换:(模仿sed命令)
    :range s/from/to/flags
    from和to分别表示要被替换和替换的内容
    range表示行范围,%是全局所有行(1,$表示从1行到尾行)
    flags为g表示这一行中所有的匹配项都替换,不带g则只会替换符合条件的第一个。
    :%s/from/to/g最常用

作业

  1. 匹配c语言头文件.h的正则表达式,匹配.c文件的正则表达式
  2. 空行的正则表达式 ^[[:space:]]*$
  3. 已知搜索结果格式为用户名:……:主目录:登录使用的shell
    搜索/etc/passwd文件中用户名的正则表达式
    搜索/etc/passwd文件中用户shell的正则表达式
    搜索/etc/passwd文件中用户主目录的正则表达式(涉及sed,不做)
  4. 在vim中替换文件中所有Block字符串为Page的命令

8 文件系统高级操作


1-重定向

  1. C语言程序一般会打开三个缺省文件,stdin、stdout、stderr,文件描述符分别是0,1,2。
  2. 在Unix系统中,文件是io的基本抽象。标准输入、标准输出、错误输出可以替换为其它文件。
  • 标准输出重定向
command > file    //把命令执行结果存放到文件中,替换标准输出
command >> file   //追加到文件末尾
  • 标准输入重定向
command < file    //不用标准输入来执行命令,用文件内容
command << EOF    //标准输入,当碰到EOF字符串时,输入结束
  • 标准错误输出重定向
command 2> file   //将command命令的错误输出重定向到file文件里
command 2>> file  //追加重定向
  • 重定向标准输出+标准错误输出
command &> file   //把标准输出和错误输出都放到一个文件里
command &>> file  //追加重定向
  • 特别文件
    /dev/null (bit垃圾桶)
command > /dev/null  //把输出放到垃圾桶里
command < /dev/null  //从垃圾桶倒出全零,用于清空文件、引导记录
  1. 利用重定向创建文件
    cat命令不带参数,以标准输入作为输入
    cat > file,以标准输入作为输入,输出重定向的file,创建文件
    cat >> file,以标准输入作为输入,在文件末尾追加文件内容
    cat file1 > file2,以file1作为输入,输出重定向的file2,拷贝文件
    cat file1 file2 > file3,以file1,file2作为输入,输出重定向到file3,合并两个文件
    cat > file1 << EOF,标准输入到文件file1,以EOF作为输入结束标志
    注:没有指定<<字符串时ctrl-d可结束文件输入
  2. 重定向如何实现

2-管道

  1. shell将一个程序的标准输出作为另一个程序的标准输入,形成管道(pipeline)
    command A | command B
    注意:两条命令之间是以一个匿名文件传输
    ls –al | grep -e “^d”
    ls -al | less
    
  2. 原理:

管道原理

3-文件操作

  1. cp拷贝源文件成目标文件,注意默认当前目录,要提供准确的文件路径名。

    cp source target   //将源文件内容复制到目标文件下。若目标文件已存在则覆盖。  
    cp source1 (source2 …) 目录名   //将多个文件复制到一个目录下,目标文件与源文件同名。  
    
    • -b 如果目标文件存在,创建备份~(防止覆盖)
    • -i 如果目标文件存在,提示
    • -r 递归拷贝,将目录复制到新的目录
  2. mv移动文件,提供准确的文件路径名。

    mv file1 file2   //将原文件名更名为目标文件名。
    mv source1 (source2 …) 目录名   //将多个文件移动到一个目录下。
    
    • -b 如果目标文件存在,创建备份~(防止覆盖)
    • -i 如果目标文件存在,提示
    • -f 强制移动
  3. wc统计文本字数,第一列行数,第二列字数,第三列字符数。
    注意:字定义为没有空格(空格或制表符)的字符序列

    wc   //未指定文件名时从标准输入(键盘)获取输入
    wc file1 file2   //指定多个文件时分行显示,最后一行显示总数。
    
    • -l 统计行数
    • -w 统计单词数量
    • -c 统计字符数量
    eg.  ls *.h | wc -l      //统计头文件数量
    eg.  wc -l /etc/passwd   //统计用户数量
    
  4. head显示文件头部,缺省显示头部10行,可以指定多个文件

    • -n 显示头部n行
    • -l 显示头部10行(默认)
    • -c 显示头部10个字符
    • -c n 显示头部n个字符,n为正整数
  5. tail显示文件尾部,缺省显示尾部10行,可以指定多个文件

    • -n 显示尾部n行
    • -l 显示尾部10行(默认)
    • -c 显示尾部10个字符
    • -c n 显示尾部n个字符
    tail 11 file   //显示尾部11行
    tail -4 file   //显示尾部4行
    tail +50 file   //跳过文件前50行,显示剩余部分
    
  6. cut纵向输出文件某列或某域,默认分隔符是制表符

    • -f LIST 指定剪切的域
    • -c LIST 指定剪切字符位置
    • -d x 指定域的分隔符x,可以是空格或%或:等,注意有特殊意义的字符要用双引号括起来:“ ”。
    • LIST为如下形式:n-m 表示[n,m]的域,n,m 表示n和m域
  7. paste横向连接两个文件,缺省分隔符是TAB制表符

    • -d x 指定域的分隔符x
  8. more 分页显示文件内容,后翻不可前翻

    • [Return] 下翻一行
    • [Spacebar] 下翻一页,两屏间两行重复显示
    • [Q或q] 退出
    • -lines 显示指定行数
    • +lines 从指定行数开始显示
    • + /pattern 从包含pattern的上面两行开始显示
    • -c 显示每页前清屏而不是翻动
    • -d 显示提示
    • = 看当前行
    • h 查看可用选项列表(帮助)
  9. less 同上但可前翻

  10. sort按照行做字典序排列文件内容,注:按照字典序:空格等非文字数字字符前于数字前于大写字母前于小写字母(Unix使用ASCII排序,数字按照第一个数位排序而不是数值大小)

    • -b 忽略行首空格
    • -d 字典序比较,忽略标点和控制符号
    • -t 指定域分隔符
    • -f 忽略大小写
    • -n 数字以数值大小排序
    • -r 逆序排列
    • -o 指定输出文件
    • +num 排序前跳过num个字段(默认分隔符为制表符)
    sort /etc/passwd             //排序所有用户
    sort -t: -n +2 /etc/passwd   //按uid排列所有用户(:为分隔符、以数字大小排序、对第二个字段排序)
    
  11. grep打开文件,在文件中以RE方式搜索字符串,可以指定多个文件,样式内容是含有空格和元字符的字符串时要用双引号括起来。
    如:grep "#include<private.h>"*.c 在c源文件中查找字符串"#include<private.h>"。
    grep [OPTION] PATTERNS [FILE]

    • -c 只显示匹配的行数
    • -l 只显示具有匹配行的文件名
    • -i 忽略大小写匹配
    • -G BRE,grep缺省
    • -E ERE,egrep缺省
    • -e PATTERNS 指定一个或多个RE
    • -v 只显示不匹配的行
    • -n 输出行号

练习

ls -al | grep -e '^d'                                       //查找当前目录下的子目录
ls -al /dev | grep -e '^c'                                  //查找/dev目录下的所有字符型设备
ls -al | grep -e '^d' | wc -l                               //统计当前目录下的子目录个数
ls -al /dev | grep -e '^c' -c 或 ls -al /dev | grep -e '^c' | wc -l   //查找/dev目录下的所有字符型设备个数
more /var/log/dpkg.log 或 less /var/log/dpkg.log           //翻看/var/log/dpkg.log
grep -e ' installed ' /var/log/dpkg.log                     //搜索/var/log/dpkg.log中安装的package
grep -e ' installed ' /var/log/dpkg.log | wc -l             //根据/var/log/dpkg.log统计安装的package
tail -20 /var/log/dpkg.log                                 //查看/var/log/dpkg.log尾部20行
sort -t: -n +3 /etc/passwd                                  //按照组id(第四个字段)排序/etc/passwd

4-文件系统原理

  1. Unix有三大抽象:(1)进程、线程对执行过程(2)文件对io(3)地址空间对内存

  2. Unix有四种io:文件系统、块设备、字符设备、socket。

    • 块设备和字符设备出现在文件系统的名字空间
    • Socket仅表现为文件,但不出现在文件系统
  3. 磁盘文件组织,需要从几个维度去考虑磁盘如何组织成文件:快速访问、方便修改、节省空间。

  4. 考虑磁盘的空间组织,主要有几种形式:

    • 变长的堆,顺序放在磁盘(主要形式)
    • 定长的记录(数据库)
    • 索引(快速访问)
  5. Unix文件系统的选择:堆+索引

    • 索引 key->value,key是文件名,要求变长结构。将文件名收集形成目录文件。
    • 而关于文件的定位和状态放在inode结点,是定长结构。
  6. 典型Unix磁盘布局:
    Unix磁盘布局

MBR主引导记录–分区表(DOS有4个分区)–
Boot block自举块–inodes–Files and directories存放文件(堆形式)–
7. 目录文件 -> i-node -> data
(ls –i显示节点)
目录与节点

  1. ln链接,在已存在文件和新文件名间创立链接。
    ln [OPTION]... [-T] TARGET LINK_NAME
    ln命令不会创建新的i-node,而是引用已有i-node,增加引用计数(硬连接)
    ln –s符号链接,分配一个新的inode,内部记录指向原有文件(软连接),文件用ls -al查看时以l开头。
    符号化链接指向初始文件,初始文件被删除该符号链接就不再起作用,链接得到的文件主人为链接操作者,文件链接数为1,文件大小为链接的地址包含的字符串大小;ls-Ll可获取符号化列表所指向的文件详细信息。删除符号化链接所指向的初始文件会使符号链接变得无效。
    注意:有时文件被删但符号连接的指针仍在,会找不到文件。inodes资源有限,硬连接会挤占资源。软连接会创建新的inode,保存文件属性。
  • 当改变任何一个链接文件的内容,无论使用哪个名字,这些文件都会改变。
  • 如果指定已经存在的目录名作为新文件名,用户可以访问该目录下的文件而不用输入文件名。
  • ls -l 输出的第二列显示链接数。每个文件的链接数至少为1,指的是目录和文件的链接。

实例
移动文件到不同目录,inode不会发生变化
touch一个文件,创建目录项?inode?分配数据块?

9 探索shell


1-shell工作原理

  1. /etc/passwd决定了用户登录后执行的shell程序
    有些特殊的用户,可以不是shell程序

  2. shell解析用户命令

  • 创建子进程执行用户命令
  • shell等待命令子进程退出
  • 命令子进程退出,发送SIGCHLD信号给shell
  • shell在信号处理函数中处理子进程退出
  1. shell进程退出
  • 发送SIGCHLD信号给login进程

  • login进程处理SIGCHLD信号

  • 退出,发送SIGCHLD信号给init进程

  • init进程处理SIGCHLD信号,重新fork/exec一个getty进程
    在这里插入图片描述

    init–(fork)->getty–(exec)->login–(fork)->bash–(fork)->command
    bash<—command回收子进程执行完成后的状态
    注意:
    (1)纵轴表示的是生存时间
    (2)方框内表示一个类,加了:表示一个实例
    (3)登陆后login始终wait bash退出
    (4)退出bash后返回消息给login,login返回消息给init,之后init fork一个getty进程在终端等候

  1. 注意bash退出:
    ctrl-d
    exit(并不是一个程序)内置命令 builtin
    所谓 Shell 内建命令,就是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件。

    http://c.biancheng.net/view/1136.html

  2. shell内置命令可以替换一些经常使用的命令,部分提升性能

    • man bash
    • 搜索:SHELL BUILTIN COMMANDS
    • source、alias、echo、cd、eval、exec、export、let、pwd、history、printf、set、unset、test等
    • Special building command -> function -> building command -> export command
    • 内置命令区分出special原因是某些内置命令允许function重载
  3. echo命令输出字符串 echo "…"
    不同的Unix系统对echo的命令做了选项扩展(不要求)
    如果是格式化输出,使用printf printf "%d" &x

2-shell语言

  1. shell是一种语言、负责与用户交互
    • 变量
    • 命令
    • 循环与分支
  2. 命令的语法
    命令+空格+[选项]+参数+(;|回车)
    eg.echo hello; ls -al
    多行单条命令,一行的尾部以\结束
    ls \
    -al
    
    完整的命令解析过程:
    • tilde是~表达式展开
    • 变量替换
    • 命令展开是重音符的命令展开
    • 单词划分利用$IFS变量分割
    • 寻找命令
      在这里插入图片描述

3-shell变量

  1. shell内置一个变量表(哈希表)
    每个变量有环境变量或局部变量属性
    变量名->字符串(无类型)
  2. 环境变量
    父进程会将环境变量传递给子进程(fork)
    C语言getenv()函数
  3. set命令显示所有变量,export命令显示所有环境变量
  4. 添加修改变量
    VAR=xxx 添加普通变量
    注意:等号两侧不能由空格:=前加空格会走命令解析过程,会把var看成命令,=及后面内容看成参数;=后面加空格会把空格也算进字符串
    export VAR=xxx 添加环境变量
  5. 引用环境变量
    $VAR或者${VAR}
  6. 标准变量
    • HOME变量记录用户主目录
      HOME=/usr  //修改主目录
      cd
      
    • PATH变量给出外部程序的搜索路径
      echo $PATH :分割符
      dash  //dash
      PATH= //清空PATH变量
      which pwd  //查找当前工作路径
      exit
      
    • IFS变量定义扩展命令参数时的分隔符(教材的例子是错的)

4-参数展开

  1. shell在解释命令时,有一个重要的步骤是展开变量得到命令参数
    ls -al * //给shell,根据空格抽取各部分token
    shell在解释这条命令时,ls是命令,special builtins(特别内置命令) -> functions(用户定义函数) -> builtins(内置命令) -> export command(在PATH中去查找),-al是一个参数,*需要展开(最先完成参数展开)

  2. shell内部将对参数的展开

    • -开头当成选项
    • 双引号、单引号、重音符号开头作为字符串
    • $开头作为变量
    • <>作为重定向符号
    • |作为管道符号
    • 其余字符串如果包含*?[]需要做路径匹配展开
  3. shell路径元字符
    注意:shell元字符并非正则表达式!

    • ?匹配路径名的单个字符(正则:.
    • * 匹配路径名的任意长度字符串(正则:.*
    • [list] 匹配list中任意一个字符
    • [!list] 匹配不在list中的任意一个字符(正则求反:^)
    • [abc] //匹配abc
    • [a-z] //匹配a-z任一
    • [!a-z] //匹配非a-z
    • [a-z!] //匹配a-z及!任一
  4. 反斜杠\转义,取消元字符语义

    rm temp? //匹配temp1、temp2…
    rm temp\?//匹配temp?
    

    echo <>"'`$*?&|\

  5. 双引号,单引号字符串
    shell不将双引号、单引号字符串看成路径名

    • 双引号字符串需要展开 V A R 变量,单引号,重音符号 e c h o “ VAR变量,单引号,重音符号 echo “ VAR变量,单引号,重音符号echoHOME”
    • 单引号字符串不会展开
      echo ‘$HOME’
    • 重音符号表示一个内嵌命令,要先执行,然后得到输出作为参数
      双引号内的重音符号要先执行:echo “`ls -al`”
      注意:如果输出有*可能会被解析,所以最好加双引号

5-find与xargs

  1. find命令在文件目录树中查找文件
    find start-point tests action

    • 从start-point开始查找(start-point是一个路径)
    • tests做测试(找什么)
    • 满足条件执行action(做什么)
  2. tests测试条件:

    • name “filename” 根据给定filename做匹配查找
    • size +-n 查找大小为n的文件
    • type filetype 查找指定类型filetype的文件
    • atime n 查找access访问时间的问题
    • mtime n 查找修改时间的文件
    • 其中:type
      • type f 普通文件
      • type d 目录文件

    注意:name “*.c”,这个模式是shell的路径匹配模式,直接写成-name *.c不行。

    首先++文件通配符++和++正则表达式++含义是不同的。最大的差别在于:
    (1) "*"在正则表达式中表示前面的字符重复任意次数,所以表示任意字符串".*", shell通配符中*就表示任意字符串
    (2) "."在正则表达式中是任意个字符,在通配符中没有其他任何含义,在通配符中"?"表示一个任意的字符
    shell本身会对*进行解析,所以如果不希望shell解析"*",就一定要把通配符用双引号括起来(单引号使用后就什么都替换不了)

  • ls -l ab*这个*由shell来解析的,假如目录下面有ab1 abc ab2,那这个命令首先会被shel转化为ls -l ab1 abc ab2ls本身没有解析通配符的能力
  • ls -l "ab*",那就会什么都没有,因为没有一个文件的名字是ab*
  • find . -name "abc*"这个参数会原封不动的传给find,find命令本身具备解析通配符的能力,会在当前目录下面的各级目录下面寻找以abc开头的文件。
  • find . -name abc*那通配符会被shell解析,如果当前目录下没有以abc开头的文件,那传给find命令的就是空的,相当于:
    find . -name
    find: missing argument to' -name'
    
    如果当前目录下游多个abc开头的文件,会出错,相当于:
    find . -name abc1 abc2
    find: paths must precede expression: abc2
    
    就是说第二个name前面没有指定寻找的路径;
    如果当前目录下面只有一个abc开头的文件,那就不会出错,但是相当于:
    find . -name abc1
    
    最终最在所有的目录下面搜索abc1的文件,和我们的本意大相径庭。记住,-name选项搜索的是basename,不要再里面带"".
  1. action选项:(不要求)

    • print 打印输出
    • exec command 执行命令
    • ok command在执行命令前要求确认
  2. xargs从标准输入上读,将标准输入文件按照空格/TAB拆解成参数,作为command执行参数。
    xargs [command [initial-arguments]]

    查找epoll_wait函数在那个文件:  
    find /usr/include –name “*.h” -type f | xargs grep “epoll_wait”
    

xargs与管道区别的相关资料 https://www.cnblogs.com/wangqiguo/p/6464234.html

6-shell配置

  1. 用户登录,启动缺省shell
    man bash,查找INVOCATION
    /etc/profile -> ~/.bash_profile -> ~/.bash_login -> ~/.profile

  2. 如果不是login启动的shell
    /etc/bash.bashrc -> ~/.bashrc

  3. 用户退出
    ~/.bashr_logout

7-进程控制命令

  1. ps命令显示进程(不要求)

    • -a 显示所有进程,但不包括会话leader,不包括无终端进程
    • -f 显示进程完整信息
    • -e 显示所有进程
    • -H 按照树形显示
    • -j 按照job形式输出
    • -ejH 树形输出所有进程
  2. kill杀死进程
    kill命令向进程发送信号
    缺省发送SIGTERM信号,15

    • -l 列出所有信号
    • -1 除init进程以及自己以外的所有进程
    • -s 发送s标志的信号
    • 77 对77号进程操作
    • -7 发送7号信号
      信号类似于硬件中断
      Ctrl-c -> 发送SIGINT信号
      Ctrl-d -> 发送EOF,意思是输入关闭
  3. trap设置进程捕获信号后如何处理
    中断服务程序&信号服务程序
    trap “command” signal numbers
    trap ‘’ TERM 忽略SIGTERM信号
    trap - TERM 恢复SIGTERM信号缺省处理
    问题:trap设置的是当前进程——bash进程的信号处理函数,如何保证子进程依然是这个动作?

8-前台后台

  • shell命令使用 & 表示 后台执行
    ping www.baidu.com > /dev/null &
  • jobs命令是一个(内置)builtin命令,可列举后台执行的作业
    man bash搜索SHELL BUILTIN COMMANDS
  • fg命令把后台作业切至前台
    fg jobspec 作业编号用jobs命令查询
  • nohup “command”&
    后台执行命令,并且该命令在用户退出登录后仍然执行

9-History和fc

  1. Bash在执行命令后,会在内存中记录所有使用的命令。
    当用户退出登录,所有命令保存在~/.bash_history文件中
    history命令则列出到目前为止,执行的所有命令。
    ~/.bash_history记录的是到上次退出前的所有命令。

  2. fc是一个(内置)builtin命令
    man bash搜索SHELL BUILTIN COMMANDS
    fc first last //命令先编辑从first到last的命令,然后执行
    fc –s cmd //cmd是history的命令编号,执行该编号任务

  3. alias是一个(内置)builtin命令
    alias ll=‘ls –al’
    tee命令分离输出,同时输出到标准输出和文件
    ls -al | tee dir.list

    • -a 追击到文件
    • -i 忽略中断信号

练习:
搜索/usr/include目录下名字为fuse.h
在/usr/include目录下搜索包含EPOLLIN的头文件
列出/etc/passwd文件的用户名+登录目录
统计一个项目中的.h/.c文件的行数,要求排除空行
man tr,然后利用tr命令将一个dos结尾的\r\n文本文件变换为Unix结尾的\n
阅读.bashrc和.profile文件

10 UNIX通信


  1. 接口与状态

    ifconfig / ip addr  
    netstat / ss
    ping 
    
  2. ssh
    安装openssh服务

    su
    apt install openssh-client
    apt install openssh-server
    

    ssh客户端操作

    ssh ip-address,交互式操作
    scp src dst,scp://[user@]host[:port][/path]
    sftp
    
  3. curl安装

    su
    apt install curl
    
  4. wget

  5. ftp

  6. systemd
    system daemon,代替常用的System V与BSD风格init程序
    init采用脚本来加载各种服务,各种服务的依赖难以维持,服务加载速度慢
    systemd使用c编写的程序接管各种服务加载

    • Log
    • Timer
    • Service
    • Swap
    • Device
    • Socket
  7. Init:T1+T2+…+T7
    Upstart:T1+T2+T3

    Systemd:即时发现依赖 >T1

  8. Socket依赖

    • Inetd
    • Fork创建后描述符继承
      D-bus依赖
    • Networkmanager
      文件依赖
    • 内核automounter 模块、
      unit声明依赖
  9. 利用Cgroup管理进程生命周期
    Fork两次之后,父子进程关系链条断裂

    10.Systemd的设计模仿了Windows和MacOS
    与Linux内核严重耦合,其它开源系统无法使用
    结构复杂,功能强大,违反了keep it stupid simple,kiss原则
    要求管理员抛弃init脚本,重新学习
    11.Systemd管理的对象抽象为单元(unit),man 5 systemd.unit

    • service 单元,封装后台服务进程
    • socket 单元,封装有名管道
    • target 单元,组合多个单元
    • device 单元,封装设备文件,可用于基于设备的启动
    • mount 单元,封装文件系统挂载点,/etc/fstab
    • automount 单元,封装文件系统自动挂载点,仅在挂载点被访问时才进行挂载,取代传统的 autofs 服务
    • timer 单元,封装基于时间触发的动作
    • swap 单元,封装交换分区或者交换文件
    • path 单元,根据文件系统上特定对象的变化来启动其他服务
    • slice 单元,控制特定 CGroup 内(例如一组 service 与 scope 单元)所有进程的总体资源占用
    • scope 单元,与 service 单元类似,但是由 systemd 根据 D-bus接口接收到的信息自动创建, 可用于管理外部创建的进程
  10. Unit文件目录,man 5 systemd.unit

  • 系统unit文件目录
  • 用户unit文件目录
  1. Systemctl
  • Systemctl –a
  • Systemctl status

11 GUN工具链


  1. GUN工具链

https://my.fsf.org/civicrm/contribute/transact?reset=1&id=57

Gnu toolchain是开发操作系统、应用程序的一套完整的程序和库,包括gcc、gdb、glibc:

  • cpp
  • m4
  • gas
  • gcc、g++
  • ld
  • glibc、libc++
  • gdb
  • makefile
  • libtool
  • binutils: ar、objdump、c++filt、nm、readelf等
  • autoconf、automake
    相当与工业制造中的母机
  1. gcc是一族编译器,包括c、c++、go、java等
    前端+后端

    • .c为后缀的文件,C语言源代码文件;
    • .a为后缀的文件,是由目标文件构成的档案库文件;
    • .C、.cc或.cxx 为后缀的文件,是C++源代码文件;
    • .h为后缀的文件,是程序所包含的头文件;
    • .i 为后缀的文件,是已经预处理过的C源代码文件;
    • .ii为后缀的文件,是已经预处理过的C++源代码文件;
    • .m为后缀的文件,是Objective-C源代码文件;
    • .o为后缀的文件,是编译后的目标文件;
    • .s为后缀的文件,是汇编语言源代码文件;
    • .S为后缀的文件,是经过预编译的汇编语言源代码文件。

    C语言编译过程

    gcc -E hello.c -o hello.i
    gcc -S hello.i -o hello.s 
    gcc -c hello.s -o hello.o
    gcc -o hello hello.o
    

  1. gdb

    #include <stdio.h>
    int main(int argc, char *argv[])
    {
        for(int i=0, j=0; i < 10; ++i) {
            j += 5;
            printf("j=%d\n", j);
        }
        return 0;
    }
    
  2. makefile
    Makefile用于工程组织和编译
    与常见的命令式语言不同,它是一种依赖推导语言
    Shell语言:变量定义+命令执行
    Makefile:变量定义+依赖描述
    例子:

    count_words: count_words.o lexer.o -lfl
        gcc count_words.o lexer.o -lfl -o count_words 
    target: dependencies, …
        actions
    

    显式规则与隐式规则
    %.o: %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<
    推导规则

    • 检查目标和依赖文件的时间,如果依赖更新,则执行动作
    • 显式规则 > 隐式规则
      推导过程
    • 动态规划
    • 从target出发,枚举所有规则,直到依赖可达
    • 反过来行不行?
      Makefile的主要问题
    • 推导结论没有显式导出,不便于理解
    • 应该保存为中间结果,下次编译直接调用
    • 中间结果保存为一棵树,同时编译
      5.cmake
      cross platform make跨平台自动化建置系统
      Cmake vs Makefile
    • Makefile的依赖推导不直观
    • Cmake的语法设计采用命令式
    • 跨平台,可以导出为makefile、sln等
      Cmake在不同平台上生成不同的本地化脚本
    • Linux下的Gnu Makefile
    • Visual Studio的sln
    • Google等ninja
      Cmake管理的代码编译主要有两步:
    • 利用cmake生成本地编译脚本
    • 利用本地脚本编译程序
      基本语法
    • 定义工程
    • 设置变量
    • 添加可执行目标
    • 添加递归目录
    • 添加静态库、动态库
    • 条件分支
    • 定制命令和目标add_custom_command/add_custom_target
      6.git
      版本控制系统(Version Control System,简称VCS)是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。
    • 本地版本控制系统
    • 集中化的版本控制系统
    • 分布式版本控制系统

    Git的分布式管理

    Git的分支管理:围绕主干开发

主要命令

  • git init
  • git clone
  • git status
  • git add
  • git commit
  • git log
  • git fetch [remote-name]
  • git push [remote-name] [branch-name]
  • git branch

12 Shell编程


1-脚本

  1. Shell是一种语言,可分类为bash(对shell有扩展)、csh…

  2. Unix的传统是提供基本的功能,由用户自行扩展,包括自己编写shell脚本

    cat > won   //定义一个won脚本文件
    who | wc –l //统计登陆的用户数量
    Ctrl-d      //结束输入脚本
    
    • 执行脚本:sh won
    • 自包含脚本文件:**#! /bin/sh**或#! /bin/bash
      要修改为可执行文件(chmod将该文件从rw变为rwx可执行)
  3. 自包含脚本工作原理:
    (1)won为第一个token,解释为命令,到$PATH中寻找路径
    (2)确认是否为可执行文件
    (3)loader程序加载脚本,发现不是elf可执行文件,返回错误(非elf格式loader不接受)
    (4)bash收到错误,然后打开文件头部#! /bin/sh,发现是脚本,指明了使用/bin/sh执行
    (5)调用脚本执行

  4. 基于兼容性考虑
    #! /bin/sh:bash–(fork)–/bin/sh–(分别fork新的子进程)执行echo和ls
    Debian上的/bin/sh符号链接指向dash
    dash对标准的兼容性更好

  5. 注意:#开始到行尾均为注释

2-调试技术

  1. echo命令输出参数
    echo “hello, world”  
    echo *  
    echo含有\*的时候会进行shell匹配,有匹配结果输出结果,没有匹配结果直接显示*\
    
  2. set打开调试
    • set -x命令打开执行命令输出,输出的是带参数展开后的命令
      set -x
      echo *(*会被结果替换)
      set +x 关闭
    • set –v命令输出参数替换前的命令
      set -v
      echo *
      set +v 关闭

3-变量

  1. 变量赋值VAR=xxx(注意不能加空格)、环境变量export VAR=xxx/局部变量等知识在上一章介绍

  2. 变量引用要看成字符串$VAR

  3. 变量替换操作(不要求)

    • ${VAR:-word} 如果变量不存在,返回word
    • ${VAR:=word} 如果变量不存在,设置VAR变量为word,返回word
    • ${VAR:?message} 如果变量不存在,打印message,退出,但交互shell不会退出
    • ${VAR:+word} 如果变量存在,返回word;否则返回null
  4. 删除变量:unset VAR

  5. 位置参数是一种特殊的变量,用于表示命令行参数

    • $1- 9 , 9, 9{10}表示参数
    • $0表示命令名
    • $#表示参数个数
    • ∗ 将所有参数使用 *将所有参数使用 将所有参数使用IFS隔开,形成一个字符串
    • $@是每个参数一行

例:用++set++命令改变命令行参数(set是bash内置命令)
set hello “I love bash” world
echo $0:-bash
echo $1:hello
echo $2:I love bash
echo $3:world
echo $*:hello I love bash world 合并所有为一个字符串
echo $@:hello I love bash world 可以枚举

  1. 特殊变量
    • **$?**表示进程退出状态
      ls -al hello
      echo $?
      errno num查询错误码看看是什么错误
      
    • **$$**表示当前进程id

4-算术表达式

  1. Shell中变量都是字符串,计算算术的时候使用$(())作为算术表达式,不提倡用let
    echo $((3+2))
    $((3+2))
    
  2. 算术运算符:++、–、+、-、!、~(按位求反)、*、/、%等
    i=3
    echo $((i++)) $i //先输出i后将i+1赋值给i,输出3 4
    echo $((++i)) $i //先输出i+1的结果后将i+1赋值给i,输出5 5
    
    注意算术表达式中,true=1,false=0
    echo $((3==3)):1

5-逻辑连接

  1. 使用&&和||连接两条命令
    • &&表示and
    • ||表示or
  2. 逻辑短路
    • Command1 && command2,当command1正确执行,才会执行command2
    • Command1 || command2,当command1执行错误,才会执行command2;若command1执行正确,不会执行command2

6-命令分块

Shell中使用分号;将多条命令分开,然后利用()将多条命令组合成一块

  • 单行
  • ()表示当前shell执行

7-条件分支

if 条件; then
command lines
[elif 条件
command lines]
[else
command lines]
fi
或
if 条件
then
command lines
[elif 条件
command lines]
[else
command lines]
fi
  • 条件是一段命令,测试的是$?是否是0
    ++为0满足条件(正确执行)
    不为0,不满足条件++
    因此test $((3>2)) = 1;或[ $((3>2)) = 1 ];才可以正确判断。

  • test或者[ … ]是测试条件:test EXPRESSION

    1. 测试字符串表达式:

      • = “$STR1” = “STR2” //两个字符串是否相同
      • != “$STR1” != “STR2” //两个字符串是否不同
      • -n -n “$STR” //字符串不是null
      • -z -z “$STR” //字符串是null
      • 注意:
        在引用变量做字符串测试时,一定要加引号
        操作符两侧必须有空格
        [ … ]中括号内两侧必须有空格
    2. 文件测试:

      • -r -r filename //filename文件是否可读
      • -w -w filename //filename文件是否可写
      • -s -s filename //filename文件是否存在并且长度非0
      • -f -f filename //filename文件是否是普通文件
      • -d -d filename //filename文件是否是目录文件
      touch xx; [ -s xx ]; echo $?
      [ -f xx ]; echo $? 
      
    3. 算术表达式测试:
      利用$(())计算算算术表达式
      利用字符串比较

      [ $((2+3)) = 5 ]; echo $?输出0 //字符串比较
      i=3; [ $((i+7)) = 10 ]; echo $?输出0
      中括号内接受算术表达式:[ $((3+2 > 1)) ]; echo $?输出0
      $((3+2 > 1)); echo $?输出1
      

      注意:在if中使用算术表达式,Bash中扩展(()),但dash中有错

    4. 空指令用冒号或true来表示。

      case $1 in
      -f)
         … ;;
      -d | --directory) #竖线表示或,而[...]表示从中选取一个
         … ;;
      *)
         … ;;
      esac
      

8-循环

  1. Shell提供三种循环:for、while、until
    循环与分支类似,都带有一定的结构,是shell语言的支持

    • 基本格式如下
    for variable in list-of-values; do
    …
    done
    

    注意:list-of-values用$IFS隔开,缺省是空格、tab、回车
    eg.

    #! /bin/sh
    echo
    for count in 1 2 3; do #注意这里的变量没有$
    echo “In the loop for $count times”
    done
    
    #! /bin/sh
    read filename
    for FILE in $filename; do
    echo “filename is $FILE\n”
    done
    

    注意:read是一个builtin命令,它从标准输入读入一行

    • 表示枚举所有参数
    for variable; do …
    
  2. While循环的格式如下

    while [ condition ]; do
    …
    done
    

    [ condition ]等价于前述的test命令
    eg.

    #! /bin/sh
    carryon=Y
    while [ $carryon = Y ]; do
    printf “I do the job as long as you type Y: ”
    read $carryon
    done
    
    #! /bin/sh
    count=1
    while [ $((count < 10)) = “1” ]; do
    echo $count
    count=$((count+1))
    done
    
  3. Until循环的格式如下

    until [ condition ]; do
    …
    done
    

    Until表示条件为假时,执行循环体

    #! /bin/sh
    count=1
    until [ $((count < 10)) = “0” ]; do
    echo $count
    count=$((count+1))
    done
    

9-函数

  1. 函数定义
    [function] funname() #()不可以带参数
    {

    }

  2. 函数引用,类似于普通命令

    • 参数传递
    • 但是函数执行,类似于内置命令,不会新fork一个shell
    • return n表示函数返回值
  3. . command命令执行command,但不会去fork一个新进程,修改了.bashrc文件,需要执行

  4. printf命令兼容所有shell,其命令方式与c类似
    echo命令参数不兼容
    count=3
    printf “count=%d\n” $count

  5. df显示可用空间
    du统计文件或者目录的磁盘使用情况

    tar zcfv压缩成.tar.gz文件
    tar zxfv解压.tar.gz文件
    tar Jcfv压缩成.tar.xz文件
    tar Jxfv解压.tar.xz文件
    tar jcfv压缩成.tar.bz2文件
    tar jxfv解压.tar.bz2文件

  6. chmod修改文件目录的访问权限
    [ugoa]±=rwx
    chown修改文件目录的owner
    chgrp修改文件目录的group
    /etc/profile
    /etc/bash.bashrc
    /etc/init.d/networking

作业
习题:6、7、8
阅读:/etc/rc5.d/S01ssh, /etc/rc5.d/S01cron
编程:利用curl、wget,编写一个脚本从cn.bing.com下载当日墙纸

13 编写shell脚本


  1. 信号命令
    在unix系统中,信号被设计为“软中断”
    进程类比于一个程序,信号从各个侧面完整的模拟了中断机制

    • 中断掩码 信号掩码
    • 中断源 信号
    • 不可屏蔽中断 不可屏蔽信号
    • ISR 信号处理函数
      信号列表64个
    • kill –l
    • kill –n pid

    trap设置进程捕获函数:trap “命令” n
    忽略信号:trap “ ” n
    恢复缺省:trap n

  2. 终端命令
    stty设定终端模式

    • stty –echo禁止回显,输入口令时
    • stty echo打开回显
      tput控制终端输出缓冲
    • tput clear清屏
    • tput cup row column移动光标到row行column列
  3. 程序

补充命令


  1. sed

  2. tr

  3. shift

  4. eval

    • 编写一个脚本,输入变量名,然后输出该变量的值
    • eval echo $$1
  5. $()

    • 等价于重音符号
    • echo date
    • echo $(date)
    • echo $(ls -al)
  6. break
    continue

  7. true
    false
    :

  8. return 函数返回值

  9. ! command 求反
    ! ls -al
    echo ? t e s t ! “ ? test ! “ ?test!s” = “hello”
    [ ! “$s” = “hello” ]

  10. 条件与或

    • [ -z $VAR ] && [ ${VAR2} = 3 ]
    • [ -z $VAR ] || [ ${VAR2} = 3 ]

    条件非

    • [ ! ${VAR2} = 3 ]
  11. unset VAR
    [ $VAR = “hello” ]
    [ “$VAR” = “hello” ]
    

    要确定VAR是否已经定义,否则是语法错误

  12. case的匹配模式

    • *)
    • -v|–verbose)
    • -v*)
    • -v[hc])
    • -v?)
  13. $@ vs $*

#! /bin/sh
for i in "$@"; do
   case $i in
      -v) echo "verbose";;
      -k) echo "kite";;
      *) echo "default";;
   esac
done

测试:

  • @ − > “ @ -> “ @>@”
  • ∗ − > “ * -> “ >*”
  • ./a.sh “-k -v”
  • ./a.sh -k -v

结论:使用”$@”

作业:
搜索/exam目录下.txt文件,然后将以\r\n结尾的dos文本文件,修改为unix结尾的\n文件,同时将原dos文件保留为.txt.bak文件
求解斐波那契数列,例如./fab.sh 5输出
0 1 1 2 3 5
编写一个脚本,接受多个输入参数,输出最大值,./greatest 3 9 5,输出为:
The largest number is: 9
利用case语句编写脚本判断选项:
-d选项输出debug
-v选项输出verbose
其它选项输出usage $0 -d|-v

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45151415/article/details/130185454

智能推荐

解决win10/win8/8.1 64位操作系统MT65xx preloader线刷驱动无法安装_mt65驱动-程序员宅基地

文章浏览阅读1.3w次。转载自 http://www.miui.com/thread-2003672-1-1.html 当手机在刷错包或者误修改删除系统文件后会出现无法开机或者是移动定制(联通合约机)版想刷标准版,这时就会用到线刷,首先就是安装线刷驱动。 在XP和win7上线刷是比较方便的,用那个驱动自动安装版,直接就可以安装好,完成线刷。不过现在也有好多机友换成了win8/8.1系统,再使用这个_mt65驱动

SonarQube简介及客户端集成_sonar的客户端区别-程序员宅基地

文章浏览阅读1k次。SonarQube是一个代码质量管理平台,可以扫描监测代码并给出质量评价及修改建议,通过插件机制支持25+中开发语言,可以很容易与gradle\maven\jenkins等工具进行集成,是非常流行的代码质量管控平台。通CheckStyle、findbugs等工具定位不同,SonarQube定位于平台,有完善的管理机制及强大的管理页面,并通过插件支持checkstyle及findbugs等既有的流..._sonar的客户端区别

元学习系列(六):神经图灵机详细分析_神经图灵机方法改进-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏27次。神经图灵机是LSTM、GRU的改进版本,本质上依然包含一个外部记忆结构、可对记忆进行读写操作,主要针对读写操作进行了改进,或者说提出了一种新的读写操作思路。神经图灵机之所以叫这个名字是因为它通过深度学习模型模拟了图灵机,但是我觉得如果先去介绍图灵机的概念,就会搞得很混乱,所以这里主要从神经图灵机改进了LSTM的哪些方面入手进行讲解,同时,由于模型的结构比较复杂,为了让思路更清晰,这次也会分开几..._神经图灵机方法改进

【机器学习】机器学习模型迭代方法(Python)-程序员宅基地

文章浏览阅读2.8k次。一、模型迭代方法机器学习模型在实际应用的场景,通常要根据新增的数据下进行模型的迭代,常见的模型迭代方法有以下几种:1、全量数据重新训练一个模型,直接合并历史训练数据与新增的数据,模型直接离线学习全量数据,学习得到一个全新的模型。优缺点:这也是实际最为常见的模型迭代方式,通常模型效果也是最好的,但这样模型迭代比较耗时,资源耗费比较多,实时性较差,特别是在大数据场景更为困难;2、模型融合的方法,将旧模..._模型迭代

base64图片打成Zip包上传,以及服务端解压的简单实现_base64可以装换zip吗-程序员宅基地

文章浏览阅读2.3k次。1、前言上传图片一般采用异步上传的方式,但是异步上传带来不好的地方,就如果图片有改变或者删除,图片服务器端就会造成浪费。所以有时候就会和参数同步提交。笔者喜欢base64图片一起上传,但是图片过多时就会出现数据丢失等异常。因为tomcat的post请求默认是2M的长度限制。2、解决办法有两种:① 修改tomcat的servel.xml的配置文件,设置 maxPostSize=..._base64可以装换zip吗

Opencv自然场景文本识别系统(源码&教程)_opencv自然场景实时识别文字-程序员宅基地

文章浏览阅读1k次,点赞17次,收藏22次。Opencv自然场景文本识别系统(源码&教程)_opencv自然场景实时识别文字

随便推点

ESXi 快速复制虚拟机脚本_exsi6.7快速克隆centos-程序员宅基地

文章浏览阅读1.3k次。拷贝虚拟机文件时间比较长,因为虚拟机 flat 文件很大,所以要等。脚本完成后,以复制虚拟机文件夹。将以下脚本内容写入文件。_exsi6.7快速克隆centos

好友推荐—基于关系的java和spark代码实现_本关任务:使用 spark core 知识完成 " 好友推荐 " 的程序。-程序员宅基地

文章浏览阅读2k次。本文主要实现基于二度好友的推荐。数学公式参考于:http://blog.csdn.net/qq_14950717/article/details/52197565测试数据为自己随手画的关系图把图片整理成文本信息如下:a b c d e f yb c a f gc a b dd c a e h q re f h d af e a b gg h f bh e g i di j m n ..._本关任务:使用 spark core 知识完成 " 好友推荐 " 的程序。

南京大学-高级程序设计复习总结_南京大学高级程序设计-程序员宅基地

文章浏览阅读367次。南京大学高级程序设计期末复习总结,c++面向对象编程_南京大学高级程序设计

4.朴素贝叶斯分类器实现-matlab_朴素贝叶斯 matlab训练和测试输出-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏12次。实现朴素贝叶斯分类器,并且根据李航《统计机器学习》第四章提供的数据训练与测试,结果与书中一致分别实现了朴素贝叶斯以及带有laplace平滑的朴素贝叶斯%书中例题实现朴素贝叶斯%特征1的取值集合A1=[1;2;3];%特征2的取值集合A2=[4;5;6];%S M LAValues={A1;A2};%Y的取值集合YValue=[-1;1];%数据集和T=[ 1,4,-1;..._朴素贝叶斯 matlab训练和测试输出

Markdown 文本换行_markdowntext 换行-程序员宅基地

文章浏览阅读1.6k次。Markdown 文本换行_markdowntext 换行

错误:0xC0000022 在运行 Microsoft Windows 非核心版本的计算机上,运行”slui.exe 0x2a 0xC0000022″以显示错误文本_错误: 0xc0000022 在运行 microsoft windows 非核心版本的计算机上,运行-程序员宅基地

文章浏览阅读6.7w次,点赞2次,收藏37次。win10 2016长期服务版激活错误解决方法:打开“注册表编辑器”;(Windows + R然后输入Regedit)修改SkipRearm的值为1:(在HKEY_LOCAL_MACHINE–》SOFTWARE–》Microsoft–》Windows NT–》CurrentVersion–》SoftwareProtectionPlatform里面,将SkipRearm的值修改为1)重..._错误: 0xc0000022 在运行 microsoft windows 非核心版本的计算机上,运行“slui.ex