• 《Linux/Unix系统编程》第十章学习笔记


    sh编程

    sh脚本

    sh脚本是一个包含sh语句的文本文件,命令解释程序sh要执行该语句,所有的sh基本都执行相同的任务,脚本在语法上略有不同,shebang允许允许主sh调用适当版本的sh来执行脚本。如果未指定shebang,默认执行sh,即下列程序的第一行。

    例:创建一个一个文本文件mysh,包含:

    #! /bin/bash //sh第一行通常以#!开始通常称为shebang

    //当bash执行mysh脚本时,将会打印hello

    # comment line

    echo hello

    • 使用chmod +x mysh使其可执行。然后运行mysh。

    • 当主sh见到shebang时,读取脚本所针对的程序名并调用该程序

     

    sh脚本与C程序的区别

    • sh是一个解释程序,逐行读取sh脚本文件并直接执行这些行,如果行是可执行命令且为内置命令,那么sh可直接执行。否则,复制一个子进程来执行命令,等待子进程终止后再继续,这与它执行单个命令行完全一样。

      其次,sh脚本中每个变量都是字符串,不需要类型;

      sh脚本不需要 main()函数,第一个可执行语句就是程序的入口点。

    • C程序必须先编译链接到一个二进制可执行文件,然后通过sh子进程运行可执行的二进制文件。

      其次,C程序中,每个变量必须有一个类型。

      C语言必须有 main()函数。

     

    命令行参数

    可使用与运行sh命令完全相同的参数调用sh脚本:

    mysh one two three

    sh脚本中可以通过0−0−{n}访问命令行参数,其中需要注意的是:后10个参数必须被称为{$x},x>10。

    命令行参数:

    # = 命令行参数1到1到n的数量 * = 所有命令行参数,包括00S = 执行sh的进程PID $? = 最后一个命令执行的退出状态(若成功为0,否则为非0)

     

    sh变量

    • sh内置变量:PATH、HOME、TEAM......

    • 用户自定义变量:可以使用任何符号作为sh变量,不需要声明。所有sh变量都是字符串。未赋值的sh变量是NULL字符串。

    • sh的赋值方法:

      variable=string

     

    sh中的引号

    sh有许多特殊字符,如$、/、*、>、<

    用作普通字符时:使用 或者单引号来引用他们。

    A=xyz

    echo $A ==>$A //将原样归还

    echo '$A' ==> $A

     

    单双引号的区别:

    • 单引号内没有替换;

    • 双引号用于保留双引号字符串中的空格,且会发生替换;

     

    sh命令

    • .file :读取并执行文件。

    • break [n]:从最近的第 n 个嵌套循环中退出。

    • cd [dirname]:更换目录。

    • continue [n]:重启最近的第 n 个嵌套循环。

    • eval [arg...]:计算一次参数并让sh执行生成的命令。

    • exec [arg...]:通过这个 sh 执行命令, sh 将会退出。

    • exit[n]:使 sh 退出,退出状态为 n 。

    • export [var...]:将变量导出到随后执行的命令。

    • read [var...]:从 stdin 中读取一行并为变量赋值。

    • set [arg...]:在执行环境中设置变量。

    • shift :将位置参数223...重命名为112...

    • trap [arg[n]:接收到信号 n 后执行参数。

    • umask [ ddd ]:将掩码设置为八进制数 ddd 的。

    • wait [pid];等待进程 pid ,如果没有给出 pid ,则等待所有活动子进程。

    • read 命令:当 sh 执行 read 命令时,它会等待来自 stdin 的输入行。它将输人行划分为几个标记,分配给列出的变量。

    在获得read的输入后,sh可能会测试输入的字符串,以决定下一步做什么

     

    Linux命令

    • echo:将参数字符串作为行回显到stdout,通常将多个空格压缩为一个(除非有引号);

     

    • expr:用于在UNIX/LINUX下求表达式变量的值,一般用于整数值,也可用于字符串;

    expr的运行方式:

    expr string1 OP string2

    首先将两个参数字符串转换为数字,然后对数字执行二进制操作OP,再将得到的数字转换回字符串。

    I=123
    I=$(expr $I+1)

     

    管道命令

    在sh脚本中经常使用管道作为过滤器。

     

    实用命令

    • awk:数据处理程序;

    • cmp:比较两个文件;

    • comm:选择两个排序文件共有的行;

    • grep:匹配一系列文件的模式;

    • diff:找出两个文件的差异;

    • join:通过使用相同的键来连接记录以比较两个文件;

    • sed:流或行编辑命令;sort:排序或合并文件;

    • tail:打印某个文件的最后n行;

    • tr:一对一字符翻译;

    • uniq:从文件中删除连续重复行。

       

    命令替换

    当sh遇到'cmd'$(cmd)时,会优先执行cmd,并用执行结果字符串替换cmd。

     

    sh控制语句

    sh是一种编程语言,支持许多执行行控制语句;

    在sh上每个语句需要单独在一行上,若用分号将多个语句隔开,则运行多个语句在同一行;

    在sh中0为TRUE。这是因为当sh执行命令时,它会获得命令执行的退出状态,执行成功则为0,否则非0。

     

    if-else-fi语句
    if [condition]; then
    statements
    else
    statements
    fi
    字符串比较

    (将参数作为字符串进行比较)

    if [s1 = s2]
    if [s1 != s2]
    if [s1 < s2]
    if [s1 > s2]
    作为整数比较
    -eq           #等于
    -ne           #不等于
    -gt           #大于
    -lt           #小于  
    -ge           #大于等于
    -le           #小于等于
    文件比较

    if [ -x name]

    -e filename #如果 filename存在,则为真
    -f filename #如果 filename为常规文件,则为真
    -d filename #如果 filename为目录,则为真
    -r filename #如果 filename可读,则为真
    filename1 -ef filename2 #如果 filename1与filename2相同,则为真
    if-elif-else-fi复合语句

    与C语言的if-else语言类似。

    if [condition1]; then
    statements
    elif [condition]; then
    statements
    #additional elif[condition3]; then
    .....
    else
    statements
    fi

    复合条件:类似C语言的 &&(AND)和||(OR),但是语法比C语言更加严格。条件必须用一对匹配的双括号[[和]]括起来。

    例:

    if[[ conditional1 & conditional2]];then
    if[[conditional1 & (conditional2 || expression3)]];then
    for语句

    每次迭代中,变量接受一个参数字符串值,并执行do和done之间的命令

    for VARIABLE in string1 string2 ... stringn
    do
    statements
    done
    while语句

    当条件为真时,重复执行do-done语句,直至为假时退出

    while [condition]
    do
    statements
    done
    until-do语句

    当条件为真时退出循环

    until [condition]
    do
    statements
    done
    case语句

    在sh中比较少用

    case $variable in
    pattern1) commends;;
    pattern2) commend;;
    patternN) commend;;
    esac
    continue 和 break 语句

    continue重启最近循环的下一个迭代

    break退出循环

    工作原理与C语言完全相同

     

    I/O重定向

    进入sh命令时,我们可以指示sh将I/O重定向到除默认stdin、stdout和sterr以外的文件。I/O重定向有以下形式和含义:

    • .>file stdout转向文件,如果文件不存在,将会创建文件

    • .>>file stdout追加到文件

    • <file 将文件用作stdin;文件必须存在具有r权限

    • <<word 从“here”文件中获取输入,直到包含“word”的行

     

    嵌入文档

    可以指示输出命令从stdin获取输入,将其回显到stdout,直到遇到预先安排的关键字。

    echo << END
    END
    cat << DONE
    DONE

    这种文档被称为嵌入文档。他们通常用在sh脚本中,以生成长块的描述性文本,不需要分别回显每一行。

     

    sh函数

    定义:

    func()
    {

    }

    因为sh逐行执行命令,所以必须在任何可执行语句之前定义sh脚本中的所有函数。

    sh无法声明函数原型

     

    sh中的通配符

    *通配符:可扩展到当前目录中的所有文件

    • file *:列出当前目录中所有文件的信息

    • ls *.c:列出当前目录中所有以.c结尾的文件

      ?通配符:查询某文件名中的字符

    • file ???:有三个字符的所有文件名

    • ls *.??:点号后有2个字符的所有文件名

      []通配符:查询文件名中一对[]中的字符

    • file [ab]:包含字符a或b的所有文件名

    • ls [xyz]:列出所有包含x、y或z的文件名

    • ls [a-m]:列出包含a到m范围内字符的所有文件名

     

    命令分组

    • 在sh脚本中,可以用{}或()对命令进行分组。

    • {ls;mkdir abc;ls;}:通过当前sh执行{}中的命令列表。{}命令分组的唯一用处是在相同环境下执行这些命令,例如,为分组中的所有命令重定向I/O

    • 更有用的分组是(),由subsh执行。

    • (cd newdir;ls;A=value;mkdir $A):通过subsh进程执行()中的命令。subsh进程可在不影响父sh的情况下更改其工作目录。此外,当subsh进程终止时,subsh中的任何赋值变量都不起作用。

     

    eval语句

    eval [arg1 arg1 ...argn]

    eval是sh的一个内置命令。由sh自己执行,不需要复制新进程。

    它将输入参数字符串连接到一个字符串中,计算一次,即执行变量和命令替换,然后给出结果字符供sh执行。

     

    调试sh脚本

    sh脚本可由带有 -x 选项的子sh运行,以进行调试,如

    bash -x mysh

    子sh可以将在执行命令之前显示要执行的每个sh命令,包括变量和命令替换。允许用户跟踪命令执行。

    出错,sh将在错误行上停止并显示错误信息。

     


    大家学习过Python,C,Java等语言,总结一下一门程序设计语言有哪些必备的要素和技能?这些要素和技能在shell脚本中是如果呈现出来的?

    知识点归纳以及自己最有收获的内容 (3分)

    我认为每一门编程语言都有不同擅长的方向,譬如C语言就更加偏向于底层,直接作用于底层,使用起来相对复杂,但是确实是最为基础的知识。而python、Java语言则更加高级,面向对象,上手会相对较快,但是如果没有底层相关的知识,上升空间会受到局限。在我看来Python、Java能做的事比C语言要多,日常应用的话也相对广泛,但是若要是开发系统之类的,C语言使用的还是更多,因为面向底层,使其漏洞和错误会比较少。

    语义、语法、语言规则是程序设计语言的必备要素,无论什么语言基础的都是在学他们,但是在这之上是逻辑,

    shell脚本就是由Shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑,脚本不用编译即可运行。它通过解释器解释运行,所以速度相对来说比较慢。shell脚本中最重要的就是对shell命令的使用与组合,再使用shell脚本支持的一些语言特性,完成想要的功能。

     

  • 相关阅读:
    mongodb的sql日志
    mysql – 在WHERE子句中使用substr的SELECT语句
    MySQL视图
    Linux简单查找log
    转 信号量与PV操作
    二进制小数及 IEEE 浮点表示
    转 :原码,反码,补码
    转:C# Delegate委托 1
    C#中Invoke的用法2
    C#中Invoke的用法1
  • 原文地址:https://www.cnblogs.com/Aegon-Targaryen/p/15339776.html
Copyright © 2020-2023  润新知