shell基础知识总结

1. shell

  对于一台计算机而言,其硬件受系统内核的控制,使用者想要控制计算机,就必须有与系统内核进行通讯的手段。而shell就是使用者与计算机进行通讯的手段之一。从命名上看,shell其实是相对于kernel(内核)而言,指系统与外界(使用者)进行接触的部分,一个提供系统功能给用户使用的软件,它接受来自用户的指令,然后调用相应的应用程序。
  为了满足不同的需求,shell提供了两种执行命令方式:

  • a. 交互式:解释并执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令。
  • b. 程序设计式:作为一种脚本语言,提供变量、控制结构和函数,再通过解释器解释并执行。
    Linux上常见的shell有sh、bash、ksh、tcsh等,不同解释器在某些语法的执行方面可能有些不同。通过查看/etc/shells文件就可以知道本系统所支持的shell解释器类型。如shells的文件内容如下:
    [email protected]~$ cat /etc/shells
    /bin/sh
    /bin/bash
    /sbin/nologin
    /usr/bin/sh
    /usr/bin/bash
    /usr/sbin/nologin
    /bin/tcsh
    /bin/csh
    /bin/ksh
    /bin/zsh
    

      而linux默认是用的解释器是bash。在脚本头可以声明本脚本所使用的解释器,
    声明方式: #!/bin/bash

