shell脚本中的$0、$n、$#、$-、$?、$!、$$、$*、$@等和shift

  我们写别人shell脚本的时候,常会看到$0、$?、$!、$$、$*、$#、$@这样的参数,他们表示什么含义呢?

  先看一段脚本打印一下日志:

    #!/bin/bash
    
    echo 当前执行脚本: $0
    echo 参数个数: $#
    echo 参数列表: $@
    arguments=($@)
    for i in $(seq 1 $#); do
      echo 第$i个参数是: ${arguments[`expr $i - 1`]}
    done
    
    echo 参数列表: $*
    arguments=($*)
    for i in $(seq 1 $#); do
      echo 第$i个参数是: ${arguments[`expr $i - 1`]}
    done
    
    echo 当前shell启动时的选项标志: $-
    echo 上一条命令执行后的状态: $?
    echo 当前shell的进程ID: $$
    
    echo 这里在一个后台进程输出 &
    echo shell最后一次运行的后台进程ID: $!

  执行后得到结果:bash ./demo.sh a b c

  

    说明:
    $0    表示当前的执行脚本路径,如果是绝对路径,那么结果就是绝对路径,如果是相对路径,结果就是相对路径
    $#    表示脚本传进来的时候的参数个数
    $n    n是大于0的正整数,表示第n个参数,比如$1表示第一个参数,$2表示第二个参数,$5表示第5个参数
    $@    参数列表,每个参数作为单独引用
    $*    参数列表,以一个单字符串显示所有向脚本传递的参数
    $?    当前shell上一个命令执行后的状态,0表示成功正确执行,否则表示异常代码
    $$    当前shell执行的进程ID
    $!    当前shell最后一次启动的后台进程的ID
    $-    当前shell的选项标志,表示当前shell的一些设置等,常见的返回结果有
        i:交互模式
        m:监控模式
        B:使用括号展开
        H:历史扩展
        x:跟踪模式
        v:verbose模式
        K:禁止globbing(文件名扩展)
        h:禁止hashing(命令查找优化)

  $@$*

  这两个经常拿来比较,相同点是都可以获取到所有参数,却别在于参数的传递方式不一样,比如:

    #!/bin/bash

    echo "-- \$* 演示 ---"
    for i in "$*"; do echo $i; done

    echo "-- \$@ 演示 ---"
    for i in "$@"; do echo $i; done

   

  可以看到,$*把所有参数放到一个字符串里面视为一个参数了,而$@是将它们分开了,但是再未使用引号时,两者作用是一样的。

  在应用中,我们厂使用$@来传递参数,使用$*来打印内容:  

    # 使用引号包着,表示把当前脚本的所有参数逐个传递
    bash test.sh "$@"
    # 打印或者在当前脚本使用
    echo 参数列表:$*

  shift

  这里说下shift,因为我们在写脚本时,往往会使用$@来传递所有的参数,但是往往我们可能有这种需求,我们需要传递的是$@参数列表从第二个参数开始的数据,因为第一个参数可能有特殊含义,这种做法在很多命令里面是很常见的,这个时候,shift可以帮助我们进行在参数列表中进行偏移,看下代码就明白了

    #!/bin/bash
  
    echo 当前的参数列表:$*
    echo 当前的参数列表:$@

    shift
    echo 当前的参数列表:$*
    echo 当前的参数列表:$@

    shift
    echo 当前的参数列表:$*
    echo 当前的参数列表:$@

  执行命令:bash demo.sh a b c d

  

 

posted @ 2025-06-02 17:12  没有星星的夏季  阅读(295)  评论(0)    收藏  举报