美文网首页spark
linux基础学习笔记二:vim, shell和shell脚本

linux基础学习笔记二:vim, shell和shell脚本

作者: Caucher | 来源:发表于2022-07-27 00:18 被阅读0次

    3.1 vim

    只记录一些不太熟悉且强大的命令:

    • 功能键[home]或者0:到行首;
    • 功能键[end]或者$:到行尾;
    • 数字+回车:往下走多少行;
    • [ctrl] + v:矩形区块选择;
    • u:撤销;
    • [ctrl]+r:redo;
    • .:重复上个指令
    • y是复制,d是删除,有一些通用变种:
      • yy是一行,数字+yy是几行,y1G是从头到光标位置,yG是到结尾,y0是到行首,y$是到行尾。
    • :1,$s/word1/word2/gc,从头到尾替换word1为word2,c是可选的,在替换前请求确认。
      -:w [filename]:另存为, 甚至还有:n1,n2 w [filename]
    • :sp [filename]:分屏打开另一个文件。[ctrl] +w+↑用来切换窗口。
    • :set nu:显示行号。
    • :! ls /usr:暂时离开vim去执行别的命令。

    3.2 shell基础

    本节的shell都以bash为例说明。

    3.2.1 一些普通命令

    • [ctrl]+u:从当前位置删到开头,+k则是删到结尾;
    • [ctrl]+s:暂停屏幕输出,+q恢复屏幕输出。这些都可以通过stty命令来查看修改。
    • alias可以给命令起别名,对复杂且常用的命令很好用
    • history是历史命令,不过条数有限。另外也建议不要给同一个用户开多个连接,因为历史记录会被覆盖乱掉。
    • printf可以在命令行上格式化打印数据,和C语言很像。
    • 差异比较:
      • diff file1 file2可以查看两个文件的差异,在行的级别上;还可以比较目录。
        • 通过diff,我们可以制作补丁文件,diff -Naur old_file new_file > file.patch
        • 然后通过patch命令,可以将旧文件更新成新文件。
      • cmp会找字节级别上的差异。
    • 命令的查找路径:
      1. 绝对或相对路径:./program
      2. alias中的命令
      3. shell 内置命令,比如cd
      4. 操作系统提供的脚本,即$PATH的目录中提供的脚本程序。
    • 多条命令的执行:
      1. ;是多条指令连续执行;
      2. &&是前一条成功了,后面一条执行;否则不执行。
      3. ||恰好反过来,前一条失败了,后面一条执行,否则不执行。

    3.2.2 变量和环境变量

    • env观察所有环境变量,set观察所有环境变量+自定义变量,echo观察一个变量。
    • 读取环境变量时,需要用$,但对其修改时则不用,修改时只需var=/home/user即可。
      • 注意:为变量赋值时,单引号里面的值全部解析为纯文本,也就是不能读取其他变量;但是双引号里面是可以解析变量的。
      • 变量是可以累加的,最经典的PATH=${PATH}:/usr/local/bin,不需要任何符号,直接把变量放上去就行了。
      • 变量也可以从用户输入中读取,使用read命令,read -p "input sth." var
      • export可以将自定义变量share给子进程,但也只有子进程可以看到。
    • 变量类型可以定义为字符串(默认),整数,数组。命令为declare -i/a var。参数-x可以将var设为当前shell的环境变量,如下条。
    • 命令中如果需要其他命令的返回值,可以用$(locate find)括起来或者用``包裹起来。
    • 像linux的命令提示符,就是由环境变量来设置格式的;
    • 上一条指令的执行结果,会存在一个系统变量$?,一般成功则为0。
    • 变量判断检测:

    • 变量还可以做删除一部分和替换一部分,也可以检测某个变量是否存在或是否为空。
    • 在用户登录shell的时候,shell会自己读入一组环境变量,读入的文件有两个:
      1. /etc/profile:整个系统的环境变量,在这个脚本中,还会额外读入并执行:
      • /etc/profile.d/*.sh:一些基本环境和alias
      • /etc/locale.conf:语系设置
      • /usr/share/bash-completion-completions:自动补齐规则
      1. ~/.bash_profile:用户的环境变量,如果没有的话就依次找~/.bash_login或者~/.profile。会额外读入:
      • ~/.bashrc:一些个人设置,没登录的时候也会激活。
    • source或者.命令可以主动激活一个配置文件
    • ~/.bash_logout:注销shell时的操作。

    3.2.3 高级命令

    3.2.3.1 通配符与正则表达式

    shell的命令中有四种通配符可以用:

    • *:任意多个任意字符
    • ?:一个任意字符
    • [abcd]:方括号中的一个字符。类似正则表达式,[0-9][^a-c]的用法也支持。

    通配符由shell负责解析,正则表达式则由命令本身负责解析。能支持正则表达式的命令则不再使用通配符规则,比如grepsedawk等。

    • ^代表行首,$代表行尾;
    • .和通配符中的?含义一致;
    • *用来表示前一个字符零个或任意多个;
    • \{n\}表示n个前一个字符,\{n,m\}表示[n,m]个前一个字符,\{n,\}表示大于等于n个前一个字符。
    • 方括号和通配符规则一致。
    • 【扩展版】+表示一个或多个前一个字符,?表示0个或1个前一个字符。
    • 【扩展版】|表示或。
    • 【扩展版】()可以把部分正则表达式括号成一个群组,比如:
      • g(oo|la)d表示两个单词之一,A(xyz)+c表示中间一个或多个xyz。

    一些常用的正则表达式搭配:

    • .*代表0个或任意多个任意字符;
    • ^$:空白行

    还有一些宏可以用在正则表达式里:

    • [:space:]表示任何空白符,[:blank:]表示空格和TAB
    • [:lower:],[:upper:]表示小写/大写英文字母,[:alpha:]代表所有英文字母
    • [:digit:]代表所有数字,[:alnum:]代表字母和数字

    3.2.3.2 数据流重定向

    命令执行(可能)有三条数据流,输入数据流stdin,标准输出流stdout,标准错误输出流stderr,分别对应代码0,1,2。数据流重定向是将数据的末端从屏幕变成文件。

    • >:将标准输出流输出到文件中(覆盖写),>>则是追加写;
    • 2>, 2>>是写标准错误流;
    • 2>&1 >, 2>&1 >>是同时把输出流和错误列写出来;
    • 如果想丢弃这些输出,可以重定向到/dev/null这个黑洞中去;
    • <是从文件中获取输入(而非命令行),<<是指定用户键盘输入的结束字符串(没啥用)。
    • tee:转存命令,可以在多个管道命令传递数据之间额外保存中间结果到文件中,参数-a表示追加写。

    3.2.3.3 管道命令

    管道命令|是将前一个命令的标准输出作为后一个命令的标准输入,这要求后一个命令必须能接受标准输入,即是管道命令。

    • grep选行: last | grep 'root':将输入中带有pattern的行留下来,pattern支持正则表达式。参数-c可以计数,-i忽略大小写,-v反向选择,-n显示行号,-A 3显示后几行,-B 4显示前几行。
      • grep有一个重要功能就是搜索文件中出现了什么关键字,比如grep 'key' ./*, grep 'key' $(find . -type f), find . -type f | xargs -n 10 grep 'key'
    • cut选列: echo $PATH | cut -d ":" -f 5,7:将输入的每一行,按照-d后面的字符split,然后取出第-f个元素。有一个参数-c可以直接选择字符的索引区间,比如export | cut -c 10-20
    • sort排序:默认按照字典序排序各行。参数-f忽略大小写,-b忽略前导空格,-r反向排序,-n数值排序。
      • less data.txt | sort -t ":" -k 3-5 -n,用:split,按照第3-5列数值排序。
    • uniq去重:-i忽略大小写,-c对每个元素进行计数。
    • tr,join等命令可以对数据做删除/替换,两组数据的join,笛卡尔积join等,不详细展开。
    • wc计数:-l统计行数,-w统计英文字母数,-m统计字符数。
    • split划分:-b参数确定分割后的最大文件大小,-l确定最大行数。
      • split -l 10 file new_files:由于这里需要一个文件参数,如果在管道中就用-来代替文件名代表从标准输入中获得,输出的文件也可以用-来代替代表标准输出流。
    • xargs将标准输入流变成参数:很多常用命令并非管道命令,比如ls,我们可以通过...|xargs ls把标准输入流变成参数传给ls命令。
      • 有些命令只能接受一个参数,则可以用...|xargs -n 1 ls表示每次只传递一个参数;另外-p表示每次执行都询问,-e可以设置最后一个参数是什么样的。
    • sed:强大的数据操作工具。
      • 删除:...|sed '2,5d'表示删除【2,5】行;...|sed '2,$d'表示删到结尾。
      • 新增:...|sed '2a new line'表示在第二行下面新插入一行,文字为new line;通过\+回车还可以直接插入多行;
      • 替换:...|sed '2,5c repleaced text',把[2,5]行替换成了一行replaced text;
      • 打印:...|sed -n '2,5p',很简答,只打印[2,5]行,注意参数-n表示只显示操作的部分;
      • 行内替换:...|grep 'sth'| sed 's/old word'/new word/g,注意old word可以是一个正则表达式。
      • 参数-i可以直接修改文件中的数据。
      • 参数-e,如果需要多个连续操作,每个操作前面都需要加-e
    • awk: 表格式数据处理工具。以换行符定义行,以空格或[tab]分割列(可以设置分割符)。awk会迭代处理每一行,$1代表第一列,依次类推,然后判断条件,满足则执行操作。$0最特殊,表示一整行。
      基本语法是awk '条件1{操作1} 条件2{操作2}'
      • ... | awk '{print $1 "\t" $3}' 无条件,打印第一列和第三列的数据;

    awk命令还藏了两个变量,NR表示现在处理的是第几行,NF表示该行共有几列。

    • ... | awk '{print "cur line:" NR ", total columns: " NF}'

    设置分隔符是另一个变量FS

    • ... | awk 'BEGIN {FS=":"} $3<10{print $3}':第一个操作设置分隔符为:,随后若第三列<10,则打印第三列。BEGIN表示从第一行的分隔符就是:,否则从第二行开始。

    在awk的操作中,即{}中,可以有多条命令,用;或者回车可以分隔;甚至还可以定义变量,且无需加上$读取变量;再甚至可以有条件逻辑和循环逻辑,非常强大

    3.2.4 ulimit

    • ulimit可以对各个用户对系统的资源使用作出限制,比如:
      • -d 是对一个进程的内存大小的限制(不仅仅是二进制文件的数据段,也包括动态申请的堆)。
      • -l最大锁住的内存,即钉死在内存里,不允许交换的内存数据。
      • 【这个指令很强大,其他限制将继续研究补充】

    3.3 shell脚本

    shell脚本就是一系列shell命令写到文件里,从上到下依次执行而已。
    规则是碰到回车就执行当前行命令,除非是用\+回车换行。
    基本规则:

    • 第一行必须有#!/bin/bash用来指明这个脚本在哪个shell中执行,=。注意这不是注释,没有这一行系统不知道用哪个shell来执行这个脚本。
    • 可以用exit + 数字来结束这个脚本。

    执行方式:

    • 一种是直接执行,用绝对/相对路径执行,或者放到$PATH里面,或者用shbash显示执行,其实都会启用一个子进程,在子进程中执行,执行结束后,定义的变量也就丢弃了;
    • 另一种是用source来执行,这样是直接在父进程中执行,定义的变量也会得到保留。
    • 参数-x会打印执行过的每一条命令,可以用于调试。

    脚本的参数:脚本也可以拥有参数,在脚本中以特殊方式读取

    • $1代表第一个参数,后续的依次类推;
    • $0代表脚本路径;
    • $@代表全部参数的一个变量

    条件逻辑:

    if [some condition] && [other condition]; then
      sth
    elif [conditon1] || [condition2]; then
      sth
    else [condition 3]
      sth
    fi
    

    选择逻辑:

    case $var in 
      "one")
        sth
        ;;
      "two")
        sth
        ;;
      *)
        echo "Usage: ./$0 one or two"
        ;;
    esac
    

    循环逻辑:

    while [condition]
    do
        sth
    done
    
    until [condition]
    do
        sth
    done
    
    for var in one two three
    do
        sth
    done
    for var in $(ls .), for var in {1..100}, for var in $(seq 1 100)
    
    for (( i=1; i<=${th}; i=i+1 ))
    do
        sth
    done
    

    shell内的函数:没有返回值,但是可以像命令那样传递些参数进来,里面仍然会有$1,$2,$0是函数名,但与整个脚本的不同,只看调用的时候提供的参数。

    function fname(){
        echo "$1"
    }
    fname hello
    

    相关文章

      网友评论

        本文标题:linux基础学习笔记二:vim, shell和shell脚本

        本文链接:https://www.haomeiwen.com/subject/hqigirtx.html