2. 变量

  • a. 赋值

    • 赋值方式:variable_name = variable_value
    • 等号两边不能有空格符;
    • 增加变量内容:PATH=”$PATH”:/home/bin
    • 取消变量:unset variable_name
    • 变量类型:可以使用declare [[-/+]aixr] [name[=value] …],其中-表示赋予变量属性,+表示去除变量属性,a-数组,i-整数,r-只读,x-环境变量
  • b. 自定义变量与环境变量

    • 使用“=”赋值得到的自定义变量,这个变量的作用域为当前shell进程。
    • 使用export命令可以声明一个环境变量,一个环境变量的作用域为当前shell进程及
      其shell子进程(subshell)。
    • 在启动shell进程的时候,shell会从文件中加载一些默认的环境变量到shell进程中,
      如HOME、PATH等。
    • 用env可以查看当前所有的环境变量,set则可以看所有的环境变量和自定义变量。
    • p.s. 关于子shell进程

      • i. 创建一个shell子进程的方式包括但不限于:

        • 使用&提交后台作业。后台作业于subshell中运行;
        • 使用管道。|左右的命令均在独立的subshell中运行;
        • 括号操作符。()中的命令在subshell中运行;
        • 执行外部脚本或程序。
      • ii. subshell可以继承shell父进程的属性包括:当前的工作目录、环境变量、标准输入输出和错误输出、所有已打开的文件描述符、忽略的信号。
      • iii. subshell对环境变量的修改对shell父进程不可见。
  • c. shell中的单引号、双引号和反引号

    • 双引号:保留$的变量扩展功能,使用变量时会$后的变量转变为变量的值。在双引号中可以使用转义符\将$转变为纯文本符号。使用双引号后不支持正则匹配。
    • 单引号:不保留特殊符号的功能,括号内内容仅作为纯文本进行使用。
      如:
      [email protected]~$ echo "I am $name"
      I am someone
      [email protected]~$ echo ‘I am $name‘
      I am $name
      
    • 反引号:引号内内容会被作为命令先被执行,命令的结果作为引号的输出。$()的效果与之相同
      如:
      [email protected]~$ echo I am `pwd`
      I am /home/asl
      [email protected]~$ echo I am $(pwd)
      I am /home/asl
      
    • p.s. 反引号与$()的一点区别

        — 参考自http://km.oa.com/articles/show/310289
      先来看几个例子:

      [email protected]~$ echo `echo \$SHELL`
      /bin/bash
      [email protected]~$ echo $(echo \$SHELL)
      $SHELL
      [email protected]~$ echo `echo \\$SHELL`
      $SHELL
      [email protected]~$ echo $(echo \\$SHELL)
      \/bin/bash
      [email protected]~$ echo `echo \`
      >
      [email protected]~$ echo $(echo \\)
      

        参考的文章的解释是“反引号齐本身就对\进行了转义,保留了齐本身意思,如果我们想在反引号中起到\的特殊意义,我们必须使用2个\来进行表示”。
        对此我的理解是,在反引号中,\表示续行(见倒数第二个例子),\才表示转义符。而在$()中,\本身就起到转义符的效果。

      3. 数组

  • a. 赋值

     #shell脚本中#表示行注释
      array=(0 1 2 3 4)
      array[101]=101           #直接通过 数组名[下标] 就可以对其进行引用赋值。
                                         #如果下标不存在,自动添加新一个数组元素
      unset array[101]         #使用unset清除指定值
      unset array              #使用unset清除整个数组
    
  • b. 取值

    echo ${array[2]}      #使用下标获取值
    echo ${a[@]}         #使用@或*获取数组所有值
    echo ${a[*]}
    

    输出结果:

    2
    0 1 2 3 4
    0 1 2 3 4
    
  • c. 截取

     #${数组名[@或*]:起始位置:长度}
    newArray=(${array[@]:1:3}) #先截取数组"1 2 3",再将截取到的数组赋给newArray
    
  • d. 遍历

    for a in ${arr[@]}
    do
         echo "$a"
    done
    
  • e. 拆分字符串到数组

    a="one,two,three,four"
    OLD_IFS="$IFS"    #使用临时变量保存环境变量IFS的值
    IFS=","                    #给环境变量IFS赋值,这个值用来切割字符串
    arr=($a)                  #字符串切分
    IFS="$OLD_IFS"    #还原IFS
    

4. 语法

  • a. if

    if语句的格式如下:

    if …; then
      …
    elif …; then
      …
    else
      …
    fi
    

    注意格式中分号;的使用。
    if的判断语句中,方括号和逻辑运算符两边都必须有空格(“]”的右边除外)。

  • p.s. []必须有空格的原因

      “[“ 是linux系统中的指(试试whereis [),用法与test相同,但最后一个参数必须是 “]”。这也是为什么then前面要加分号”;”的原因。相似地可以推出,if后面可以接其他指令,利用其返回值进行判断,当返回值为0时if才判断为true
    如:

    [email protected]~$ if echo "123"; then
    > echo "123"
    > fi
    123
    123
    
  • p.s. (),(()),[]和[[]]

    ( ): 1. 用于数组的初始化
      2. 指令群组(command group),即用括号将一组命令包括起
    来,这组命令共用一个shell子进程,因此可以分享自定义变量等。
    (( )): 相当于命令let,用于算数运算。举个例子:

    [email protected]~$ ((a=1+1)); echo $a
    2
    [email protected]~$ ((a=1+1)); echo $a
    2
    

    [ ]和[[ ]]的区别:
     如上所说,[其实是一个指令,因此使用判断中字符串时最好用双引号括住,
    且>、<必须改写成>和\<(>,<是重定向符)。
      另外,在使用&&和||时,必须写成 [ cond1 ] && [ cond2 ] 的形式。
    [[ ]]则是bash的关键字。可以直接使用>、<、&&、||,如[[ a>1 && b>2 ]]。
     [[ ]]中字符串未双引号括住的话,能进行正则表达式匹配。如:

    [email protected]~$ [[ ab == a* ]] && echo "ok"
    ok
    

    if语句支持的运算符/操作符:(可以理解为是[指令的参数,就像rm -rf一样)

  • b. for

    for var in …; do
          do something
    done
    for (( cond1; cond2; cond3 )) do
          do something
    done
    

应用示例:

     #输出1 2 3 4 …… 10
for i in $(seq 10); do    #这里是用seq指令生成了"1 2 3 …… 10"的字符串
        echo $i;
done;
    #判断输入的字符串是不是文件名
for file in $*; do    # $*指从命令行读入的参数,如输入"test.sh a.xml b.txt c.pdf",则$*=(a.xml b.txt c.pdf)
        if [ -f "$file" ]; then
            echo "INFO: $file exists"
        else
            echo "ERROR: $file not exists"
        fi
done;
  • p.s. 关于脚本的传入参数

    • $#是入参的个数,
    • [email protected]和$*是当前所有的入参
    • $0是脚本的名字
    • $1是第一个入参,$2是第二个入参,以此类推
    • pp.s. [email protected]和$*的区别
      • 不被双引号””括起来时,[email protected]和$*一致。
      • 被双引号””括起来时:
        • “$*”表示“$0IFS$1IFS$2”。举个例子,设IFS为“-”,入参为“1 2 3”,则输出为“1-2-3”。
        • “[email protected]”与[email protected]相同
          ```
  • c. while和until

    while [ cond1 ] && { || } [ cond2 ] …; do
          do something
    done
    
    until [ cond1 ] && { || } [ cond2 ] …; do
          do somethingdone
    

    应用示例:

    # 逐行输出/etc/hosts文件内容
    while read line; do
          echo $line;
    done < /etc/hosts;
    # 这里能读入/etc/hosts,是因为<将文件重定向到read指令
    
  • d. case

    case var in
      pattern 1 )
          … ;;
      pattern 2 )
          … ;;
      *)
          … ;;
    esac
    
  • case行尾必须为单词“in”,每一个模式必须以右括号“)”结束。
  • ;; 表示命令序列结束。
  • pattern可以使用匹配符,如
    • a|b: a或者b
    • *:匹配任意长度的任意字符;
    • ?:匹配任意单个字符;
    • [-]:范围匹配
  • 另外提一下shfit,它可以将入参左移,即进行赋值:$1=$2;$2=$3;$3=$4……
    case可以与shfit结合使用,用于根据入参进行处理,举例如下:
    shell脚本test.sh:
    #!/bin/bash
    while [ $# -gt 0 ]; do
          case $1 in
          -a)
                  shift; echo a-$1; shift;
          ;;
          -b|-d)
                  shift; echo bd-$1; shift;
          ;;
          -c)
                  shift; echo c-$1; shift;
          ;;
          *)
                  echo unkown; shift;
          esac
    done
    

    输出:

    [email protected]~$ ./test.sh -a 1 -c 2 -b 3 -d 3
    a-1
    c-2
    bd-3
    bd-3
    
  • e. function

    • 函数定义

      functionname()
      {
      do something
      }
      function func()
      {
      do something
      }
      
    • 函数调用
      函数必须先定义后使用。
      func param1 param2 ... # 函数内使用$#,$1等方式获取参数属性和参数,与脚本获取入参类似
      
  • 函数返回值
    func
    ret=$?            #使用$?获取函数的执行结果
    ret=`func`      #使用反单引号执行函数并将返回值赋值给变量
    
  • 函数变量
      + 脚本中定义的变量可在函数中使用
      + 函数中可用local关键字声明属于自己的,不被外部可见的局部变量
    

