zoukankan      html  css  js  c++  java
  • liunx命令简介

      图形界面和命令行要达到的目的是一样的,都是让用户控制计算机。然而,真正能够控制计算机硬件(CPU、内存、显示器等)的只有操作系统内核(Kernel),图形界面和命令行只是架设在用户和内核之间的一座桥梁。由于安全、复杂、繁琐等原因,用户不能直接接触内核(也没有必要),需要另外再开发一个程序,让用户直接使用这个程序;该程序的作用就是接收用户的操作(点击图标、输入命令),并进行简单的处理,然后再传递给内核。如此一来,用户和内核之间就多了一层“代理”,这层“代理”既简化了用户的操作,也保护了内核。用户界面和命令行就是这个另外开发的程序,就是这层“代理”。在Linux下,这个命令行程序叫做 Shell。

    Shell是文本解释器程序的统称,所以包括了不止一种Shell。常见的Shell有sh、bash、ksh、rsh、csh等。sh的全名是Bourne Shell。名字中的玻恩就是这个Shell的作者。而bash的全名是Bourne Again Shell。最开始在Unix系统中流行的是sh,而bash作为sh的改进版本,提供了更加丰富的功能。一般来说,都推荐使用bash作为默认的Shell。其他Linux系统中广泛安装sh,都是出于兼容历史程序的目的。

      

    Shell命令可以分为如下三类:

    • Shell内建函数(built-in function)
    • 可执行文件(executable file)
    • 别名(alias)

      Shell的内建函数是Shell自带的功能,而可执行文件是保存在Shell之外的脚本,提供了额外的功能。Shell必须在系统中找到对应命令名的可执行文件,才能正确执行。我们可以用绝对路径来告诉Shell可执行文件所在的位置。如果用户只是给出了命令名,而没有给出准确的位置,那么Shell必须自行搜索一些特殊的位置,也就是所谓的默认路径。Shell会执行第一个名字和命令名相同的可执行文件。这就相当于,Shell帮我们自动补齐了可执行文件的位置信息。我们可以通过which命令,来确定命令名对应的是哪个可执行文件:$which date。

      别名是给某个命令设置一个简称,便于以后在Shell中就可以通过这个简称来调用对应的命令。在Shell中,我们可以用alias来定义别名:$alias freak="free -h"。Shell会记住我们的别名定义。以后我们在这个Shell中输入命令freak时,都将等价于输入free -h。在Shell中,我们可以通过type命令来了解命令的类型。如果一个命令是可执行文件,那么type将打印出文件的路径。

    总的来说,Shell就是根据空格和其他特殊符号,来让电脑理解并执行用户要求的动作。

    命令结构:

    命名名      [-单个短选项]     [-单个短选项]      [参数]

    命令名      [-多个短选项]     [参数]

    命令名      [--长选项]           [参数]

    在Linux中,可以在一个行命令中执行多个程序。比如:

    $touch demo.file; ls;

    【短路与:&&】在执行多个程序时,我们可以让后一个程序的运行参考前一个程序的返回代码。比如说,只有前一个程序返回成功代码0,才让后一个程序运行: 

    $rm demo.file && echo "rm succeed"

    如果rm命令顺利运行,那么第二个echo命令将执行。

    【短路或:||】还有一种情况,是等到前一个程序失败了,才运行后一个程序,比如:

    $rm demo.file || echo "rm fail"

    如果rm命令失败,第二个echo命令才会执行。

     Bash脚本就是把多行的Bash命令写入同一个文件。当Bash脚本执行时,Shell将逐行执行脚本中的命令。编写Bash脚本,是我们开始实现Bash代码复用的第一步。

    用文本编辑器编写一个Bash脚本hello_world.bash: 

    #!/bin/bash
    echo Hello
    echo World

     脚本的第一行说明了该脚本使用的Shell,即/bin/bash路径的Bash程序。脚本正文是两行echo命令。

    运行脚本的方式和运行可执行程序的方式类似,都是: 

    $./hello_world.bash

    需要注意的是,如果用户不具有执行Bash脚本文件的权限,那么他将无法执行Bash脚本。此时,用户必须更换文件权限,或者以其他身份登录,才能执行脚本。

    当脚本运行时,两行命令将按照由上至下的顺序依次执行。Shell将打印两行文本:

    Hello

    World

    Bash脚本是一种复用代码的方式。我们可以用Bash脚本实现特定的功能。由于该功能记录在脚本中,因此我可以反复地运行同一个文件来实现相同的功能,而不是每次想用的时候都要重新敲一遍命令。

    和可执行程序类似,脚本也可以有返回代码。一个脚本如果正常运行完最后一句,会自动的返回代码0。在脚本运行后,我们可以通过$?变量查询脚本的返回代码: 

    $./hello_world.bash
    $echo $?

     返回代码0。

    如果在脚本中部出现exit命令,脚本会直接在这一行停止,并返回该exit命令给出的返回代码。比如下面的demo_exit.bash:

    #!/bin/bash
    echo hello
    exit 1
    echo world

    返回代码

    hello 

    1

    函数

    在Bash中,脚本和函数有很多相似的地方。脚本实现了一整个脚本文件的程序复用,而函数复用了脚本内部的部分程序。一个函数可以像脚本一个包含多个指令,用于说明该函数如果被调用会执行哪些活动。

    #!/bin/bash
    function my_info (){             #my_info是函数名。在定义函数时,我们需要花括号来标识函数包括的部分,
                        #关键字function和花括号都提示了该部分是函数定义。因此,function关键字并不是必须的
                        #花括号中的三行命令,就说明了函数执行时需要执行的命令。需要强调的是,函数定义只是食谱,并没有转化成具体的动作。

    lscpu >> log              #lscpu显示本机CPU的信息,uname显示系统版本信息,free显示系统内存使用情况
    uname –a >> log          
    free –h >> log 
    }

    my_info                #脚本的最后一行是在调用函数。只有通过函数调用,函数内包含的命令才能真正执行。调用函数时,只需要一个函数名就可以了。

    在Bash中使用source命令,可以实现函数的跨脚本调用。命令source的作用是在同一个进程中执行另一个文件中的Bash脚本。

    变量是内存中的一块儿空间,可以用于存储数据。我们可以通过变量名来引用变量中保持的数据。借助变量,程序员可以复用出现过的数据。

    Bash中也有变量,但Bash的变量只能存储文本。用“=”来表示赋值。

     

    在Bash中,我们可以把一个命令输出的文本直接赋予给一个变量:

          $now=`date`

    借助``符号,date命令的输出存入了变量now。

    运算和判断

      在Bash中,你还可以通过$(())语法来进行数值运算。在双括号中你可以放入整数的加减乘除表达式。Bash会对其中的内容进行数值运算。比如

     加法:$(( 1 + 6 ))。结果为7。
     减法:$(( 5 – 3 ))。结果为2。
     乘法:$(( 2*2 ))。结果为4。
     除法:$(( 9/3 ))。结果为3。
     求余:$(( 5%3 ))。结果为2。
     乘方:$(( 2**3 ))。结果为8。

    数值大小和相等关系的判断,是最常见的逻辑判断:

    $test 3 -gt 2; echo $?       //大于
    $test 3 -lt 2; echo $?    //小于
    $test 3 -eq 3; echo $?    //等于
    $test 3 -ne 1; echo $?   //不等于
    $test 5 -ge 2; echo $?    //大于等于
    $test 3 -le 1; echo $?   //小于等于

    Bash中最常见的数据形式是文本,因此也提供了很多关于文本的判断:

    • 文本相同: $test abc = abx; echo $? 
    • 文本不同: $test abc != abx; echo $? 
    • 按照词典顺序,一个文本在另一个文本之前: $test apple > tea; echo $? 
    • 按照词典顺序,一个文本在另一个文本之后: $test apple < tea; echo $? 

    Bash还可以对文件的状态进行逻辑判断:

    • 检查一个文件是否存在: $test –e a.out; echo $? 
    • 检查一个文件是否存在,而且是普通文件: $test –f file.txt; echo $? 
    • 检查一个文件是否存在,而且是目录文件: $test –d myfiles; echo $? 
    • 检查一个文件是否存在,而且是软连接: $test –L a.out; echo $? 
    • 检查一个文件是否可读: $test –r file.txt; echo $? 
    • 检查一个文件是否可写: $test –w file.txt; echo $? 
    • 检查一个文件是否可执行: $test –x file.txt; echo $? 

    在做逻辑判断时,可以把多个逻辑判断条件用“与、或、非”的关系组合起来,形成复合的逻辑判断。 

    expression1 –a expression2

    expression1 –o expression2

    ! expression

    选择结构

    逻辑判断可以获得计算机和进程的状态。进一步,Bash可以根据逻辑判断,让程序有条件地运行,这也就是所谓的选择结构。选择结构是一种语法结构,可以让程序根据条件决定执行哪一部分的指令。最早的程序都是按照指令顺序依次执行。选择结构打破了这一顺序,给程序带来更高的灵活性。

    结构 if  [判断条件]  then……else……fi 

    如果 if 后的判断条件成立,那么执行 then 部分的代码块;如果不成立,那么脚本将执行 else 部分的代码块。末尾的 fi 结束整个语法结构。

    #!/bin/bash
    
    filename=$1
    if [ -e $filename ]
    then
      echo "$filename exists"
    else
      echo "$filename NOT exists"
    fi
    
    echo "The End"

    if 结构的选择语句可以多层嵌套:

    #!/bin/bash
    
    var=`whoami`
    echo "You are $var"
    
    if [ $var = "root" ]
    then
      echo "You are my God."
    else
      if [ $var = "vamei" ]
      then
        echo "You are a happy user."
      else
        echo "You are the Others."
      fi
    fi

    使用case语句实现多个代码块的选择执行:

    #!/bin/bash
    
    var=`whoami`
    echo "You are $var"
    
    case $var in
    root)
    echo "You are God."
    ;;
    vamei)
    echo "You are a happy user."
    ;;
    *)          //通配符*,即表示任意条件文本都可以触发此段代码块的运行。当然,前提是前面的几个文本标签都没有“截胡”。
    echo "You are the Others."
    ;;
    esac

    可以看到case结构与if结构的区别。关键字case后面不再是逻辑表达式,而是一个作为条件的文本。后面的代码块分为三个部分,都以文本标签)的形式开始,以;;结束。在case结构运行时,会逐个检查文本标签。当条件文本和文本标签可以对应上时,Bash就会执行隶属于该文本标签的代码块。

    通配符 含义 文本标签例子 通过的条件文本
    * 任意文本 *) Xyz, 123, …
    ? 任意一个字符 a?c) abc, axc, …
    [] 范围内一个字符 [1-5][b-d]) 2b, 3d, …

    循环结构是编程语言中另一种常见的语法结构。循环结构的功能是重复执行某一段代码,直到计算机的状态符合某一条件。在while语法中,Bash会循环执行隶属于while的代码块,直到逻辑表达式不成立。

    #!/bin/bash
    
    now=`date +'%Y%m%d%H%M'`
    deadline=`date --date='1 hour' +'%Y%m%d%H%M'`
    
    while [ $now -lt $deadline ]
    do
      date
      echo "not yet"
      sleep 10
      now=`date +'%Y%m%d%H%M'`
    done
    
    echo "now, deadline reached"

    关键字do和done之间的代码是隶属于该循环结构的代码块。在while后面跟着条件,该条件决定了代码块是否重复执行下去。这个条件是用当前的时间与目标时间对比。如果当前时间小于目标时间,那么代码块就会重复执行下去。否则,Bash将跳出循环,继续执行后面的语句。

    与while语法对应的是for循环。这种语法会在程序进行前确定好循环进行的次数:

    #!/bin/bash
    
    for var in `ls log*`
    do
      rm $var
    done

    在这个例子中,命令ls log*将返回所有以log开头的文件名。这些文件名之间由空格分隔。循环进行时,Bash会依次取出一个文件名,赋值给变量var,并执行do和done之间隶属于for结构的程序块。由于ls命令返回的内容在是确定的,因此for循环进行的次数也会在一开始确定下来。

    在for语法中,我们也可以使用自己构建一个由空格分隔的文本。由空格区分出来的每个子文本会在循环中赋值给变量。比如:

    #!/bin/bash
    
    for user in vamei anna yutian
    do
      echo $user
    done

    for循环还可以和seq命令配合使用:

    #!/bin/bash
    
    total=0
    
    for number in `seq 1 1 100`    //命令seq用于生成一个等差的整数序列。命令后面可以跟3个参数,第一个参数表示整数序列的开始数字,第二个参数表示每次增加多少,最后一个参数表示序列的终点。
    do
      total=$(( $total + $number ))
    done
    
    echo $total

    另外,循环中还有 continue 和 break 语句。

      编程语言的作者在设计语言时,往往会借鉴已有编程语言的优点。这是编程语言之间相似性的一大原因。程序员往往要掌握不止一套编程语言。相似的语法特征,会让程序员在学习新语言时感到亲切,从而促进语言的推广。

      Bash和C的相似性,也来自于它们共同遵守的编程范式——面向过程编程。支持面向过程编程的语言,一般都会提供类似于函数的代码封装方式。函数把多行指令包装成一个功能。只要知道了函数名,程序可以通过调用函数来使用函数功能,最终实现代码复用。

      除了面向过程编程,还有面向对象和函数式的编程范式。每种编程范式都提供了特定的代码封装方式,并达到代码复用的目的。值得注意的是,近年来出现的新语言往往会支持不止一种编程范式。

      除了相似性,我们还应该注意到Bash和C程序的区别。Bash的变量只能是文本类型,C的变量却可以有整数、浮点数、字符等类型。Bash的很多功能,如加减乘除运算,都是调用其他程序实现的。而C直接就可以进行加减乘除运算。可以说,C语言是一门真正的编程语言。C程序最终会编译成二进制的可执行文件。CPU可以直接理解这些文件中的指令。

      另一方面,Bash是一个Shell。它本质上是一个命令解释器程序,而不是编程语言。用户可以通过命令行的方式,来调用该程序的某些功能。所谓的Bash编程,只是命令解释器程序提供的一种互动方法。Bash脚本只能和Bash进程互动。它不能像C语言一样,直接调用CPU的功能。因此,Bash能实现的功能会受限,运行速度上也比不上可执行文件。

      但另一反面,Bash脚本也有它的好处。 C语言能接触到很底层的东西,但使用起来也很复杂。有时候,即使你已经知道如何用C实现一个功能,写代码依然是一个很繁琐的过程。Bash正相反。由于Bash可以便捷地调用已有的程序,因此很多工作可以用数行的脚本解决。此外,Bash脚本不需要编辑,就可以由Bash进程理解并执行。因此,开发Bash脚本比写C程序要快很多。Linux的系统运维工作,如定期备份、文件系统管理等,就经常使用到Bash脚本。

      总之,Bash编程知识是晋级为资深Linux用户的必要条件。

       

       

  • 相关阅读:
    关闭编辑easyui datagrid table
    sql 保留两位小数+四舍五入
    easyui DataGrid 工具类之 util js
    easyui DataGrid 工具类之 后台生成列
    easyui DataGrid 工具类之 WorkbookUtil class
    easyui DataGrid 工具类之 TableUtil class
    easyui DataGrid 工具类之 Utils class
    easyui DataGrid 工具类之 列属性class
    oracle 卸载
    “云时代架构”经典文章阅读感想七
  • 原文地址:https://www.cnblogs.com/zzp-biog/p/9760060.html
Copyright © 2011-2022 走看看