• 20191320-2021-2022-1-diocs 学习笔记3


    第10章 sh编程——教材知识点归纳

    这一章课本为我们介绍的是sh编程内容,sh是一种脚本,是一种可以实现在linux中批量执行命令的文件。

    10.1~10.2 sh脚本、sh脚本和C程序

    sh是Linux下进行批处理的脚本,我觉得它类似于windows下的bat脚本。可见sh脚本的逻辑和C语言等程序设计语言有很多相似之处,教材将它与C语言进行了对比学习。虽然相似,但根本上是不同的,因为sh是脚本,是一个解释程序,而C语言却是能生成机器码的程序设计语言。
    sh的执行和参数对应:

    mysh   a  b  c  d
     $0    $1 $2 $3 $4
    

    a、b、c、d分别和参数$1、$2、$3、$4对应。

    10.3 命令行参数

    使用sh命令时和运行程序时一样可以使用参数,如:
    mysh one two three
    其中有:
    $#为命令行参数从$1到$n的数量。
    $*为所有命令参数。
    $S为执行sh命令的PID。
    $?为最后一个命令执行的退出状态。
    教材示例:

    10.4 sh变量

    sh中也可以设置变量,A是一个变量,那么$A就代表A的值。
    给变量赋值:使用A="xxx"即可。
    B=A将B分配(assign)到A。
    B=$A意为给B赋予A的值。
    echo $A输出显示A的值。

    10.5~10.6 sh中的引号、sh语句

    sh中想要将如$/*><等的特殊字符用作普通字符,用来引用他们。类似C语言的转义。
    sh包含所有Unix/Linux命令,以及可能的I/O重定向。

    10.7 sh命令

    10.7.1 sh内置命令

    sh有一些内置命令,这些命令由sh执行,不创建新进程。这是教材上的常用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:			将位置参数$2 $3重命名为$1 $2
    trap [arg] [n]:		接收到信号n后执行参数。
    umask [ddd]:		将掩码设置为八进制数ddd的。
    wait [pid]:		等待进程pid,如果没有给出pid,则等待所有活动子进程。
    

    10.7.2 Linux命令

    这些命令原是Linux本来的命令,非常常用的有echo命令、expr命令、管道命令等。

    echo命令:echo就是打印(显示)其后面的内容,多个空格压缩为一个。
    expr命令:sh变量都是字符串,无法改为数值,但expr命令可以实现转换、运算和回转换。
    如:

    I=123
    I=I+1
    

    执行后,I的值是字符串"I+1",但如果使用下面的命令执行后:

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

    变量I的值就变成了字符串"124"
    管道命令:管道命令作为过滤器,如cat file | grep word就是从file中找到含有word的内容。

    此外还有些别的实用命令,总结在此:

    awk:	    数据处理程序。
    cmp:	    比较两个文件。
    comm:	    选择两个排序文件共有的行。
    grep:	    匹配一系列文件的模式。
    diff:	    找出两个文件的差异。
    join:	    通过使用相同的键来链接记录以比较两个文件。
    sed:	    流或行编辑命令。
    sort:	    排序或合并文件。
    tail:	    打印某个文件最后n行。
    tr:	    一对一字符翻译。
    uniq:	    从文件中删除连续重复行。
    

    10.8命令替换

    $A会替换为A的值,$(cmd)就是cmd执行后的内容的值。

    10.9sh控制语句

    条件语句

    if [condition1];  then
      statements
    elif  [condition2];  then
      statements
    else
      statements
    fi
    

    循环语句
    for语句:

    for VARIABLE in str1 str2 ... strn
      do
        commands
      done
    

    每次循环,for都接受其后面的一个变量值。
    while语句:

    while [condition]
      do
        commands
      done
    

    此外,还有continue/break语句,其用法和C语言类似,continue开始下一个迭代,break跳出循环。

    10.10~10.11 I/O重定向

    可以将输入输出流进行重定向。

    >file	stdout转向文件,如果文件不存在,将会创建文件。
    ​>>file	stdout追加到文件。
    ​<file	将文件用作stdin;文件必须存在并具有r权限。
    ​<<word 	从“here”文件中获取输入,直到只包含word的行。
    

    10.12 sh函数

    sh的函数和C等高级语言的写法类似。函数必须在任何可执行语句之前定义,没有函数原型。

    func()
    {
      # function code
    }
    

    10.13~10.15 sh中的通配符、命令分组、eval语句

    sh中的通配符
    *是通配符,可以配位所有字符。
    ?可以配对对应数量的字符。
    [xyz]配对中括号内的字符。

    sh命令分组
    类似于C语言,sh脚本可用{}()进行命令分组。{}中语句在相同的环境下执行,()在subsh进程中执行,不影响sh的工作目录。

    eval语句
    eval是sh一个内置命令,对其后的参数进行一次计算。
    a="cat file.txt"时,直接写$a会出错,而eval $a就可以执行a

    10.16 调试sh脚本

    用-x选项进行调试。如:
    bash -x mysh

    实践内容过程、问题解决过程

    用sh脚本递归复制文件

    参考了书上的方法和思想,实现了sh脚本递归复制文件。
    代码如下:

    cpf2f()
    {
    	if [ ! -e $1 ]; then
    		echo "没有找到文件:"$1
    		return 1
    	fi
    	if [ $1 -ef $2 ]; then
    		echo "错误操作:复制给自己"
    		return 1
    	fi
    	if [ -L $1 ]; then
    		echo "复制"$1"..."
    		link=$(readlink $1)
    			ln -s $link $2
    			return 0
    	fi
    	echo "复制$1给$2"
    	cp $1 $2 2> /dev/null
    }
    cpf2d()
    {
    	newfile=$2/$(basename $1)
    	echo "复制$1给路径$2"
    	cpf2f $1 $newfile
    }
    cpd2d()
    {
    	echo "复制路径$1给路径$2"
    	cp -r $1 $2
    }
    
    if  [ "$#" != "3" ];  then
      echo "参数数目错误"
    elif  [ "$1" == "cpf2f" ];  then
      cpf2f $2 $3
    elif  [ "$1" == "cpf2d" ];  then
      cpf2d $2 $3
    elif  [ "$1" == "cpd2d" ];  then
      cpd2d $2 $3
    else
      echo "错误使用"
    fi
    

    测试截图

    复制文件到文件:

    复制文件到文件夹:

    复制文件夹到文件夹:

    遇到问题和解决方法

    1.编写代码的过程遇到了问题,发现sh文件的标准还是很严格的。注意到有时不同的表示具有不同的意义,与C语言也有很多不同。在if语句中,要注意中括号后和前面都需要有空格才能实现相应的功能。
    2.编写完代码后发现不能直接执行,查资料原来是sh文件没有执行权限。需要用chmod更改权限,增加执行权限。具体为:chmod +x mycp.sh

    代码链接

    代码包括一些以前的代码,在码云。链接:https://gitee.com/Ressurection20191320/code/tree/master/IS/sh

  • 相关阅读:
    Django跨域问题
    DOM,jquery,vue
    from和modelform的用法和介绍
    元类的__call__和__new__方法的作用
    Django学习之路由分发和反向解析
    Django 自定义auth_user
    Django创建对象的create和save方法
    Flask--(登录注册)抽取视图函数
    Flask--(项目准备)--添加日志
    Flask--(项目准备)--框架搭建,配置文件抽取,业务逻辑抽取
  • 原文地址:https://www.cnblogs.com/Ressurection-20191320/p/15335720.html
Copyright © 2020-2023  润新知