后记

  学习过shell的基础知识后,最大的感受是原以为是 shell脚本的特殊用法事实上是有规律可推理的。在此之前,虽然知道[]两边要加空格、使用while read $line;do……done < a.txt可以逐行读入文件等零碎的知识点,但只是知其然却不知其所以然。了解了shell的特殊符号的含义后,才发现这些东西并非只能靠死记硬背,而是有规则可循的。

时间: 2024-10-24 09:40:08

shell基础知识总结的相关文章

【Linux系列】【基础版】第三章 Shell基础知识

3. Shell基础知识     3.1 Shell的由来         3.1.1 Bourne Agin Shell         3.1.2 其他的shell, 有 zsh, ksh等     3.2 查看有没有shell         3.2.1 yum list | grep zsh         3.2.2 ls /root/.bash_history         3.2.3 echo $HISTSIZE -> vi /etc/profile 修改HISTSIZE的值 -

centos shell基础知识 2015-4-8 第十二节课

centos shell基础知识  2015-4-8 第十二节课 上半节课 下半节课 history:命令历史 ,默认保存1000条命令历史 !!:上一条命令 !$:上一条命令的最后一个参数 !n:执行命令历史里的第n条命令 !字符:最近那个字符的命令 Tab 键可以补全文件路径或者命令alias a=“b” unalias a通配符 *匹配零个或多个字符 ?匹配一个字符输入输出重定向 >, >>, <, 2>, 2>>管道符 |作业控制 ctrl+z, jobs

