Bootstrap

Linux - 易错知识点整理(待更新)

Linux - 易错知识点整理(待更新)

本文根据CSDN Linux进阶技能树整理的易错知识点(带),参考资料Linux常用命令大全(非常全!!!)Linux面试题(2020最新版)(带问/练),2019全新Shell脚本从入门到精通教程

参考Linux面试题(2020最新版)

0、命令选项和参数

参考Linux常用基本命令及选项参数总结Linux中shell命令的参数和选项Linux中命令选项及参数简介

  • Linux命令使用须知:

    • 大多数命令都有各种参数和选项

    • 大多数命令的参数可以组合使用(相斥参数除外);

    • 用“命令 --help”或者“man 命令”可以获取相应命令的详细用法;

    • 命令/工具不同版本所支持的参数可能会有所差异;

    • 命令区分大小写,包括参数;

    • Shell 支持 TAB 键命令补齐,输入命令开头字母,按 TAB 键能补齐命令。

    • 命令后面跟着的“选项”(英文options)或“参数”(英文arguments),即Linux中命令格式为:command options argument 有些命令不需要选项也不需要参数,但有的命令在运行时需要多个选项或参数,命令格式也会按照命令+选项+参数的方式进行排列

    • 选项[options] 是用于调整命令执行行为的开关,即选项不同决定了命令的显示结果不同;

    • 参数[arguments] 是指定命令的作用对象

  • [options]选项:包含短选项和长选项

    选项是调整命令执行行为的开关,即,选项不同决定了命令的显示结果不同

    选项分为长选项和短选项。

    • 短选项:比如-h-l-s等。(-后面接单个字母)

      • 短选项都是使用‘-’引导,当有多个短选项时,各选项之间使用空格隔开。

      • 有些命令的短选项可以组合,比如 -l –h 可以组合为–lh

      • 有些命令的短选项可以不带-,这通常叫作BSD风格的选项,比如ps aux

      • 有些短选项需要带选项本身的参数,比如-L 512M

    • 长选项:比如--help--list等。(--后面接单词)

      • 长选项都是完整的单词

      • 长选项通常不能组合

      • 如果需要参数,长选项的参数通常需要‘=’,比如–size=1G

  • [arguments]参数:可以包含短参数和长参数,比如iptables(参考Linux iptables命令详解(参数--dport用于匹配目标端口)

    参数是指命令的作用对象

    ls命令,不加参数的时候显示是当前目录,也可以加参数,如ls /dev, 则输出结果是/dev目录。

1、文件管理
  • 【练】登录linux后,哪个是用户名,哪个是主机名?(用户名@主机名),参考更改用户名@主机名
    Note:在root@localhost:~$

    • $ :命令提示符,如果是root用户则提示符是#;
    • edu: 主机短名称
    • @: 分隔符.
    • csdn: 表示当前的登陆用户,这里是使用csdn账户登陆。
  • 【练】如何使用touch创建空文件?(如果文件不存在,touch会创建空文件;如果存在则会更新文件的时间戳;-c可以避免touch创建新文件),可参考Linux命令之touch命令touch命令详解

    Note

    • touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件

    • 语法

      touch [-acfm][-d<日期时间>][-r<参考文件或目录>] [-t<日期时间>][--help][--version][文件或目录…]
      
    • 案例分析

      $ ls -l testfile                #查看文件的时间、读写权限属性、用户和用户组信息  
      #原来文件的修改时间为16:09  
      -rw-r--r-- 1 hdd hdd 55 2011-08-22 16:09 testfile  $ touch testfile                #修改文件时间属性为当前系统时间  
      $ ls -l testfile                #查看文件的时间属性  
      #修改后文件的时间属性为当前系统时间  
      -rw-r--r-- 1 hdd hdd 55 2011-08-22 19:53 testfile  
      
  • 【练】如何获取绝对路径(pwd)?如何利用相对路径回到上一级目录(cd..)?

  • 【练】如何删除文件?【练】如何删除目录?,参考【Linux】rm 命令:删除文件/文件夹linux 命令:rm 详解

    Note

    • rm命令用于删除一个目录中的一个或多个文件或目录,如果没有使用 -r 选项,则 rm 不会删除目录。如果使用 rm 来删除文件,通常仍可以将该文件恢复原状。

    • 案例

      $ rm -f filename   #强制删除文件,不用询问确认
      
      $ rm -i *.log  #删除任何 .log 文件,删除前逐一询问确认
      
      $ rm -rf fileDir  #递归删除目录, fileDir目录及子目录中所有档案删除,并且不用一一确认:
      
  • 【练】如何复制目录和文件?,参考Linux 命令之 cp – 复制文件或目录
    Note

    • cp命令将源文件复制至目标文件,或将多个源文件复制至目标目录

      注意:命令行复制,如果目标文件已经存在会提示是否覆盖,而在 shell 脚本中,如果不加 -i 参数,则不会提示,而是直接覆盖!

      -i 提示
      -r 复制目录及目录内所有项目
      -a 复制的文件与原文件时间一样
      
    • 实例

      • 1)复制 a.txttest 目录下,保持原文件时间,如果原文件存在提示是否覆盖

        cp -ai a.txt test
        
      • 2)为 a.txt 建议一个链接(快捷方式)

        cp -s a.txt link_a.txt
        
  • 【练】如何移动目录和文件?如何重命名文件?,参考linux怎么将一个文件移动到另一个目录下

    Note

    • mv命令用于移动文件修改文件名,根据第二参数类型:如目录,则移动文件;如为文件则重命名该文件。当第二个参数为目录时,第一个参数可以是多个以空格分隔的文件或目录,然后移动第一个参数指定的多个文件到第二个参数指定的目录中。

    • 案例

      • 1)将文件 test.log 重命名为 test1.txt
      mv test.log test1.txt
      
      • 2)将文件 log1.txt,log2.txt,log3.txt 移动到根的 test3 目录中
      mv log1.txt log2.txt log3.txt /test3
      
      • 3)将文件 file1 改名为 file2,如果 file2 已经存在,则询问是否覆盖
      mv -i log1.txt log2.txt
      
      • 4)移动当前文件夹下的所有文件到上一级目录
      mv * ../
      
  • 【练】如何重命名目录和文件?(mvrename,文件重命名看上一问),参考linux下文件的重命名方法(mvLinux rename命令(rename支持通配符和正则表达式)

  • 【问】标准化输出: echo 详解

    Note

    • echo命令的功能是写内容到标准输出。

      用法echo [-neE] [ARG ...]
      描述:在标准输出上显示由单个空格字符分隔并后跟换行符的 ARG

      选项-n 不加换行符;-e 启用对后续反斜杠转义;-E 明确禁止反斜杠转义。

      echo 支持的转义符号:

      在这里插入图片描述

    • 例子:

      echo -e 'aaa\bbbb'
      ---
      aabbb
      
      echo -E 'aaa\bbbb'
      ---
      aaa\bbbb
      
      echo -e 'aaa\nbbb'
      ---
      aaa
      bbb
      
      echo -E 'aaa\nbbb'
      ---
      aaa\nbbb
      
  • 【问】Linux中>、>>、和2>&1的含义,参考Linux中>>>、和2>&1的含义

    Note

    • >:直接把内容生成到指定文件,会覆盖源文件中的内容。

    • >>尾部追加,不会覆盖掉文件中原有的内容,相当于append2>&1

    • &:把该命令以后台的job的形式运行,可用jobs -l查看

    • 2>&1含义是:这条命令就是相当于把标准错误重定向到标准输出以后台的形式运行。其中:

      0 表示stdin标准输入
      1 表示stdout 标准输出
      2 表示stderr 标准错误

  • 【练】如何查看文件全部内容?( -n path在查看文件时可以显示出行号),参考linux的cat命令(cat查看/合并/创建/追加)cat -n和-b的区别

    Note

    • cat命令用于连接文件并打印到标准输出设备上。

    • cat命令主要有三大功能:

      • 1)一次显示整个文件

        cat filename
        
        • -b有内容的行前面显示行号
        • -n空行内容也会显示行号
      • 2)从键盘创建一个文件:参考使用cat写入内容到指定文件

        cat > filename
        
        cat >log.txt <<EOF
        >Hello
        >World
        >PWD=$(pwd)
        >EOF
        ls -l log.txt
        cat log.txt
        Hello
        World
        

        只能创建新文件,不能编辑已有文件。

      • 3)将几个文件合并为一个文件:

        cat file1 file2 > file
        
  • 【练】如何查看长内容的文件?(head file -n 2查看文件头2行文本; tail file -n 2查看文件尾2行文本),参考linux 查看大文件内容

    Note

    • tail命令用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理。常用查看日志文件。常用参数:

      -f 循环读取(常用于查看递增的日志文件)
      -n<行数> 显示行数(从后向前)
      

      例如:循环读取逐渐增加的文件内容:

      ping 127.0.0.1 > ping.log &  #>表示覆盖,&表示后台运行,可使用 jobs -l 查看
      
      tail -f ping.log
      
    • head 用来显示档案的开头至标准输出中,默认 head 命令打印其相应文件的开头 10 行。常用参数:

      -n<行数> 显示的行数(行数为复数表示从最后向前数)
      
      • 1)显示 1.log 文件中前 20 行

        head 1.log -n 20
        
      • 2)显示 1.log 文件前 20 字节

        head -c 20 log2014.log
        
      • 3)显示 t.log最后 10 行

        head -n -10 t.log
        
  • 【练】如何分页查看文件内容?(moreless,参考Linux命令 - less命令Linux less 命令使用介绍

    Note

    • more命令功能类似于 cat, more 会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示

      lessmore 类似,但使用 less 可以随意浏览文件,而 more 仅能向前移动,却不能向后移动,而且less查看之前不会加载整个文件

    • more命令:

      • 命令参数:

        +n      从笫 n 行开始显示
        -n       定义屏幕大小为n行
        +/pattern 在每个档案显示前搜寻该字串(pattern),然后从该字串前两行之后开始显示 
        -c       从顶部清屏,然后显示
        -d       提示“Press space to continue,’q’ to quit(按空格键继续,按q键退出)”,禁用响铃功能
        -l        忽略Ctrl+l(换页)字符
        -p       通过清除窗口而不是滚屏来对文件进行换页,与-c选项相似
        -s       把连续的多个空行显示为一行
        -u       把文件内容中的下画线去掉
        
      • 操作命令:

        Enter    向下 n 行,需要定义。默认为 1 行
        Ctrl+F   向下滚动一屏
        空格键  向下滚动一屏
        Ctrl+B  返回上一屏
        =       输出当前行的行号
        :f     输出文件名和当前行的行号
        V      调用vi编辑器
        !命令   调用Shell,并执行命令
        q       退出more
        
      • 案例:

        1)显示文件中从第3行起的内容

        more +3 text.txt
        

        2)在所列出文件目录详细信息,借助管道使每次显示 5 行

        ls -l | more -5
        

        按空格显示下 5 行。

    • less命令:

      • 命令参数:

        -b   <缓冲区大小> 设置缓冲区的大小。
        -e   当文件显示结束后,自动离开。
        -f   强迫打开特殊文件,例如外围设备代号、目录和二进制文件。
        -g   只标志最后搜索的关键词。
        -i   忽略搜索时的大小写。
        -m   显示类似more命令的百分比。
        -N   显示每行的行号。
        -o   <文件名> 将less 输出的内容在指定文件中保存起来。
        -Q   不使用警告音。
        -s   显示连续空行为一行。
        -S   行过长时间将超出部分舍弃。
        -x   <数字> 将“tab”键显示为规定的数字空格。
        
      • 常用操作命令:
        打开一个文件后,可以使用以下操作命令,搜索时整个文本中匹配的部分会被高亮显示

        操作    功能说明
        /字符串    向下搜索“字符串”的功能。n 向下查找;N 向上查找
        ?字符串    向上搜索“字符串”的功能。 n 向上查找;N 向下查找
        n    重复前一个搜索(与 / 或 ? 有关)。
        N    反向重复前一个搜索(与 / 或 ? 有关)。
        b    向后翻一页。
        d    向后翻半页。
        h    显示帮助界面。
        Q    退出less 命令。
        u    向前滚动半页
        y    向前滚动一行
        空格键    滚动一行
        回车键    滚动一页
        [pagedown][pgdn]键    向下翻动一页
        [pageup][pgup]键    向上翻动一页
        
      • 案例:

        • 1)浏览多个文件

          less log1.txt log2.txt
          

          当打开多个文件时,使用命令在多个文件之间切换,:n 浏览下一个文件log2.txt:p 浏览前一个文件log1.txt

        • 2)ps查看进程信息并利用管道,通过less分页显示:

          ps -ef |less
          ---
          UID          PID    PPID  C STIME TTY          TIME CMD
          root           2       0  0 13:42 ?        00:00:00 [kthreadd]
          root           3       2  0 13:42 ?        00:00:00 [rcu_gp]
          root           4       2  0 13:42 ?        00:00:00 [rcu_par_gp]
          root           5       2  0 13:42 ?        00:00:00 [kworker/0:0-events]
          root           6       2  0 13:42 ?        00:00:00 [kworker/0:0H-kblockd]
          root           7       2  0 13:42 ?        00:00:00 [kworker/0:1-events]
          root           9       2  0 13:42 ?        00:00:00 [mm_percpu_wq]
          root          10       2  0 13:42 ?        00:00:00 [ksoftirqd/0]
          root          11       2  0 13:42 ?        00:00:00 [rcu_sched]
          root          12       2  0 13:42 ?        00:00:00 [migration/0]
          root          13       2  0 13:42 ?        00:00:00 [idle_inject/0]
          root          14       2  0 13:42 ?        00:00:00 [cpuhp/0]
          root          15       2  0 13:42 ?        00:00:00 [cpuhp/1]
          :
          
  • 【练】如何使用vi编辑文本(插入模式和底行模式),参考linux vi命令vi查找并替换字符(底行模式进行全局替换::%s/查找字符串/要替换的字符串/gLinux vim 文本替换 %s/原文/替换文本/g

    Note

    • vi/vim 共分为三种模式,分别是命令模式(Command mode)输入模式(Insert mode)和底行命令模式(Last line mode)。

      命令模式通过i,a,o进入输入模式,通过:进入底行模式

      • ​ 按「i」切换进入插入模式「insert mode」,按"i"进入插入模式后是从光标当前位置开始输入文件;

      • 按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;

      • 按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。

      输入模式通过esc回到命令模式;

      底行命令通过enter回到命令模式;

      在这里插入图片描述

    • 在底行模式下替换字符串::%s/查找字符串/要替换的字符串/g,eg:把10.1.1.2.1.1替换成10.1.1.256.1.128

      $cat test.txt
      10.1.1.2.1.1
      
      :%s/\(10.1.1\).2.\(1\).1/\1.256.\2.128/g
      

      Note

      • \(10.1.1\)为正则表达式,表示保留10.1.1的字符串
      • 其中\1转义为10.1.1\2转义为1
  • 【练】grep命令(全局正则式搜索),参考Linux面试题(2020最新版)

    Note

    • 强大的文本搜索命令,grep(Global Regular Expression Print) 全局正则表达式搜索,命令格式为grep [option] pattern file|dir

      常用参数

      -c :只输出匹配模式的行数。
      -h :只显示匹配的行,不显示文件名。
      -i :忽略匹配时的大小写。
      -l :只显示文件名列表。
      -n :显示匹配的行及其行号。
      -r :显示文件所在目录即路径。
      -v :输出所有不匹配的行。
      -e exp : 指定该选项的表达式,可以多次使用。
      -f file :指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
      -E :将样式为延伸的正则表达式来使用。
      -w :匹配整个单词。
      -r :明确要求搜索子目录。
      -d skip :忽略子目录。
      -o :只打印匹配行的匹配部分,每个这样的部分在单独的输出行上。
      \ :忽略正则表达式中特殊字符的原有含义。
      [ ]:单个字符,如[A]即A符合要求。
      [ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求。
      .:所有的单个字符。
      *:所有字符,长度可以为0。
      
      -A n : 除了显示符合范本样式的那一行之外,并显示该行之后n行。
      -B n : 除了显示符合范本样式的那一行之外,并显示该行之前n行。
      -C n : 除了显示符合范本样式的那一行之外,并显示该行之前以及之后n行。
      

      grep的规则表达式:

      ^  #锚定行的开始 如:'^grep'匹配所有以grep开头的行。 
      $  #锚定行的结束 如:'grep$'匹配所有以grep结尾的行。 
      .  #匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。  
      *  #匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。
      .*   #一起用代表任意字符。  
      []   #匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。 
      [^]  #匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。  
      \(..\)  #标记匹配字符,如'\(love\)',love被标记为1。   
      \<      #锚定单词的开始,如:'\<grep'匹配包含以grep开头的单词的行。
      \>      #锚定单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。
      x\{m\}  #重复字符x,m次,如:'0\{5\}'匹配包含5个o的行。 
      x\{m,\}  #重复字符x,至少m次,如:'o\{5,\}'匹配至少有5个o的行。  
      x\{m,n\}  #重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。  
      \w    #匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,然后是p。  
      \W    #\w的反置形式,匹配一个或多个非单词字符,如点号句号等。  
      \b    #单词锁定符,如: '\bgrep\b'只匹配grep。
      
    • 常见例子:

      • 1)查找指定进程名称

        ps -ef 
        ---
        root      45563    947  0 12:20 ?        00:00:00 sshd: dpf [priv]
        dpf       45573  45563  0 12:20 ?        00:00:05 sshd: dpf@pts/1
        dpf       45574  45573  0 12:20 pts/1    00:00:00 -bash
        root      48838  45574  0 13:47 pts/1    00:00:00 su
        root      48839  48838  0 13:48 pts/1    00:00:00 bash
        dpf       48871  19682  0 13:51 ?        00:00:00 /usr/lib/openssh/sftp-server
        root      49382   9303  0 13:59 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.17.0.3 -container-port 5000
        root      49391   4967  0 13:59 ?        00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/5e6c5fb6c0441a6b09af6a19f7a4f9b33a887eaa
        root      49412  49391  0 13:59 pts/0    00:00:00 /bin/bash
        root      52222      2  0 14:07 ?        00:00:03 [kworker/0:2]
        root      52695      2  0 16:17 ?        00:00:00 [kworker/2:0]
        root      52713      2  0 16:29 ?        00:00:00 [kworker/3:0]
        root      52786      2  0 16:43 ?        00:00:00 [kworker/3:2]
        root      52806      2  0 16:54 ?        00:00:01 [kworker/0:1]
        root      52883      2  0 17:09 ?        00:00:00 [kworker/1:1]
        root      52903      2  0 17:20 ?        00:00:00 [kworker/2:1]
        root      52921      2  0 17:34 ?        00:00:00 [kworker/1:0]
        root      52925      2  0 17:35 ?        00:00:00 [kworker/u256:2]
        root      52982      2  0 17:41 ?        00:00:00 [kworker/u256:0]
        root      52997      2  0 17:45 ?        00:00:00 [kworker/0:0]
        root      52999  48839  0 17:47 pts/1    00:00:00 ps -ef
        
        ps -ef | grep kworker
        ---
        root          5      2  0 10月26 ?      00:00:00 [kworker/0:0H]
        root         15      2  0 10月26 ?      00:00:00 [kworker/1:0H]
        root         20      2  0 10月26 ?      00:00:00 [kworker/2:0H]
        root         25      2  0 10月26 ?      00:00:00 [kworker/3:0H]
        root        284      2  0 10月26 ?      00:00:00 [kworker/3:1H]
        root        290      2  0 10月26 ?      00:00:00 [kworker/2:1H]
        root        569      2  0 10月26 ?      00:00:00 [kworker/u257:0]
        root        574      2  0 10月26 ?      00:00:00 [kworker/u257:2]
        root        966      2  0 10月26 ?      00:00:00 [kworker/0:1H]
        root       1079      2  0 10月26 ?      00:00:00 [kworker/1:1H]
        root      52222      2  0 14:07 ?        00:00:03 [kworker/0:2]
        root      52695      2  0 16:17 ?        00:00:00 [kworker/2:0]
        root      52713      2  0 16:29 ?        00:00:00 [kworker/3:0]
        root      52786      2  0 16:43 ?        00:00:00 [kworker/3:2]
        root      52806      2  0 16:54 ?        00:00:01 [kworker/0:1]
        root      52883      2  0 17:09 ?        00:00:00 [kworker/1:1]
        root      52903      2  0 17:20 ?        00:00:00 [kworker/2:1]
        root      52921      2  0 17:34 ?        00:00:00 [kworker/1:0]
        root      52925      2  0 17:35 ?        00:00:00 [kworker/u256:2]
        root      52982      2  0 17:41 ?        00:00:00 [kworker/u256:0]
        root      52997      2  0 17:45 ?        00:00:00 [kworker/0:0]
        root      53001  48839  0 17:48 pts/1    00:00:00 grep --color=auto kworker
        
      • 2)查找指定进程个数

         ps -ef | grep kworker -c
         ---
         22
        
      • 3)从文件中读取关键词

        cat > test1.txt << EOF
        > Hello world
        > Hello boy
        > Hello girl
        > Hello lady
        > Hello sir
        > Hello sir1
        > EOF
        ---
        cat test1.txt | grep Hello
        Hello world   
        Hello boy
        Hello girl
        Hello lady
        Hello sir
        Hello sir1
        ---
        Hello位置在控制台会标红
        
      • 4)从文件夹中递归查找以grep开头的行,并只列出文件

         grep -lR '^grep' /tmp
        
      • 5)查找以"sir"结尾的行内容

        grep 'sir$' test1.txt
        ---
        Hello sir
        
      • 6)显示包含 sir或者 sir1字符串的内容行

        grep -E 'sir|sir1' test1.txt
        ---
        Hello sir
        Hello sir1
        
  • 【问】wd命令统计文件内容数,参考Linux面试题(2020最新版)

    Note

    • wc(word count)功能为统计指定的文件中字节数、字数、行数,并将统计结果输出。常用参数如下:

      -c 统计字节数
      -l 统计行数
      -m 统计字符数
      -w 统计词数,一个字被定义为由空白、跳格或换行字符分隔的字符串
      
    • 例子:

      1)查找文件的 行数 单词数 字节数 文件名

      wc test1.txt   
      6 12 65 test1.txt   
      

      2)查找文件的 行数 和 单词数

      wc test1.txt -l -w  
      6 12 test1.txt 
      
  • 【练】如何查找文件?(根据查找路径的不同,划分成whereis,which,locate和find(耗资源,不建议使用)),参考Linux命令之find命令(按指定文件大小size/文件类型type查)寻找文件的技巧Linux下4个查找命令which、whereis、locate、find的总结

    Note

    • which命令(从binsbin文件夹下查找)

      • 原理:执行which命令时,which在当前环境变量PATH中依次寻找能够匹配所找命令名字的可执行文件名,不加-a选项,返回第一个匹配的可执行文件的路径,否则依次返回满足条件的所有可执行文件的路径名。

      • 适用场合:一般用于查找命令/可执行文件所在的路径。有时候可能在多个路径下存在相同的命令,该命令可用于查找当前所执行的命令到底是哪一个位置处的命令。

    • whereis命令:(从sbindocman文件夹下查找)

      • 原理whereis命令首先会去掉filename中的前缀空格和以.开头的任何字符,然后再在数据库(var/lib/slocate/slocate.db)中查找与上述处理后的filename相匹配的二进制文件、源文件和帮助手册文件, 使用之前可以使用updatedb命令手动更新数据库。

      • 适用场合:二进制文件、源文件和帮助手册文件路径的查找。

    • locate命令(全文件模糊查找)

      • 原理:默认情况下(当filename中不包含通配符*),locate给出所有与*filename*相匹配的文件的路径

      • 适用场合没有文件类型性质的模糊查找(你只记得某个文件的部分名称)。

    • find命令(全文件查找)

      • find命令用于在文件树中查找文件,并作出相应的处理:

        find pathname -options [-print -exec -ok ...]
        ---
        pathname: find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。
        

        原理遍历当前工作目录及其子目录,find命令是在硬盘上遍历查找,非常耗硬盘资源,查找效率相比whereislocate较低。

        适用场合:能用whichwhereislocate的时候尽量不要用find

      • 命令选项

        -name 按照文件名查找文件
        -perm 按文件权限查找文件
        -user 按文件属主查找文件
        -group  按照文件所属的组来查找文件。
        -print: find命令将匹配的文件输出到标准输出。
        -exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' {  } \;,注意{   }\;之间的空格。
        -ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。
        -type  查找某一类型的文件,诸如:
           b - 块设备文件
           d - 目录
           c - 字符设备文件
           l - 符号链接文件
           p - 管道文件
           f - 普通文件
        
      • 案例:

        1)在当前目录查找 以 .log 结尾的文件。.代表当前目录(命令为find fileDir -name filename):

        find ./ -name '*.log'
        

        2)查找/opt 目录下 权限为777 的文件

        find /opt -perm 777
        

        3)查找大于 1K 的文件

        find -size +1000c
        

        查找等于 1000 字符的文件

        find -size 1000c
        
    • 四种查找命令的比较:

      在这里插入图片描述

  • 【练】如何压缩/解压一个文件(压缩tar cvfz backup.tar.gz /xxx/和解压tar -zxvf xxx.tar.gz),参考linux命名压缩解压文件

    Note

    • tar 命令:用来压缩和解压文件。tar 本身不具有压缩功能,只具有打包功能,有关压缩及解压是调用其它的功能来完成。打包和压缩是不同的概念:打包是指将一大堆文件或目录变成一个总的文件;压缩则是将一个大的文件通过一些压缩算法变成一个小文件

      常用参数

      -c 建立新的压缩文件
      -f 指定压缩文件
      -r 添加文件到已经压缩文件包中
      -u 添加改了和现有的文件到压缩包中
      -x 从压缩包中抽取文件
      -t 显示压缩文件中的内容
      -z 支持gzip压缩
      -j 支持bzip2压缩
      -Z 支持compress解压文件
      -v 显示操作过程
      
    • 实例:

      1)将文件全部打包成 tar 包

      tar -cvf log.tar 1.log,2.log 或tar -cvf log.*
      

      2)将 /etc 下的所有文件及目录压缩 / 解压到指定目录

      tar -zcvf /tmp/etc.tar.gz /etc  #使用 gz 压缩
      tar -zxvf /tmp/etc.tar.gz /etc  #解压 gz
      
      tar -jcvf /tmp/etc.tar.bz2 /etc  #使用 bzip2 压缩
      tar -jxvf /tmp/etc.tar.bz2 /etc  #解压 bzip2
      

      3)查看刚打包的文件内容(一定加z,因为是使用 gzip 压缩的):

      tar -ztvf /tmp/etc.tar.gz
      

      4)要压缩打包 /home, /etc ,但不要 /home/dmtsai

      tar --exclude /home/dmtsai -zcvf myfile.tar.gz /home/* /etc
      
  • 【练】怎样创建一个快捷方式(即软连接,ln -s source dist,参考软连接与硬链接
    Note

    • 软连接,硬连接和拷贝的区别:

      1)软连接:软连接建立的链接文件与源文件并不是同一个文件, 就是一个快捷方式, inode号也不同;

      2)硬链接 :硬链接实际上是文件的一个别名, 链接文件和源文件实际上是同一个文件, 修改源文件或者硬链接文件, 相互都会改变;

      3)拷贝:复制源文件, 产生一个全新的文件, 与源文件没有关系了, 修改新文件内容与源文件无关;

    • 建立软连接ln -s source dist对文件夹不能建立硬连接,只能建立软连接
      例如执行命令:ln -s /usr /home/csdn/myusr,会在/home/csdn/目录下创建一个myusr的软链接,该软链接指向 /usr 目录
      例如:删除了源文件1,会同时影响目标文件2,下面是无法输出hello的

      执行命令:`touch 1.txt`
      使用`vi 1.txt`编辑并输入"hello",然后保存退出
      执行命令:`ln -s 1.txt 2.txt`
      执行命令:`rm 1.txt`
      执行命令:`cat 2.txt`
      此时,输出:hello
      
    • 建立硬连接ln source dist
      例如:删除了源文件1,并不会影响目标文件2,下面是可以输出hello的

      执行命令:`touch 1.txt`
      使用`vi 1.txt`编辑并输入"hello",然后保存退出
      执行命令:`ln 1.txt 2.txt`
      执行命令:`rm 1.txt`
      执行命令:`cat 2.txt`
      此时,输出:hello
      
2、用户权限管理
  • 【练】如何新增用户?(useradd命令,需要root权限),参考useradd命令Linux下useradd与adduser的区别

    Note

    • useradd创建新用户时,系统是不会帮你在home目录下新建主目录的,且不会提示设置密码。

    • adduser创建新用户时,系统会自动帮你创建主目录,而且会提示设置密码

  • 【练】如何给账户设置密码?(passwd 用户名,参考Linux命令之设置用户密码passwd

    Note

    • 通过 useradd 命令创建的用户初始是没有密码的,需要通过 passwd 命令来为其设置密码,未设置密码的用户不能登录系统。

    • 修改自己的密码时,直接输入 passwd 命令即可,之后会有1次密码输入和1次密码认证;

      修改普通用户的密码时:passwd 用户名

  • 【练】如何切换用户(su 用户名,参考linux系统切换用户

    Note

    • 从root用户切换为一般用户:su 用户名,之后会出现$表示普通用户

    • 从普通用户切换到 root 用户:su root,之后会出现#表示root用户

    【练】如何查看文件的权限?(ls -l 文件名 查看文件权限,用户所有者和组用户),可参考Linux常用命令详解 ls -l命令详解

    Note

    • 使用ls -l会产生长列表格式输出,包含了目录中每个文件的更多的信息,假设查看结果如下:

      drwxr-xr-x 2 csdn csdn 4096 83 17:49 
      

      Code表示对Code目录,所有者可读写执行(wxr)、组用户可读不可写可执行(w-r)以及其他用户可读不可写可执行(w-r

      • 1)第一个字母含义如下:

        ‘d’:目录文件;
        ‘-’:普通文件;
        ‘p’:管理文件;
        ‘l’:链接文件;
        ‘b’:块设备文件;
        ’c‘:字符设备文件;
        ‘s’:套接字文件。

      • 2)后面九个字母分别3个为一组r表示读权限,w表示写权限,x表示可执行权限,-表示无权限),第一组为表示所有者权限,第二组为表示组用户权限,第三组为表示其他用户组的权限。

      • 3)其他列的信息:

        第三列: 该文件或目录的所有者

        第四列: 表示所属的组

        第五列: 文件的大小

        第六列: 月份(最近修改文件的日期)。
        第七列: 多少号(最近修改文件的最后日期)。
        第八列: 几点(最近修改文件的最后日期)。

  • 【练】如何修改文件权限?如何设置文件权限,可参考chmod命令详细用法

    Note

    • chmod命令语法:

      chmod [-cfvR] [–help] [–version] mode file…
      

      参数如下:

      mode : 权限设定字串,格式如下 : [ugoa...][[+-=][rwxX]...][,...],其中
      u 表示该档案的拥有者,g 表示与该档案的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示这三者皆是。
      + 表示增加权限、- 表示取消权限、= 表示唯一设定权限。
      r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该档案是个子目录或者该档案已经被设定过为可执行。
      -c : 若该档案权限确实已经更改,才显示其更改动作
      -f : 若该档案权限无法被更改也不要显示错误讯息
      -v : 显示权限变更的详细资料
      -R : 对目前目录下的所有档案与子目录进行相同的权限变更(即以递回的方式逐个变更)
      --help : 显示辅助说明
      --version : 显示版本
      
    • 执行命令chmod 777 Code 则Code文件的权限为drwxrwxrwx;文件的权限为drwxrwx---,则权限数字为770

    • 两种写法都可以:

      chmod a=rwx file 等价于  chmod 777 file 
      chmod ug=rwx,o=x file 等价于  chmod 771 file 
      
  • 【练】如何修改文件所有者?(chownchange ownerchown test.test 1.txt1.txt的使用权限转换成用户test和所在组testll查看文件权限和归属)【练】如何修改文件所在组?(chownchgrp都可以),可参考Linux命令之chown命令Linux chgrp命令(change group)

    Note

    • chown(即change owner)命令用法:

      chown [参数] user[:group] 文件
      

      参数说明:

      user    新的文件拥有者的使用者 ID
      group    新的文件拥有者的使用者组(group)
      -c    显示更改的部分的信息
      -f    忽略错误信息
      -h    修复符号链接
      -v    显示详细的处理信息
      -R    处理指定目录以及其子目录下的所有文件
      –help    显示辅助说明
      --version    显示版本
      
    • 修改文件所在者:

      执行命令:sudo chown csdn /tmp/yum.log
      执行命令:ll /tmp/yum.log
      输出:-rw------- 1 csdn root 0 54  2020 /tmp/yum.log
      表示文件 yum.log 已授权给用户 csdn
      

      修改文件的用户组(chownchgrp(即change group)都可以):

      #例子1
      [root@s141 test]# chown test.test 1.txt
      [root@s141 test]# ll
      total 0
      -rw-r–r-- 1 test test 0 Nov 22 15:52 1.txt
      drwxrwxr-x 2 test test 6 Nov 21 18:24 a
      
      #例子2
      # 将/usr/meng及其子目录下的所有文件的用户组改为mengxin
      chgrp -R mengxin /usr/meng
      
3、系统管理
  • 【练】如何查看系统进程(ps aux查看系统进程信息,包括内存和cpu的占用信息)【练】如何实时监控进程运行(tophtop可以实时监控cpu和内存的使用情况,而ps不可以),可参考Linux中ps命令详解Linux ps命令 - 菜鸟教程linux之ps命令的使用Linux top命令详解
    Note

    • ps aux中 aux参数的含义:

      a 显示现行终端机下的所有程序,包括其他用户的程序
      u 以用户为主的格式来显示程序状况。
      x 显示所有程序,不以终端机来区分。
      
    • ps 为我们提供了进程的一次性的查看,它所提供的查看结果并不动态连续的;有些时候ps查看得到的进程,通过jps(查看java运行的进程)却查不到,主要原因是psjps通过不同的文件来感知进程是否存在 jps不显示java进程信息

      root@wxx:/dev# jps
      68417 dubhe-data-0.0.1-SNAPSHOT-exec.jar
      68418 dubhe-data-task-0.0.1-SNAPSHOT-exec.jar
      68420 gateway-0.0.1-SNAPSHOT-exec.jar
      11559 nacos-server.jar
      55853 nacos-server.jar
      70988 Jps
      root@wxx:/dev# ps -ef | grep dubhe-data-dcm-0.0.1-SNAPSHOT-exec.jar
      root      79614   8751  0 08:15 pts/0    00:00:00 grep --color=auto dubhe-data-dcm-0.0.1-SNAPSHOT-exec.jar
      root@wxx:/dev# ps -ef | grep admin-0.0.1-SNAPSHOT-exec.jar
      root      92166   8751  0 08:31 pts/0    00:00:00 grep --color=auto admin-0.0.1-SNAPSHOT-exec.jar
      root@wxx:/dev# ps -ef | grep dubhe-data-0.0.1-SNAPSHOT-exec.jar
      root      68417      1  5 08:02 pts/0    00:01:42 java -Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/dubhe-data-dump.hprof -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5004 /Dubhe/exec_jar/dubhe-data-0.0.1-SNAPSHOT-exec.jar --spring.profiles.active=prod
      root      94712   8751  0 08:35 pts/0    00:00:00 grep --color=auto dubhe-data-0.0.1-SNAPSHOT-exec.jar
      root@wxx:/dev#
      

      如果想对进程时间监控,应该用 top 工具

    • linux上进程有5种状态

      • 运行(正在运行或在运行队列中等待)
      • 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号)
      • 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)
      • 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放)
      • 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行)
    • ps aux查看进程时的输出格式

      ps aux | grep dubhe-data-task-0.0.1-SNAPSHOT-exec.jar
      USER    PID  %CPU  %MEM  VSZ  RSS  TTY  STAT  START  TIME  COMMAND
      root       3625  0.0  0.0  16700  1056 pts/0    S+   09:25   0:00 grep --color=auto dubhe-data-task-0.0.1-SNAPSHOT-exec.jar
      root      68418  2.4  5.8 7310400 804128 pts/0  Sl   08:02   2:02 java -Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/dubhe-data-task-dump.hprof -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006 /Dubhe/exec_jar/dubhe-data-task-0.0.1-SNAPSHOT-exec.jar --spring.profiles.active=prod
      

      其中进程状态含义如下所示:

      STAT: 该行程的状态:
          D: 无法中断的休眠状态 (通常 IO 的进程)
          R: 正在执行中
          S: 静止状态
          T: 暂停执行
          Z: 不存在但暂时无法消除
          W: 没有足够的记忆体分页可分配
          <: 高优先序的行程
          N: 低优先序的行程
          L: 有记忆体分页分配并锁在记忆体内 (实时系统或捱A I/O)
      
    • ps j输出格式(不能和ps -ef同时使用):

      root@wxx:/dev# ps -efj | grep dubhe-data-task-0.0.1-SNAPSHOT-exec.jar
      root      68418      1  66047   8751  3 08:02 pts/0    00:01:54 java -Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/dubhe-data-task-dump.hprof -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006 /Dubhe/exec_jar/dubhe-data-task-0.0.1-SNAPSHOT-exec.jar --spring.profiles.active=prod
      root     114159   8751 114158   8751  0 08:59 pts/0    00:00:00 grep --color=auto dubhe-data-task-0.0.1-SNAPSHOT-exec.jar
      root@wxx:/dev# ps j | grep dubhe-data-task-0.0.1-SNAPSHOT-exec.jar
           1  68418  66047   8751 pts/0    114334 Sl       0   1:54 java -Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/dubhe-data-task-dump.hprof -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006 /Dubhe/exec_jar/dubhe-data-task-0.0.1-SNAPSHOT-exec.jar --spring.profiles.active=prod
        8751 114335 114334   8751 pts/0    114334 S+       0   0:00 grep --color=auto dubhe-data-task-0.0.1-SNAPSHOT-exec.jar
      
    • 通过top或者htop可以查看进程和内存占用,但不能查看进程的端口;top 命令可以实时监控系统的进程信息。

  • nohup命令详解(开启守护进程,在后台执行程序(不挂起)),参考linux 命令:nohup 详解

    Note

    • nohup命令的功能是在不挂断的情况下执行命令,默认会输出一个 nohup.out 的文件

      用法

      nohup COMMAND [ARG]...

      nohup OPTION

      • 如果标准输入是终端,则将其从不可读的文件中重定向。 如果标准输出是终端,则尽可能将输出附加到“nohup.out”,否则附加到“$HOME/nohup.out”

      • 如果标准错误是终端,则将其重定向到标准输出。 要将输出保存到 FILE,请使用“nohup COMMAND > FILE”

      选项

      –help 帮助文档

      –version 版本信息

    • 例子:

      后台运行项目(gunicorn是flask web应用的服务器启动模块):

      nohup gunicorn -w 5 -b 0.0.0.0:5000 --certfile=client-1.local.crt --keyfile=client-1.local.key manage:app >> ai_platform.log 2>&1 &
      

      根据项目根目录下的ai_platform.log,查看服务的运行状态:

      tail -10 ai_platform.log
      
  • 【练】查看文件夹大小(du),以及磁盘的使用情况(df,参考du和df命令概述

    Note

    • du命令作用是估计文件系统的磁盘已使用量,常用于查看文件或目录所占磁盘容量。 du命令与df命令不同,df命令是统计磁盘使用情况

      du [选项] [文件或目录名称]
      参数:
      -a--all, 列出所有的文件和目录容量大小而不仅仅列出目录容量大小,默认情况只是统计目录的容量大小,参考示例1
      -B--block-size=SIZE,指定单位大小。
      -b--bytes,以字节为单位列出文件和目录的容量大小。
      -c--total,除了列出文件和目录的容量大小外,列出总的容量大小,参考示例2
      -h--human-readable,以人们易读的方式(KB,MB,GB)显示容量大小,参考示例3
      --si:和-h参数类似,但是单位换算时是以1000进行换算,而不是1024。
      -k:和--block-size=1k类似,以KB为单位。
      -m:和--block-size=1m类似,以MB为单位。
      -s--summarize,仅列出总量,而不列出每个目录和文件的大小,参考示例4
      -S--separate-dirs,和-s参数类似,但是统计时不包含子目录的容量大小。
      --max-depth=N:类似于默认情况的du,但是,递归显示时的递归深度小于等于N。如果--max-depth=0,就相当于-s参数,只统计总量而已,参考示例4。如果--max-depth=1,就相当于du -s 目录/*参考示例5

    • 例子:

      • du查看文件夹的使用量

        du * -sh
        8.9G    dpf
        2.9G    small_ai_platform_deploy_crop.tar
        3.6G    temp
        4.0K    test1.txt
        
      • df查看磁盘的使用情况

        df -TH
        文件系统       类型      容量  已用  可用 已用% 挂载点
        udev           devtmpfs  4.2G     0  4.2G    0% /dev
        tmpfs          tmpfs     836M   19M  818M    3% /run
        /dev/sda2      ext4       44G   37G  5.3G   88% /
        tmpfs          tmpfs     4.2G  316k  4.2G    1% /dev/shm
        tmpfs          tmpfs     5.3M     0  5.3M    0% /run/lock
        tmpfs          tmpfs     4.2G     0  4.2G    0% /sys/fs/cgroup
        /dev/sda1      ext4      487M   69M  388M   15% /boot
        cgmfs          tmpfs     103k     0  103k    0% /run/cgmanager/fs
        tmpfs          tmpfs     836M   29k  836M    1% /run/user/1000
        overlay        overlay    44G   37G  5.3G   88% /var/lib/docker/overlay2/dab756c91d90a1e39d9a5295fed847dab200fb2a54c069b72a8d464e79645242/merged
        shm            tmpfs      68M     0   68M    0% /var/lib/docker/containers/47ef3fd2bcaebc420c5a415c7c3ae941bcfef5e4cbb9bf9d633210c869438932/mounts/shm
        overlay        overlay    44G   37G  5.3G   88% /var/lib/docker/overlay2/ba2f81339b9a9f7142578f9b9bd99e0de3240c1e48f6821ed4db4b89c55f2c02/merged
        shm            tmpfs      68M     0   68M    0% /var/lib/docker/containers/5e6c5fb6c0441a6b09af6a19f7a4f9b33a887eaafc45e43228fd0eb5624a3bd7/mounts/shm
        
4、网络通信
  • 【问】如何查看和配置 Linux 系统的网络接口?(ifconfig,参考ifconfig命令的功能和用法

    Note

    • ifconfig命令用来查看和配置网络设备。当网络环境发生改变时可通过此命令对网络进行相应的配置。命令格式如下:

      ifconfig [网络设备] [参数]
      

      参数说明:

      up: 启动指定网络设备/网卡。
      down:关闭指定网络设备/网卡。该参数可以有效地阻止通过指定接口的IP信息流,如果想永久地关闭一个接口,我们还需要从核心路由表中将该接口的路由信息全部删除。
      arp: 设置指定网卡是否支持ARP协议。
      -promisc:设置是否支持网卡的promiscuous模式,如果选择此参数,网卡将接收网络中发给它所有的数据包
      -allmulti: 设置是否支持多播模式,如果选择此参数,网卡将接收网络中所有的多播数据包
      -a: 显示全部接口信息
      -s: 显示摘要信息(类似于 netstat -i)
      add: 给指定网卡配置IPv6地址
      del:删除指定网卡的IPv6地址
      <硬件地址> :配置网卡最大的传输单元
      mtu<字节数>: 设置网卡的最大传输单元 (bytes)
      ...
      

      ifconfig命令输出说明:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cWTGk2XI-1666872844213)(./img/e208da0aa9634d5c80efe20e09b0f8a7.png)]

      第一行:UP(代表网卡开启状态)RUNNING(代表网卡的网线被接上)MULTICAST(支持组播)MTU:1500(最大传输单元):1500字节
      第二行:网卡的IP地址、子网、掩码
      第四行:连接类型:Ethernet(以太网),txqueuelen是传输区长度大小 
      第五-八行:接收、发送数据包、字节数情况统计
      
    • 案例:

      • 查看所有网络接口及其状态:ifconfig -a

      • 使用 up 和 down 命令启动或停止某个接口:ifconfig eth0 upifconfig eth0 down

  • 【问】如何对外开启端口?(iptables防火墙设置),参考Linux iptables命令详解

    Note

    • iptables 是集成在 Linux 内核中的包过滤防火墙系统使用iptables 可以添加、删除具体的过滤规则,iptables 默认维护着 4 个表和 5 个链,所有的防火墙策略规则都被分别写入这些表与链中。

      “四表”是指 iptables 的功能,默认的 iptable s规则表有filter 表(过滤规则表)、nat 表(地址转换规则表)、mangle(修改数据标记位规则表)、raw(跟踪数据表规则表)
      “五链” 是指内核中控制网络的 NetFilter 定义的 5 个规则链。每个规则表中包含多个数据链:INPUT(入站数据过滤)、OUTPUT(出站数据过滤)、FORWARD(转发数据过滤)、PREROUTING(路由前过滤)和POSTROUTING(路由后过滤),防火墙规则需要写入到这些具体的数据链中。

    • iptables 命令的基本语法格式如下:

      iptables [-t table] COMMAND [chain] CRETIRIA -j ACTION
      

      各参数的含义为:

      • -t:指定需要维护的防火墙规则表 filter、nat、mangle或raw。在不使用 -t 时则默认使用 filter 表。
      • COMMAND:子命令,定义对规则的管理。
      • chain:指明链表
      • CRETIRIA:匹配参数。
      • ACTION:触发动作。

      iptables 命令常用的选项及各自的功能:

      选 项功 能
      -A添加防火墙规则
      -D删除防火墙规则
      -I插入防火墙规则
      -F清空防火墙规则
      -L列出添加防火墙规则
      -R替换防火墙规则
      -Z清空防火墙数据表统计信息
      -P设置链默认规则

      iptables 命令常用匹配参数及各自的功能,命令触发动作及各自的功能见Linux iptables命令详解

  • 案例:

    • 把来源 IP 为 192.168.1.101 访问本机 80 端口的包直接拒绝

      iptables -I INPUT -s 192.168.1.101 -p tcp --dport 80 -j REJECT
      
    • 开启 80 端口,因为web对外都是这个端口

      iptables -A INPUT -p tcp --dport 80 -j ACCEP
      

    另外,要注意使用 iptables save 命令,进行保存。否则,服务器重启后,配置的规则将丢失。

  • 【练】可以使用lsof查看进程已打开的文件,参考Linux下 lsof 命令详解

    Note

    • lsofList Open File 的缩写, 它主要用来获取被进程打开文件的信息,我们都知道,在Linux中,一切皆文件lsof命令可以查看所有已经打开了的文件,比如: 普通文件,目录,特殊的块文件,管道,socket套接字,设备,Unix域套接字等等,同时,它还可以结合 grep 以及ps 命令进行更多的高级搜索。

    • 例子:

      • 输出当前所有活跃进程打开的所有文件(more分页查看,每页10行)

        lsof | more -10
        ---
        lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
              Output information may be incomplete.
        COMMAND     PID   TID        USER   FD      TYPE             DEVICE SIZE/OFF       NODE NAME
        systemd       1              root  cwd       DIR                8,2     4096          2 /
        systemd       1              root  rtd       DIR                8,2     4096          2 /
        systemd       1              root  txt       REG                8,2  1573136     397186 /lib/systemd/systemd
        systemd       1              root  mem       REG                8,2    18848     397793 /lib/x86_64-linux-gnu/libuuid.so.1.3.0
        systemd       1              root  mem       REG                8,2   262280     397597 /lib/x86_64-linux-gnu/libblkid.so.1.1.0
        systemd       1              root  mem       REG                8,2    14608     397629 /lib/x86_64-linux-gnu/libdl-2.23.so
        systemd       1              root  mem       REG                8,2   456632     397734 /lib/x86_64-linux-gnu/libpcre.so.3.13.2
        systemd       1              root  mem       REG                8,2  1868984     397605 /lib/x86_64-linux-gnu/libc-2.23.so
        systemd       1              root  mem       REG                8,2   138744     397751 /lib/x86_64-linux-gnu/libpthread-2.23.so
        
      • 查看端口号

        lsof -i:5000
        COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
        docker-pr 49382 root    4u  IPv6 964392      0t0  TCP *:5000 (LISTEN)
        
  • 【问】如何显示整个系统的网络状态?(netstat

    Note

    • 利用netstat指令可让你得知整个Linux系统的网络情况。语法:netstat [-acCeFghilMnNoprstuvVwx][-A<网络类型>][--ip]

      参数说明:

      -a或–all 显示所有线中的Socket。
      -A<网络类型>或–<网络类型> 列出该网络类型连线中的相关地址。
      -c或–continuous 持续列出网络状态。
      -C或–cache 显示路由器配置的快取信息。
      -e或–extend 显示网络其他相关信息。
      -F或–fib 显示FIB。
      -g或–groups 显示多重广播功能群组组员名单。
      -h或–help 在线帮助。
      -i或–interfaces 显示网络界面信息表单。
      -l或–listening 显示监控中的服务器的Socket。
      -M或–masquerade 显示伪装的网络连线。
      -n或–numeric 直接使用IP地址,而不通过域名服务器。
      -N或–netlink或–symbolic 显示网络硬件外围设备的符号连接名称。
      -o或–timers 显示计时器。
      -p或–programs 显示正在使用Socket的程序识别码和程序名称。
      -r或–route 显示Routing Table。
      -s或–statistice 显示网络工作信息统计表。
      -t或–tcp 显示TCP传输协议的连线状况。
      -u或–udp 显示UDP传输协议的连线状况。
      -v或–verbose 显示指令执行过程。
      -V或–version 显示版本信息。
      -w或–raw 显示RAW传输协议的连线状况。
      -x或–unix 此参数的效果和指定"-A unix"参数相同。
      –ip或–inet 此参数的效果和指定"-A inet"参数相同。
      
    • 例子:

      • 查看所有 socket 状态:netstat -a

        netstat -a | more -10
        Proto Recv-Q Send-Q Local Address           Foreign Address         State      
        tcp        0      0 localhost:37872         *:*                     LISTEN     
        tcp        0      0 10.0.3.1:domain         *:*                     LISTEN     
        tcp        0      0 dpf-virtual-mach:domain *:*                     LISTEN     
        tcp        0      0 *:ssh                   *:*                     LISTEN     
        tcp        0      0 localhost:6010          *:*                     LISTEN     
        tcp        0      0 192.168.132.131:ssh     192.168.132.1:10222     ESTABLISHED
        tcp        0     36 192.168.132.131:ssh     192.168.132.1:8530      ESTABLISHED
        tcp6       0      0 [::]:ssh                [::]:*                  LISTEN   
        
      • 查看所有 tcp socket 状态:netstat -at

        netstat -at | more -10
        Proto Recv-Q Send-Q Local Address           Foreign Address         State      
        tcp        0      0 localhost:37872         *:*                     LISTEN     
        tcp        0      0 10.0.3.1:domain         *:*                     LISTEN     
        tcp        0      0 dpf-virtual-mach:domain *:*                     LISTEN     
        tcp        0      0 *:ssh                   *:*                     LISTEN     
        tcp        0      0 localhost:6010          *:*                     LISTEN     
        tcp        0      0 192.168.132.131:ssh     192.168.132.1:10222     ESTABLISHED
        tcp        0     36 192.168.132.131:ssh     192.168.132.1:8530      ESTABLISHED
        tcp6       0      0 [::]:ssh                [::]:*                  LISTEN  
        
      • 查看所有 udp socket 状态:netstat -au

        netstat -au | more -10
        Proto Recv-Q Send-Q Local Address           Foreign Address         State      
        udp        0      0 *:58277                 *:*                                
        udp        0      0 *:mdns                  *:*                                
        udp        0      0 10.0.3.1:domain         *:*                                
        udp        0      0 dpf-virtual-mach:domain *:*                                
        udp        0      0 *:bootps                *:*                                
        udp        0      0 *:bootpc                *:*                                
        udp6       0      0 [::]:mdns               [::]:*                             
        udp6       0      0 [::]:40144              [::]:*
        
      • 查看所有监听中的 tcp socket 状态:netstat -lt

        netstat -ld | more -10
        Proto Recv-Q Send-Q Local Address           Foreign Address         State      
        tcp        0      0 localhost:37872         *:*                     LISTEN     
        tcp        0      0 10.0.3.1:domain         *:*                     LISTEN     
        tcp        0      0 dpf-virtual-mach:domain *:*                     LISTEN     
        tcp        0      0 *:ssh                   *:*                     LISTEN     
        tcp        0      0 localhost:6010          *:*                     LISTEN     
        tcp6       0      0 [::]:ssh                [::]:*                  LISTEN     
        tcp6       0      0 [::]:8888               [::]:*                  LISTEN     
        tcp6       0      0 ip6-localhost:6010      [::]:*                  LISTEN 
        
      • 查看所有监听中的 udp socket 状态:netstat -lu

      • 查看系统5000端口:

        netstat -anp | grep "5000"
        tcp6       0      0 :::5000                 :::*                    LISTEN      49382/docker-proxy
        
  • 【问】如何检测主机是否运作正常?(ping

  • 【问】如何远端登入服务器?(telnet 192.168.0.5登录IP为 192.168.0.5 的远程主机)

5、Shell语法

参考Shell脚本基础语法教程Linux【实操篇】— Shell 编程入门、变量、运算符、条件判断、流程控制Shell中getopts用法介绍Shell脚本 & Sed流编辑器 & awk语法

  • 【问】Shell脚本能用来干什么?
    Note

    • 1)自动化软件部署 LAMP/LNMP/Tomcat…
    • 2)自动化管理:系统初始化脚本、批量更改主机密码、推送公钥…
    • 3)自动化分析处理:统计网站访问量PV
    • 4)自动化备份:数据库备份、日志转储…
    • 5)自动化监控脚本
  • 【问】Shell变量的定义规则(变量名=变量值)
    Note

    • 变量名区分大小写(Aa是两个不同的变量)
    • 变量名不能有特殊符号(*A,?A,@A都是不允许的)
    • 变量名不能以数字开头;
    • 等号两边不能有任何空格;
  • 【问】Shell变量定义的方式(直接赋值和取值,read,declare)
    Note

    • 1)直接赋值
      [root@MissHou ~]$ A=1234567
      [root@MissHou ~]$ echo $A
      1234567
      [root@MissHou ~]$ echo ${A:2:4}        表示从A变量中第3个字符开始截取,截取4个字符
      3456
      
      $变量名${变量名}的异同
      • 相同点:都可以调用变量
      • 不同点:${变量名}可以只截取变量的一部分,而$变量名不可以;
    • 2)$(command 参数)将命令执行结果赋值给变量,参考Linux 命令的输出赋值给变量
      [root@MissHou ~]$ B=`date +%F`
      [root@MissHou ~]$ echo $B
      2019-04-16
      [root@MissHou ~]$ C=$(uname -r)
      [root@MissHou ~]$ echo $C
      2.6.32-696.el6.x86_64
      
      content=$(ls | grep "专业")
      echo $content
      ---
      专业实践任务书.doc 专业实践报告1.doc 专业实践报告2.doc 专业实践报告.docx
      
    • 3)交互式定义变量(read)
      • 语法: read [选项] 变量名

      • 常见选项:

        选项释义
        -p定义提示用户的信息
        -n定义字符数(限制变量值的长度)
        -s不显示(不显示用户输入的内容)
        -t定义超时时间,默认单位为秒(限制用户输入变量值的超时时间)
      • 举例说明:
        用法1:用户自己定义变量值

        [root@MissHou ~]# read name
        harry
        [root@MissHou ~]# echo $name
        harry
        [root@MissHou ~]# read -p "Input your name:" name
        Input your name:tom
        [root@MissHou ~]# echo $name
        tom
        

        用法2:读取来自文件的变量值

        [root@MissHou ~]# cat 1.txt 
        10.1.1.1 255.255.255.0
        
        [root@MissHou ~]# read ip mask < 1.txt 
        [root@MissHou ~]# echo $ip
        10.1.1.1
        [root@MissHou ~]# echo $mask
        255.255.255.0
        
    • 4)定义有类型的变量(declare)
      • 目的:给变量做一些限制,固定变量的类型,比如:整型、只读

      • 用法:declare 选项 变量名=变量值

      • 常用选项:

        选项释义举例
        -i将变量看成整数declare -i A=123
        -r定义只读变量declare -r B=hello
        -a定义普通数组;查看普通数组
        -A定义关联数组;查看关联数组
        -x将变量通过环境导出declare -x AAA=123456 等于 export AAA=123456
      • 举例说明:

        [root@MissHou ~]# declare -i A=123
        [root@MissHou ~]# echo $A
        123
        [root@MissHou ~]# A=hello
        [root@MissHou ~]# echo $A
        0
        
        [root@MissHou ~]# declare -r B=hello
        [root@MissHou ~]# echo $B
        hello
        [root@MissHou ~]# B=world
        -bash: B: readonly variable
        [root@MissHou ~]# unset B
        -bash: unset: B: cannot unset: readonly variable
        
  • 【问】Shell变量如何取值($变量名或者${变量名}
    Note

    • $变量名或者${变量名}取值:
      	[root@MissHou ~]$ A=1234567
      	[root@MissHou ~]$ echo $A
      	1234567
      	[root@MissHou ~]$ echo ${A:2:4}        表示从A变量中第3个字符开始截取,截取4个字符
      	3456
      
    • $变量名${变量名}的异同
      • 相同点:都可以调用变量
      • 不同点:${变量名}可以只截取变量的一部分,而$变量名不可以;
  • 【问】Shell变量类型?(整数/只读变量/普通数组/关联数组/环境变量,查看declare赋值方式)

  • 【问】Shell变量作用域分类?(本地变量,环境变量,全局变量,系统变量)
    Note

    • 1)本地变量:当前用户自定义的变量。当前进程中有效,其他进程及当前进程的子进程无效。

    • 2)环境变量

      1)按生效的范围分类。

      系统环境变量:公共的,对全部的用户都生效。

      用户环境变量:用户私有的、自定义的个性化设置,只对该用户生效。

      2)按生存周期分类。

      永久环境变量:在环境变量脚本文件中配置,用户每次登录时会自动执行这些脚本,相当于永久生效。

      临时环境变量:使用时在Shell中临时定义,退出Shell后失效。

      环境变量 (也是和程序绑定的, 程序结束时, 动态设置的环境变量也就结束):当前进程有效,并且能够被子进程调用, 反之不行(子进程环境变量的设置对父进程无效)。

      1. 环境变量的值由用户决定, 和Windows的用户环境变量一样. 即使用户qpyue 使用su 切换root用户,echo USER依旧是以前的用户名称(qpyue), 环境变量的值依旧不变.(除了HOME)

      2. 即使两个qpyue用户同时登录, 他们的环境变量都会重新从配置文件刷新, 单独存储, 所以环境变量的值互不影响(在两个bash程序存在过程中, 任意一方环境变量变化不影响另一方)*

    • 3)全局变量:全局所有的用户和程序都能调用(文件配置),且继承,新建的用户也默认能调用。相关配置文件解读如下:

      文件名说明备注
      $HOME/.bashrc当前用户的bash信息,用户登录时读取定义别名、umask、函数等
      $HOME/.bash_profile当前用户的环境变量,用户登录时读取
      $HOME/.bash_logout当前用户退出当前shell时最后读取定义用户退出时执行的程序等
      /etc/bashrc全局的bash信息,所有用户都生效
      /etc/profile全局环境变量信息系统和所有用户都生效
      $HOME/.bash_history用户的历史命令history -w 保存历史记录 history -c 清空历史记录

      说明: 以上文件修改后,都需要重新source让其生效或者退出重新登录。
      例子:通过脚本(env_setting.sh配置当前用户的环境变量(以ffmpeg为例)

      #bin/bash
      
      #当前目录的绝对路径
      ffmpeg_path=$(pwd)
      
      #如果~/.bash_profile已存在,只会修改时间戳
      touch ~/.bash_profile
      #配置当前用户的环境变量
      cat >> ~/.bash_profile  << EOF
      export PATH="$ffmpeg_path:$PATH"
      EOF
      
      #更新当前用户的环境变量
      source ~/.bash_profile
      
    • 4)系统变量(内置bash中变量) : shell本身已经固定好了它的名字和作用

      ./02.sh a b c -> (3个参数)

      内置变量含义
      $?上一条命令执行后返回的状态;状态值为0表示执行正常,非0表示执行异常或错误
      $0当前执行的程序或脚本名 (./02.sh)
      $#脚本后面接的参数的个数 3个
      $*脚本后面所有参数,参数当成一个整体输出,每一个变量参数之间以空格隔开 (参数数组a b c)
      $@脚本后面所有参数参数是独立的,也是全部输出 (参数数组a b c)
      1~9脚本后面的位置参数,$1表示第1个位置参数,依次类推
      {10}~{n}扩展位置参数,第10个位置变量必须用{}大括号括起来(2位数字以上扩起来)
      $$当前所在进程的进程号,如echo $$
      $!后台运行的最后一个进程号 测试: sleep 400 &(后台运行)/sleep 400(ctrl+z 暂停运行), 再运行jobs, 查看当前进程的后台子进程.
      !$调用最后一条命令历史中的参数
  • 【问】Shell变量的算术运算?
    Note

    • 默认情况下,shell就只能支持简单的整数运算:加(+)、减(-)、乘(*)、除(/)、求余数(%
      表达式举例
      $(( ))echo $((1+1))
      $[ ]echo $[10-5]
      exprexpr 10 / 5
      letn=1;let n+=1 等价于 let n=n+1
    • shell中的i++
      [root@MissHou ~]# i=1
      [root@MissHou ~]# let i++
      [root@MissHou ~]# echo $i
      2
      [root@MissHou ~]# j=1
      [root@MissHou ~]# let ++j
      [root@MissHou ~]# echo $j
      2
      
  • 【问】Shell定义普通数组和关联数组,并进行赋值(declare -adeclare -A
    Note

    • 1)数组分类
      • 普通数组:只能使用整数作为数组索引(元素的下标)
      • 关联数组:可以使用字符串作为数组索引(元素的下标)
    • 2)普通数组的定义与读取
      • 一次赋予一个值
        数组名[索引下标]=值
        array[0]=v1
        array[1]=v2
        array[2]=v3
        array[3]=v4
        
      • 一次赋予多个值
        数组名=(值1 值2 值3 ...)
        array=(var1 var2 var3 var4)
        
        array1=(`cat /etc/passwd`)            将文件中每一行赋值给array1数组
        array2=(`ls /root`)
        array3=(harry amy jack "Miss Hou")
        array4=(1 2 3 4 "hello world" [10]=linux)
        
      • 数组的读取
        ${数组名[元素下标]}
        
        echo ${array[0]}            获取数组里第一个元素
        echo ${array[*]}            获取数组里的所有元素
        echo ${#array[*]}            获取数组里所有元素个数
        echo ${!array[@]}        获取数组元素的索引下标
        echo ${array[@]:1:2}    访问指定的元素;1代表从下标为1的元素开始获取;2代表获取后面几个元素
        
      • 查看当前所有普通数组:
        查看普通数组信息:
        [root@MissHou ~]# declare -a
        
    • 3)定义关联数组和读取
      • 首先声明关联数组

        declare -A asso_array1
        declare -A asso_array2
        declare -A asso_array3
        
      • 关联数组赋值

        • 一次赋一个值
          数组名[索引or下标]=变量值
          asso_array1[linux]=one
          asso_array1[java]=two
          asso_array1[php]=three
          
        • 一次赋多个值(用(赋多值,且中间没逗号)
          asso_array2=([name1]=harry [name2]=jack [name3]=amy [name4]="Miss Hou")
          
      • 查看当前进程中所有关联数组

        # declare -A
        declare -A asso_array1='([php]="three" [java]="two" [linux]="one" )'
        declare -A asso_array2='([name3]="amy" [name2]="jack" [name1]="harry" [name4]="Miss Hou" )'
        
      • 获取关联数组值($记得加{}

        $ echo ${asso_array1[linux]}
        one
        $ echo ${asso_array1[php]}
        three
        $ echo ${asso_array1[*]}
        three two one
        $ echo ${!asso_array1[*]}
        php java linux
        $ echo ${#asso_array1[*]}
        3
        $ echo ${#asso_array2[*]}
        4
        $ echo ${!asso_array2[*]}
        name3 name2 name1 name4
        
  • 【问】从Shell变量中获取目录和文件字符串?
    Note

    • 取出一个目录下的目录和文件:dirnamebasename

      A=/root/Desktop/shell/mem.txt 
      echo $A
      /root/Desktop/shell/mem.txt
      
      dirname $A   取出目录
      /root/Desktop/shell
      
      basename $A  取出文件
      mem.txt
      
  • 【问】Shell变量"内容"的删除和替换?
    Note

    • 左右删除操作:

      一个“%”代表从右往左删除
      两个“%%”代表从右往左去掉最多
      一个“#”代表从左往右去掉删除
      两个“##”代表从左往右去掉最多

      参考代码:

      $ url=www.taobao.com
      $ echo ${#url}             获取变量的长度
      14
      $ echo ${url#*.}
      taobao.com
      $ echo ${url##*.}
      com
      $ echo ${url%.*}
      www.taobao
      $ echo ${url%%.*}
      www
      
    • 替换操作:///

      echo ${url/ao/AO}  用AO代替ao(从左往右第一个)
      www.tAObao.com
      
      echo ${url//ao/AO}   贪婪替换(替代所有)
      www.tAObAO.com
      
  • 【问】Shell条件判断的语法格式?
    Note

    • 条件判断3种语法格式
      • 格式1test 条件表达式
      • 格式2[ 条件表达式 ]
      • 格式3[[ 条件表达式 ]] 支持正则 =~
    • [][[]]使用要点:
      表达式左右两边空格字符串是否需加""是否支持&&||是否支持C风格
      [ ]需要需要不支持不支持
      [[ ]]需要不需要支持支持,比如`a=1; b=2
      [[ a > b ]] && echo a |
  • 【问】Shell中常见的条件判断
    Note

    • 条件判断常用场景:判断文件类型,判断文件新旧,判断字符串是否相等,判断权限等等…

    • 文件类型判断:

      判断参数含义说明
      -e判断文件是否存在(link文件指向的也必须存在)exists
      -f判断文件是否存在并且是一个普通文件file
      -d判断文件是否存在并且是一个目录directory
      -L判断文件是否存在并且是一个软连接文件soft link
      -b判断文件是否存在并且是一个块设备文件block
      -S判断文件是否存在并且是一个套接字文件socket
      -c判断文件是否存在并且是一个字符设备文件char
      -p判断文件是否存在并且是一个命名管道文件pipe
      -s判断文件是否存在并且是一个非空文件(有内容)is not empty

      例如:

      test -e file                    只要文件存在条件为真
      [ -d /shell01/dir1 ]             判断目录是否存在,存在条件为真
      [ ! -d /shell01/dir1 ]        判断目录是否存在,不存在条件为真
      [[ -f /shell01/1.sh ]]        判断文件是否存在,并且是一个普通的文件
      
    • 文件权限判断

      判断参数含义
      -r当前用户对其是否可读
      -w当前用户对其是否可写
      -x当前用户对其是否可执行
      -u是否有suid,高级权限冒险位
      -g是否sgid,高级权限强制位
      -k是否有t位,高级权限粘滞位 (创建者/root才能删除)
    • 文件新旧比较:这里的新旧指的是文件的修改时间。

      判断参数含义
      file1-nt file2比较file1是否比file2新
      file1 -ot file2比较file1是否比file2旧
      file1 -ef file2比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode
    • 整数比较

      判断参数含义
      -eq==相等
      -ne<>!=不等
      -gt大于
      -lt小于
      -ge大于等于
      -le小于等于
    • 字符串比较

      判断参数含义
      -z判断是否为空字符串,字符串长度为0则成立
      -n判断是否为非空字符串,字符串长度不为0则成立
      string1 = string2判断字符串是否相等
      string1 != string2判断字符串是否不相等
    • 逻辑运算符

      判断符号含义举例
      -a&&逻辑与[ 1 -eq 1 -a 1 -ne 0 ] 或者 [ 1 -eq 1 ] && [ 1 -ne 0 ]
      -o\\

      例如

      [ 33 <> 55 -a 33 -gt $[300/10] ]; echo $?
      [ 33 -le 44 ] && [ 33 -gt $[999/100] ] ; echo $?
      
  • 【问】Shell的流程控制语法( if..elif..elsecase...esac
    Note

    • if..elif..else结构:

      if [ condition1 ];then
              command1       
              if [ condition2 ];then
                  command2
              fi
       else
              if [ condition3 ];then
                  command3
              elif [ condition4 ];then
                  command4
              else
                  command5
              fi
      fi
      
    • case...esac 语句

      1. case语句为多重匹配语句
      2. 如果匹配成功,执行相匹配的命令
      说明:`pattern`表示需要匹配的模式
      
      case var in             定义变量;var代表是变量名
      pattern 1)              模式1;| 分割多个模式,相当于or
          command1            需要执行的语句
          ;;                  两个分号代表命令结束
      pattern 2)
          command2
          ;;
      pattern 3)
          command3
          ;;
      *)              default,不满足以上模式,默认执行*)下面的语句
          command4
          ;;
      esac                            esac表示case语句结束
      
  • 【问】Shell的循环控制语法(for/while/util
    Note

    • for结构
      for ((i=1;i<=5;i++));do echo $i;done
      for ((i=1;i<=10;i+=2));do echo $i;done
      for ((i=2;i<=10;i+=2));do echo $i;done
      
    • while结构:
      i=1
      while [ $i -le 5 ]
      do
          echo $i
          let i++
      done
      
    • util结构:与while相反,当条件为假就进入循环;条件为真就退出循环
      i=1
      until [ $i -gt 5 ]
      do
          echo $i
          let i++
      done
      
  • 【问】Shell的函数声明和调用(传参不用带括号)
    Note

    • 如何定义函数?

      方法1:

      函数名()
      {
        函数体(一堆命令的集合,来实现某个功能)   
      }
      

      方法2:

      function 函数名()
      {
         函数体(一堆命令的集合,来实现某个功能)
         echo hello
         echo world
      }
      
    • 函数如何调用?

      • 1)当前命令行调用(source

        [root@MissHou shell04]# cat fun1.sh 
        #!/bin/bash
        hello(){
        echo "hello lilei $1"
        hostname
        }
        menu(){
        cat <<-EOF
        1. mysql
        2. web
        3. app
        4. exit
        EOF
        }
        
        [root@MissHou shell04]# source fun1.sh 或者 . fun1.sh
        [root@MissHou shell04]# hello 888
        hello lilei 888
        DESKTOP-SPF2TPF   
        [root@MissHou shell04]# menu
        1. mysql
        2. web
        3. app
        4. exit
        
      • 2)定义到用户的环境变量中(~/.bashrc

        [root@MissHou shell05]# vim ~/.bashrc 
        文件中增加如下内容:
        hello(){
        echo "hello lilei $1"
        hostname
        }
        menu(){
        cat <<-EOF
        1. mysql
        2. web
        3. app
        4. exit
        EOF
        }
        
        注意:
        当用户打开bash的时候会读取该文件
        
      • 3)脚本中调用

        #!/bin/bash
        #打印菜单
        source ./fun1.sh
        
        hello(){
        echo "hello lilei $1"
        hostname
        }
        
        hello beautiful//调用函数
        
        menu(){
        cat <<-END
            h    显示命令帮助
            f    显示磁盘分区
            d    显示磁盘挂载
            m    查看内存使用
            u    查看系统负载
            q    退出程序
            END
        }
        menu        //调用函数
        
  • 【问】Shell的函数的返回值问题(返回状态值在0~256之间)
    Note

    • 函数中return说明:

      1. return可以结束一个函数。类似于循环控制语句break(结束当前循环,执行循环体后面的代码)。
      2. return默认返回函数中最后一个命令状态值,也可以给定参数值,范围是0-256之间
      3. 如果没有return命令,函数将返回最后一个指令的退出状态值
  • 【问】正则表达式如何使用(元字符、前导字符;正则使用原则:找什么,在哪里找,找多少)
    Note

    • 正则表达式这个概念最初是由Unix中的工具软件(例如sedgrep)普及开的。支持正则表达式的程序如:locate |find|vim| grep|sed |awk
      正则表达式常用于匹配邮箱、身份证号码、手机号、银行卡号

    • 正则当中名词解释

      • 元字符:指那些在正则表达式中具有特殊意义的专用字符,如点(.) 星(*) 问号(?)等
      • 前导字符:位于元字符前面的字符.ab*c*aoo*o.*
    • 正则中第一类普通常用的元字符:

      元字符功能备注
      .匹配除了换行符以外的任意单个字符
      *前导字符出现0次或连续多次
      .*任意长度字符ab.*
      ^行首(以…开头)^root
      $行尾(以…结尾)bash$
      ^$空行
      []匹配括号里任意单个字符或一组单个字符[abc]
      [^]匹配不包含括号里任一单个字符或一组单个字符[^abc]
      ^[]匹配以括号里任意单个字符或一组单个字符开头^[abc]
      ^[^]匹配不以括号里任意单个字符或一组单个字符开头^[^abc]
      \<取单词的头\<hel匹配hello worldhello yourself
      \>取单词的尾world\>匹配hello worldhello yourself
      \< \>精确匹配
      \{n\}匹配前导字符连续出现n次go\{3\}匹配goooglegooooooglegooooooogle
      \{n,\}匹配前导字符至少出现n次
      \{n,m\}匹配前导字符出现n次与m次之间
      \( \)保存被匹配的字符
      \d匹配数字(grep -P[0-9]
      \w匹配字母数字下划线(grep -P[a-zA-Z0-9_]
      \s匹配空格、制表符、换页符(grep -P[\t\r\n]
    • 扩展类正则常用元字符:sed要使用正则,必须加 -r

      扩展元字符功能备注
      +匹配一个或多个前导字符bo+ 匹配boo、 bo
      ?匹配零个或一个前导字符bo? 匹配b、 bo
      \
      ()组字符(看成整体)
      {n}前导字符重复n次
      {n,}前导字符重复至少n次
      {n,m}前导字符重复n到m次

      比如:

      • 需求:匹配单词的头和尾

        $ grep '\<hel' reg_test.txt
        hello world
        helloworld yourself
        
        $ grep 'world\>' reg_test.txt
        hello world
        helloworld yoursel
        
      • 需求:将10.1.1.2.1.1替换成10.1.1.345.1.678,参考Linux vim 文本替换 %s/原文/替换文本/g

          1)vim编辑器支持正则表达式
          # vim 1.txt
          :%s#\(10.1.1\).1#\1.254#g   或者
          :%s/\(10.1.1\).2.\(1\).1/\1.345.\2.678/g
        	
          2)sed支持正则表达式【后面学】
          sed -n 's#\(10.1.1\).1#\1.254#p' 1.txt 或者
          sed -n 's/\(10.1.1\).2.\(1\)/\1.345\2.678/p' reg_test.txt
          10.1.1.254
        
      • 分隔符可以使用#,也可以使用/

      • 找出含有10.1.1的行,同时保留10.1.1并标记为标签1,之后可以使用\1来引用它。

      • 最多可以定义9个标签,从左边开始编号,最左边的是第一个。

    • 第二类正则表达式

      表达式功能示例
      [:alnum:]字母与数字字符[[:alnum:]]+
      [:alpha:]字母字符(包括大小写字母)[[:alpha:]]{4}
      [:blank:]空格与制表符[[:blank:]]*
      [:digit:]数字[[:digit:]]?
      [:lower:]小写字母[[:lower:]]{4,}
      [:upper:]大写字母[[:upper:]]+
      [:punct:]标点符号[[:punct:]]
      [:space:]包括换行符,回车等在内的所有空白[[:space:]]+
    • 正则表达式如何使用,掌握如下原则(找什么,在哪里找,找多少)

        1. 我要找什么?
        • 找数字:[0-9]
        • 找字母: [a-zA-Z]
        • 找标点符号: [[:punct:]]
        1. 我要如何找?看心情找
        • 以什么为首 ^key
        • 以什么结尾 key$
        • 包含什么或不包含什么 [abc],[abc],[abc],[abc]
        1. 我要找多少呀?
        • 找前导字符出现0次或连续多次ab*
        • 找任意单个 (一次)字符ab.
        • 任意字符ab.*
        • 找前导字符连续出现几次:{n}{n,m}{n,}
        • 找前导字符出现1次或多次go+
        • 找前到字符出现0次或1次:go?
6、Sed流编辑器
  • 【问】Sed是什么?(流编辑器Stream Editor,用来处理文件的)
    Note

    • 由于sed每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会直接修改原文件
    • Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作,对文件进行过滤和转换操作
  • 【问】Sed语法(sed [options] '处理动作' 文件名
    Note

    • 语法格式sed [options] '处理动作' 文件名
      常用选项

      选项说明备注
      -e进行多项(多次)编辑
      -n取消默认输出不自动打印模式空间
      -r使用扩展正则表达式
      -i原地编辑(修改源文件)
      -f指定sed脚本的文件名

      常见处理动作:以下所有的动作都要在单引号

      动作说明备注
      'p'打印需要使用-n取消默认输出
      'i'在指定行之前插入内容(insert)类似vim里的大写O
      'a'在指定行之后插入内容(append)类似vim里的小写o
      'c'替换指定行所有内容
      'd'删除指定行
    • 举个例子:

      • ‘i’ | ‘a’ - 增加文件内容:'i'表示在地址定位的上面插入,'a'在地址定位的下面插入(但不会编辑源文件)

        [root@server ~]# sed '$a99999' a.txt                 文件最后一行下面增加内容
        [root@server ~]# sed 'a99999' a.txt                 文件每行下面增加内容
        [root@server ~]# sed '5a99999' a.txt                 文件第5行下面增加内容
        [root@server ~]# sed '$i99999' a.txt                 文件最后一行上一行增加内容
        [root@server ~]# sed 'i99999' a.txt                 文件每行上一行增加内容
        [root@server ~]# sed '6i99999' a.txt                 文件第6行上一行增加内容
        [root@server ~]# sed '/^uucp/ihello'                以uucp开头行的上一行插入
        
      • ‘d’ - 删除文件内容

        [root@server ~]# sed '1d' a.txt                         删除文件第1行
        [root@server ~]# sed '1,5d' a.txt                     删除文件1到5行
        [root@server ~]# sed '$d' a.txt                        删除文件最后一行
        
  • 【问】Sed如何保存查找串并进行替换?(支持正则表达式\(\)&
    Note

    • ‘s/搜索的内容/替换的内容/动作’ - 对文件进行搜索替换操作

      语法:

      • sed 选项 ‘s/搜索的内容/替换的内容/动作’ 需要处理的文件,其中,s表示search搜索;斜杠/表示分隔符,可以自己定义;动作一般是打印p和全局替换g

      • 如果要在源文件上进行修改,则使用-i,不要使用-n和’p’

      [root@server ~]$ sed -n 's/root/ROOT/p' 1.txt 
      [root@server ~]$ sed -n 's/root/ROOT/gp' 1.txt 
      [root@server ~]$sed -n 's/^#//gp' 1.txt 
      [root@server ~]$ sed -n 's@/sbin/nologin@itcast@gp' a.txt
      [root@server ~]$ sed -n 's/\/sbin\/nologin/itcast/gp' a.txt
      [root@server ~]$ sed -n '10s#/sbin/nologin#itcast#p' a.txt 
      uucp:x:10:14:uucp:/var/spool/uucp:itcast
      [root@server ~]$ sed -n 's@/sbin/nologin@itcastheima@p' 2.txt 
      注意:搜索替换中的分隔符可以自己指定
      
      [root@server ~]$ sed -n '1,5s/^/#/p' a.txt         注释掉文件的1-5行内容
      #root:x:0:0:root:/root:/bin/bash
      #bin:x:1:1:bin:/bin:/sbin/nologin
      #daemon:x:2:2:daemon:/sbin:/sbin/nologin
      #adm:x:3:4:adm:/var/adm:/sbin/nologin
      #lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
      
    • 支持正则表达式\(\),用于保存字符串:

      需求:将`10.1.1.2.1.1`替换成`10.1.1.345.1.678`
      sed -n 's#\(10.1.1\).1#\1.254#p' 1.txt 或者
      sed -n 's/\(10.1.1\).2.\(1\)/\1.345\2.678/p' reg_test.txt
      10.1.1.254
      
    • 使用&占位符用于保存字符串

       &   保存查找串以便在替换串中引用   \(\)
       
       [root@server ~]# sed -n '/root/p' a.txt 
       root:x:0:0:root:/root:/bin/bash
       [root@server ~]# sed -n 's/root/#&/p' a.txt 
       #root:x:0:0:root:/root:/bin/bash
    
  • 【问】Sed如何修改源文件和多项编辑?
    Note

    • -i 修改源文件:

      cat sed_test.txt
      root:x:0:0:root:/root:/bin/bash
      bin:x:1:1:bin:/bin:/sbin/nologin
      daemon:x:2:2:daemon:/sbin:/sbin/nologin
      adm:x:3:4:adm:/var/adm:/sbin/nologin
      lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
      298374837483
      172.16.0.254
      10.1.1.1
      
      sed -i '1,5s/daemon/&123/' sed_test.txt
      
      cat sed_test.txt
      root:x:0:0:root:/root:/bin/bash
      bin:x:1:1:bin:/bin:/sbin/nologin
      daemon123:x:2:2:daemon:/sbin:/sbin/nologin
      adm:x:3:4:adm:/var/adm:/sbin/nologin
      lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
      298374837483
      172.16.0.254
      10.1.1.1
      
    • -e多项编辑:

      -e 多项编辑
      -r    扩展正则
      
      [root@server ~]# sed -ne '/root/p' 1.txt -ne '/root/='
      root:x:0:0:root:/root:/bin/bash
      1
      [root@server ~]# sed -ne '/root/=' -ne '/root/p' 1.txt 
      1
      root:x:0:0:root:/root:/bin/bash
      [root@server ~]# sed -ne '/root/=;/root/p' 1.txt 
      1
      root:x:0:0:root:/root:/bin/bash
      
  • 【问】Sed结合正则使用
    Note

    • 语法:sed 选项 'sed命令或者正则表达式或者地址定位' 文件名
    • 定址用于决定对哪些行进行编辑。地址的形式可以是数字、正则表达式、或二者的结合。如果没有指定地址,sed将处理输入文件的所有行
      正则说明备注
      '/key/'查询包含关键字的行sed -n ‘/root/p’ 1.txt
      '/key1/,/key2/'匹配包含两个关键字之间的行sed -n ‘/adm/,/mysql/p’ 1.txt
      '/key/,x'匹配关键字的行开始到文件第x行之间的行(包含关键字所在行)sed -n ‘/^ftp/,7p’
      'x,/key/'从文件的第x行开始到与关键字的匹配行之间的行
      'x,y!'不包含x到y行
      '/key/!'不包括关键字的行sed -n ‘/bash$/!p’ 1.txt
  • 【问】Sed脚本运行?
    Note:

    • 语法:sed -f sedScript.sh file,其中sedScript.sh为:
      #!/bin/sed -f
      1,5d
      s/root/hello/g
      3i777
      5i888
      a999
      p
      
    • sed脚本说明
      • 脚本文件是一个sed命令行清单,包含多条sed commands
      • 每行的末尾不能有任何空格、制表符(tab)或其它文本
      • 如果在一行中有多个命令,应该用分号分隔
      • 不需要且不可用引号保护命令
      • #号开头的行为注释
7、awk语言
  • 【问】awk是什么
    Note

    • awk是一种编程语言,主要用于在linux/unix下对文本和数据进行处理,是linux/unix下的一个工具。数据可以来自标准输入、一个或多个文件,或其它命令的输出。

    • awk的处理文本和数据的方式:逐行扫描文件,默认从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。

    • awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。

    • awk用来处理文件和数据的,是类unix下的一个工具,也是一种编程语言

    • 可以用来统计数据,比如网站的访问量,访问的IP量等等

    • 支持条件判断,支持forwhile循环

  • 【问】awk语法
    Note:

    • 命令行模式:
      • 语法结构

        awk 选项 '命令部分' 文件名
        
        特别说明:
        引用shell变量需用双引号引起
        
      • 常用选项

        -F 定义字段分割符号,默认的分隔符是空格
        -v 定义变量并赋值

      • ‘命名部分’ 说明

        • 正则表达式,地址定位
        '/root/{awk语句}'                sed中: '/root/p'
        'NR==1,NR==5{awk语句}'            sed中: '1,5p'
        '/^root/,/^ftp/{awk语句}'      sed中:'/^root/,/^ftp/p'
        
        • {awk语句1; awk语句2;...}
        '{print $0;print $1}'        sed中:'p'
        'NR==5{print $0}'                sed中:'5p'
        注:awk命令语句间用分号间隔
        
    • 脚本模式:
      • 脚本编写

        #!/bin/awk -f         定义魔法字符
        以下是awk引号里的命令清单,不要用引号保护命令,多个命令用分号间隔
        BEGIN{FS=":"}
        NR==1,NR==3{print $1"\t"$NF}
        ...
        
      • 脚本执行

        awk 选项 -f awk的脚本文件  要处理的文本文件
        awk -f awk.sh filename
        
        sed -f sed.sh -i filename
        
  • 【问】awk变量和分隔符
    Note

    • awk内部相关变量

      变量变量说明备注
      $0当前处理行的所有记录
      1,2,3...n文件中每行以间隔符号分割的不同字段awk -F: ‘{print 1,3}’
      NF当前记录的字段数(列数)awk -F: ‘{print NF}’
      $NF最后一列$(NF-1)表示倒数第二列
      FNR/NR行号
      FS定义间隔符‘BEGIN{FS=“:”};{print 1,3}’
      OFS定义输出字段分隔符,默认空格‘BEGIN{OFS=“\t”};print 1,3}’
      RS输入记录分割符,默认换行‘BEGIN{RS=“\t”};{print $0}’
      ORS输出记录分割符,默认换行‘BEGIN{ORS=“\n\n”};{print 1,3}’
      FILENAME当前输入的文件名
    • 举个例子:

      • 文本准备:
        root:x:0:0:root:/roots:/bin/bash
        bin:x:1:1:bin:/bins:/sbin/nologin
        daemon123:x:2:2:daemon:/sbins:/sbin/nologin
        adm:x:3:4:adm:/var/adms:/sbin/nologin
        lp:x:4:7:lp:/var/spool/lpds:/sbin/nologin
        298374837483
        172.16.0.254
        10.1.1.1
        
      • 常用内置变量举例:
        awk -F: '{print $1,$(NF-1)}' sed_test.txt  #使用":"分隔符对行进行切分
        root /roots
        bin /bins
        daemon123 /sbins
        adm /var/adms
        lp /var/spool/lpds
        298374837483 298374837483
        172.16.0.254 172.16.0.254
        10.1.1.1 10.1.1.1
        
        awk -F: '{print $1,$(NF-1),$NF,NF}' sed_test.txt
        root /roots /bin/bash 7
        bin /bins /sbin/nologin 7
        daemon123 /sbins /sbin/nologin 7
        adm /var/adms /sbin/nologin 7
        lp /var/spool/lpds /sbin/nologin 7
        298374837483 298374837483 298374837483 1
        172.16.0.254 172.16.0.254 172.16.0.254 1
        10.1.1.1 10.1.1.1 10.1.1.1 1
        
  • 【问】awk变量定义
    Note:

    • awk中调用定义的变量不需要加$
      awk -v NUM=3 -F: '{ print $NUM }' /etc/passwd
      awk -v NUM=3 -F: '{ print NUM }' /etc/passwd
      awk -v num=1 'BEGIN{print num}' 
      1
      awk -v num=1 'BEGIN{print $num}' 
      
  • 【问】awk工作原理
    Note:

    • awk -F: '{print $1,$3}' 1.txt

      • 1)awk使用一行作为输入,并将这一行赋给内部变量$0,每一行也可称为一个记录,以换行符(RS)结束

      • 2)每行被间隔符:(默认为空格或制表符)分解成字段(或域),每个字段存储在已编号的变量中,从$1开始

        :awk如何知道用空格来分隔字段的呢?
        :因为有一个内部变量FS来确定字段分隔符。初始时,FS赋为空格

      • 3)awk使用print函数打印字段,打印出来的字段会以空格分隔,因为1,3之间有一个逗号。逗号比较特殊,它映射为另一个内部变量,称为输出字段分隔符OFS,OFS默认为空格

      • 4)awk处理完一行后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕

  • 【问】awk的begin…end
    Note

    • BEGIN:表示在程序开始前执行

    • END :表示所有文件处理完后执行

    • 用法:'BEGIN{开始处理之前};{处理中};END{处理结束后}',可以只存在'BEGIN{开始处理之前};{处理中};'或者'{处理中};END{处理结束后}'

    • 举例说明:打印最后一列和倒数第二列(登录shell和家目录)

      awk -F: 'BEGIN{ print "Login_shell\t\tLogin_home\n*******************"};{print $NF"\t\t"$(NF-1)};END{print "************************"}' 1.txt
      
      awk 'BEGIN{ FS=":";print "Login_shell\tLogin_home\n*******************"};{print $NF"\t"$(NF-1)};END{print "************************"}' 1.txt
      
      Login_shell        Login_home
      ************************
      /bin/bash        /root
      /sbin/nologin        /bin
      /sbin/nologin        /sbin
      /sbin/nologin        /var/adm
      /sbin/nologin        /var/spool/lpd
      /bin/bash        /home/redhat
      /bin/bash        /home/user01
      /sbin/nologin        /var/named
      /bin/bash        /home/u01
      /bin/bash        /home/YUNWEI
      ************************************
      
  • 【问】awk嵌套循环
    Note

    • awkwhile循环
      打印1-5
      i=1;while (($i<=5));do echo $i;let i++;done
      
      awk 'BEGIN { i=1;while(i<=5) {print i;i++} }'
      打印1~10中的奇数
      awk 'BEGIN{i=1;while(i<=10) {print i;i+=2} }'
      计算1-5的和
      awk 'BEGIN{i=1;sum=0;while(i<=5) {sum+=i;i++}; print sum }'
      awk 'BEGIN {i=1;while(i<=5) {(sum+=i) i++};print sum }'
      
    • awk嵌套循环
      awk 'BEGIN { for(y=1;y<=5;y++) { for(x=1;x<=y;x++) {printf x};print} }'
      1
      12
      123
      1234
      12345
      
  • 【问】awk 的 if…elif…else
    Note

    • awk的控制语句:
      awk -F: '{if($3==0) {i++} else if($3>=1 && $3<500 || $3==65534){j++} else {k++}};END{print "管理员个数为:" i RS "系统用户个数为:"j RS "普通用户的个数为:"k }' /etc/passwd
      管理员个数为:1
      系统用户个数为:28
      普通用户的个数为:27        
      
  • 【问】awk案例:PV统计
    Note

    • 统计网站日志中PV量

      统计Apache/Nginx日志中某一天的PV量  <统计日志>
      grep '27/Jul/2017' mysqladmin.cc-access_log |wc -l
      14519
      
      统计Apache/Nginx日志中某一天不同IP的访问量 <统计日志>
      grep '27/Jul/2017' mysqladmin.cc-access_log |awk '{ips[$1]++};END{for(i in ips){print i,ips[i]} }' |sort -k2 -rn |head
      
      grep '07/Aug/2017' access.log |awk '{ips[$1]++};END{for(i in ips){print i,ips[i]} }' |awk '$2>100' |sort -k2 -rn
      
    • 名词解释:

      • 网站浏览量(PV 名词:PV=PageView (网站浏览量) 说明:指页面的浏览次数,用以衡量网站用户访问的网页数量。多次打开同一页面则浏览量累计。用户每打开一个页面便记录1次PV

      • 名词:VV = Visit View(访问次数) 说明:从访客来到您网站到最终关闭网站的所有页面离开,计为1次访问。若访客连续30分钟没有新开和刷新页面,或者访客关闭了浏览器,则被计算为本次访问结束。

      • 独立访客UV) 名词:UV= Unique Visitor(独立访客数) 说明:1天内相同的访客多次访问您的网站只计算1个UV。

      • 独立IPIP) 名词:IP=独立IP数 说明:指1天内使用不同IP地址的用户访问网站的数量。同一IP无论访问了几个页面,独立IP数均为1

;