Shell中的参数(位置和特殊)

2023-05-16

我们先来说一下 Shell 位置参数是怎么回事。
运行 Shell 脚本文件时我们可以给它传递一些参数,这些参数在脚本文件内部可以使用$n的形式来接收,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。
同样,在调用函数时也可以传递参数。Shell 函数参数的传递和其它编程语言不同,没有所谓的形参和实参,在定义函数时也不用指明参数的名字和数目。换句话说,定义 Shell 函数时不能带参数,但是在调用函数时却可以传递参数,这些传递进来的参数,在函数内部就也使用$n的形式接收,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推

这种通过$n的形式来接收的参数,在 Shell 中称为位置参数

在讲解变量的命名时,我们提到:变量的名字必须以字母或者下划线开头,不能以数字开头;但是位置参数却偏偏是数字,这和变量的命名规则是相悖的,所以我们将它们视为“特殊变量”

除了 $n,Shell 中还有 $#、$*、$@、$?、$$ 几个特殊参数,我们将在下节讲解

1) 给脚本文件传递位置参数
[root@server1 mnt]# sh test.sh http://www.baidu.com
Language: http://www.baidu.com
URL: 
[root@server1 mnt]# sh test.sh http://www.baidu.com http://taobao.com
Language: http://www.baidu.com
URL: http://taobao.com
[root@server1 mnt]# cat test.sh 
#!/bin/bash
echo "Language: $1"
echo "URL: $2"

# 其中 http://www.baidu.com 是第一个位置参数
# http://taobao.com 是第二个位置参数,两者之间以空格分隔
[root@server1 mnt]# sh test.sh 
Language: C++
URL: http://baidu.com
[root@server1 mnt]# cat test.sh 
#定义函数
function func(){
    echo "Language: $1"
    echo "URL: $2"
}

#调用函数
func C++ http://baidu.com
# 关于函数定义和调用的具体语法请访问:Shell函数定义和调用、Shell函数参数

shell特殊参数

Shell 特殊变量及其含义 
# 脚本功能是打印脚本传递的第一个参数的值
[root@server1 mnt]# sh p.sh dd # 传入一个dd字符串参数,赋值给脚本中的$1
dd
[root@server1 mnt]# cat p.sh 
echo $1
[root@server1 mnt]# sh p.sh dd pp # 传入两个字符串参数,但脚本不会接收第二个从那书 参数默认以空格分割
dd
[root@server1 mnt]# sh p.sh "dd pp" # 加引号括起来的内容传参 会作为一个字符串参数
dd pp

[root@server1 mnt]# sh p.sh dd pp
dd pp
[root@server1 mnt]# sh p.sh "dd pp" lala
dd pp lala
[root@server1 mnt]# cat p.sh 
echo $1 $2

[root@server1 mnt]# echo \${1..15}
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@server1 mnt]# echo \${1..15} >n.sh
[root@server1 mnt]# cat n.sh 
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@server1 mnt]# echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@server1 mnt]# vim n.sh 
[root@server1 mnt]# sh n.sh {a..z}
a b c d e f g h i a0 a1 a2 a3 a4 a5
# 位置参数的数字大于9后,输出的内容就不对了
[root@server1 mnt]# cat n.sh 
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15

# 当位置参数数字大于9时,需要用大括号将数字括起来
[root@server1 mnt]# sh n.sh {a..z}
a b c d e f g h i j k l m n o
[root@server1 mnt]# cat n.sh 
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}

# 获取脚本的名称及路径
# 若不带路径执行脚本,那么输出结果就是脚本的名字
# 若使用全路径执行脚本,那么输出结果就是全路径加上脚本的名字
[root@server1 mnt]# sh n.sh 
n.sh
[root@server1 mnt]# sh /mnt/n.sh 
/mnt/n.sh
[root@server1 mnt]# cat n.sh 
echo $0

# 单独获取名称和路径
[root@server1 mnt]# dirname /mnt/n.sh 
/mnt
[root@server1 mnt]# basename /mnt/n.sh 
n.sh

[root@server1 mnt]# sh n.sh 
.
n.sh
[root@server1 mnt]# cat n.sh 
dirname $0
basename $0

# 通过$#获取脚本传参的个数
[root@server1 mnt]# cat q.sh 
echo $1 $2 $3 $4 $5 $6 $7 $8 $9
echo $# $#
[root@server1 mnt]# sh q.sh {a..z}
a b c d e f g h i  #只接收了9个变量 所以打印9个字符
26 26 #传入26个参数