Shell 基础知识和总结

调试脚本 检查脚本语法错误 bash -n /path/to/some_script 调试执行 bash -x /path/to/some_script shell里的变量 本地变量:只对当前shell有效:作用范围可以是整个shell程序文件,包括脚本中的函数,对其他的shell无效.    环境变量:对当前shell及子进程shell有效.    声明.赋值:export name=value 或者 declare -x name=value    局部变量:与函数的生命周期一样:     

shell基础知识---与监听服务器长连接端口状态

从未写过脚本我的最近接了俩脚本的需求,就在这分享一下我的我学到基础知识主要就四部分内容 一.变量 变量的定义 string='字符串' string="字符串" num=808string=str 字符串可以用单引号和双引号包裹,也可不包裹.数字话不用引号包裹的话就是一个数值. 变量也可以用来接受语句给变量赋值 file=`ls -l filepath/txt.txt` 上面的语句是接收filepath 下的txt.txt文档 数组的定义 程序中常用的还有数组在 Shell 中,用括号

shell基础知识讲解

第1章 shell基础 1.1 什么叫做shell编程 shell编程也叫做bash高级编程语法 1.2 常见的shell命令解释器 bash????????????redhat和centos使用 dsh????????????Ubuntu使用 csh和tcsh????unix使用 1.3 开发语言程序代码的分类说明 编译型????????????写完后需要编译才可以运行(C语言,java语言) 解释型????????????写完就可以直接运行(shell语言) 1.4 脚本规范 1.4.1 书

Shell基础知识

防伪码:长风破浪会有时,直挂云帆济沧海. 1.1 l Shell  简介 Shell 是一个 C 语言编写的脚本语言,它是用户与 Linux 的桥梁,用户输入命令交给 Shell 处理, Shell 将相应的操作传递给内核(Kernel),内核把处理的结果输出给用户. 下面是处理流程示意图: Shell 既然是工作在 Linux 内核之上,那我们也有必要知道下 Linux 相关知识. Linux 是一套免费试用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 UNIX 的多用户.多

Linux操作系统基础解析之(七)——Bash(Shell)基础知识(1)

在日常交际英语中,Shell可以翻译成壳,大多指能够对内部核心起到保护作用的一种装置或结构.在计算机科学中,shell其实是指:为操作者提供的.能够通过系统调用或库调用使用整个计算机资源的访问接口. 它既是一种命令解析器又是一种程序设计语言.作为命令解析器,它可以解释和执行用户输入的命令,也可以自动地解释和执行预先编写好并保存在某个文本文件中的一系列的命令:作为程序设计语言,shell特别定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和条件分支,让我们可以像使用高级语言

Linux操作系统基础解析之(七)——Bash(Shell)基础知识(3)

五.注释 在非交互shell中或交互式shell中,内置命令shopt的选项interactive_comments被开启.以"#"开始的词使得这个词所在这一行上所有其他的剩余字符都被忽略(或称注释).交互式shell不用开启interactive_comments选项也不支持注释.interactive_comments选项在交互式shell中是默认启用的.注释是编写程序时,写程序的人给一个语句.程序段.函数等的解释或提示,能提高程序代码的可读性,以便于以后的参考.修改.后来,在应用

Linux操作系统基础解析之(七)——Bash(Shell)基础知识(5)

十一.函数  shell函数就是按照上面SHELL GRAMMAR的描述定义的保存着一系列等待稍后执行的命令.当shell函数名被当做一个简单命令名使用时,被这个函数名关联的一系列命令都被执行.函数在当前shell的上下文环境中被执行:不会创建新的进程来解释它们(这与shell脚本的执行形成了对比).当执行函数时,函数的参数成为执行过程中的位置参数.特殊参数#被更新以反映这个变化.特殊参数0不会改变.函数执行时,FUNCNAME变量的第一个元素被设置为函数的名称.  shell执行环境的所有其他