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

我们先来说一下 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 $?  #获取函数返回值


 

发布了68 篇原创文章 · 获赞 14 · 访问量 1468

猜你喜欢

转载自blog.csdn.net/qq_41871875/article/details/104282943