# 利用set设置位置参数(同命令行脚本传参)
[root@server1 mnt]# set -- "I am" westos dd.
[root@server1 mnt]# echo $#
3
[root@server1 mnt]# echo $1
I am
[root@server1 mnt]# echo $2
westos
[root@server1 mnt]# echo $3
dd.


$* 和$@的区别
在 Linux  Shell 中,$* 和 $@ 都表示参数列表中的所有参数,它们在具体使用中会有哪些不同呢?
先看一下下面的代码:
[root@server1 mnt]# sh test.sh 
1 2 3 4
1 2 3 4
[root@server1 mnt]# cat test.sh 
#!/bin/sh
foo(){
 echo $*

}
bar(){
 echo $@
}
foo 1 2 3 4 
bar 1 2 3 4 
输出没有任何区别,那么$*和$@的区别在哪里?
# 当$* 和 $@被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数
我们再看一组代码:
[root@server1 mnt]# sh test.sh 
未加引号,二者相同
11 22 33
11 22 33
加入引号后对比
----$*----
11 22 33
----$@----
11
22
33
[root@server1 mnt]# cat test.sh 
#! /bin/bash
test() {
        echo "未加引号,二者相同"
        echo $*
        echo $@
        echo "加入引号后对比"
    echo "----"\$*----""
        for N in "$*"
        do
           echo $N
        done

    echo "----"\$@----""
        for N in "$@"
        do
           echo $N
        done
}
test  11 22 33

shift命令用于对参数的移动(左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理

[root@server1 mnt]# sh test.sh a b c d e f
第一个参数为:a,参数个数为:6
第一个参数为:b,参数个数为:5
第一个参数为:c,参数个数为:4
第一个参数为:d,参数个数为:3
第一个参数为:e,参数个数为:2
第一个参数为:f,参数个数为:1
[root@server1 mnt]# cat test.sh 
#!/bin/bash
while [ $# != 0 ];do
echo "第一个参数为:$1,参数个数为:$#"
shift
done
#从上可知 shift(shift 1) 命令每执行一次,变量的个数($#)减一(之前的$1变量被销毁,之后的$2就变成了$1),而变量值提前一位


$*使用举例:
[root@server1 mnt]# sh test.sh + 1 2 3 4
10
[root@server1 mnt]# vim test.sh 
[root@server1 mnt]# cat test.sh 
#!/bin/sh
join(){
   IFS=$1
   shift
   echo "$*" | bc
   }   
join $*
##########################
$?获取上一个命令的退出状态
# $? 是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值。所谓退出状态,就是上一个命令执行后的返回结果。退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1,这和C语言的 main() 函数是类似的
[root@server1 mnt]# sh test.sh 
[root@server1 mnt]# echo $?
1
[root@server1 mnt]# sh test.sh 100
[root@server1 mnt]# echo $?
0
[root@server1 mnt]# cat test.sh 
#!/bin/bash
if [ "$1" == 100 ]
then
   exit 0  #参数正确,退出状态为0
else
   exit 1  #参数错误,退出状态1
fi

$? 获取函数的返回值
[root@server1 mnt]# sh test.sh 
73
[root@server1 mnt]# cat test.sh 
#!/bin/bash
#得到两个数相加的和
function add(){
    return `expr $1 + $2`
}
add 23 50  #调用函数
echo $?  #获取函数返回值


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Shell中的参数(位置和特殊) 的相关文章

随机推荐

  • /nginx: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No

    在CentOS7下配置Nginx xff0c 但是一致都在报错 报错信息为 xff1a nginx error while loading shared libraries libcrypto so 1 1 cannot open shar
  • 【转载】sprintf的实现

    原文链接 我们已经知道printf 是控制台程序中最常用的函数 xff0c 作用是输入的字符 数字等信息拼成完整的句子并且输出到标准输出设备 显示器 控制台等 xff0c sprintf 函数命名与printf 函数及其相似又有什么作用呢
  • 【程序员读论文】题外篇:怎么读论文

    文章目录 1 如何高效读论文 xff1f 痛苦选择顺序笔记小结讨论 2 如何有针对地高效地阅读一篇学术论文 xff1f 3 一文教你如何快速高效阅读Paper xff08 硕士生版 xff09 前言Paper从哪来Paper怎么读Paper
  • Linux中C语言标准库glibc源码下载

    在这篇文章理清gcc libc glibc libc 43 43 libstdc 43 43 的关系 xff0c 我们大概理解了libc xff0c glibc之间的一些关系 下面我们就开了解一些Linux中C语言标准库glibc源码 在这
  • 50个常用SQL语句

    50个常用SQL语句 Student S Sname Sage Ssex 学生表 S 学号 xff0c 主键 Course C Cname T 课程表 C 课程号 xff0c 主键 SC S C score 成绩表 Teacher T Tn
  • 一文搞懂交叉编译,Windows和Linux的交叉编译

    文章目录 什么是交叉编译为什么要交叉编译工具链的种类 我们应该怎样建立交叉编译环境在Windows下交叉编译和调试树莓派软件一 Windows下编译树莓派程序二 用WSL来编译树莓派程序三 通过gdbserver远程调试 基于 MinGW
  • endnote 文献保留前三个作者

    1 问题描述 xff1a endnote使用GBT7714文献格式 xff0c 显示文献的全部作者 2 想要达到的效果 xff1a 最多显示三个作者 3 解决方法 xff1a 还不知道怎么弄 xff0c 看看以后再来补充 xff0c 心情烦
  • RTK_LIB 源码、可执行文件、rtkget、观测文件、星历文件(精密星历、广播星历)、精密钟差文件介绍

    1 RTK LIB开源程序下载 xff1a 点开rtklib链接 xff1a 下载最新版本的可执行文件和程序源码 2 GNSS数据处理需要的文件 2 1 伪距定位 xff1a spp 观测数据 xff08 0 xff09 导航星历 广播星历
  • RTKLIB ppp rtk_post

    1 实时ppp xff1a IGS MGEX数据处理中心的播发的实时轨道钟差产品 xff0c 结合广播星历 xff0c 实现实时定位 2 事后的 xff08 近似实时 xff09 xff1a 下载精密星历 钟差产品 xff0c 结合其他的精
  • vscode查看代码更新历史

    开源代码推出新版本后 xff0c 如何查看代码更改信息 1 首先打开vscode xff0c 点击左侧的插件管理器 xff0c 进入插件面板 xff0c 搜索Git Graph并安装 2 点击下图图标 xff0c 即可进入Git Graph
  • git更新代码

    一 git一般有很多分支 xff0c 我们clone到本地的时候一般都是master分支 xff0c 那么如何切换到其他分支呢 xff1f 主要命令如下 xff1a 1 查看本地分支文件信息 xff0c 确保更新时不产生冲突 span cl
  • char类型数组

    字符数组 xff08 一维 二维 xff09 字符数组是数组元素为char类型的一种数组 凡是适合数组的定义和赋值 xff0c 也都适合于字符数组 由于C语言没有提供字符串类型 xff0c 字符串一般用一维字符数组来存放 xff0c 而二维
  • ubuntu18.04 安装腾讯会议

    腾讯会议现在以及上线了Linux版本 xff0c 可以直接在腾讯会议官网下载linux 版本 xff0c 在官网点击免费下载 xff0c 可以直接下载Linux版本 腾讯会议下载链接 选择Linux版本 xff0c x86 64版本 xff
  • 2.树莓派系统备份

    树莓派使用SD卡来装载系统 xff0c 如果SD卡丢失或者损坏 xff0c 那么树莓派上的数据都会丢失 xff0c 所以一定要备份好SD卡 这篇文章可以帮你备份你的树莓派系统 主要内容为备份SD卡 xff0c 制作树莓派系统镜像以及在需要的
  • ic_gvins编译及环境配置问题解决

    RTK VIO松组合 对惯导精度要求较高 1 环境配置和编译 安装依赖项 span class token comment gcc 8 span span class token function sudo span span class
  • xrdp session: Login failed for display 0 树莓派 Linux

    可以通过其他方式例如ssh或者外接显示器来cat var log xrdp log查看错误日志 xff0c 我的错误日志显示为密码错误 xrdp的登录密码和账户就是你的系统用户名和密码 xff0c 不是另外的 这里我填的账户是pi xff0
  • EVO画图设置

    一 绘图设置 1 更改背景色和网格 span class token comment 白色网格 span evo config span class token builtin class name set span plot seabor
  • GINS_OB环境配置

    1 程序简介 武大开源GNSS INS松组合IMU预积分有考虑地球自传和不考虑两种形式可以灵活设置GNSS中断时间IMU可以和里程计进行融合 2 环境配置 span class token comment gcc 8 g 43 43 8 s
  • OB_GINS程序框架

    1 程序运行 span class token builtin class name cd span OB GINS span class token comment 编译好的可执行文件 xff1a bin ob gins xff0c 参数
  • Shell中的参数(位置和特殊)

    我们先来说一下 Shell 位置参数是怎么回事 运行 Shell 脚本文件时我们可以给它传递一些参数 xff0c 这些参数在脚本文件内部可以使用 n的形式来接收 xff0c 例如 xff0c 1 表示第一个参数 xff0c 2 表示第二个参