数字传递可以用$1 $2 $3 ......
获取第一个第二个第三个参数,$0
获取命令(也就是你的文件名),$#
可以查看总的参数个数
以下文件命名为param1
(shell脚本不需要以.sh
结尾)
#!/bin/bash
echo "脚本(文件名称)$0"
echo "第一个参数$1"
echo "第二个参数$2"
echo "总共有$#个参数"
在以上代码中,通过定义$1 $2 $3 ...
的方式来获取第一个、第二个、第三个…参数,使用时只需要
└─$ ./param1 1 2 3 4 5
脚本(文件名称)./param1
第一个参数1
第二个参数2
总共有5个参数
可以看到上面的shell脚本中,我只写了两个参数,但是输入的时候输入了5个参数,最终总数$#
识别为5个参数,还有一种写法即使输入多个参数也会被识别为规定的参数,后面会有说明,以上代码的截图以及运行结果如下
{}
#!/bin/bash
echo "脚本名$0"
echo "第一个参数$1"
echo "第二个参数$2"
echo "第三个参数$3"
echo "第四个参数$4"
echo "第五个参数$5"
echo "第六个参数$6"
echo "第七个参数$7"
echo "第八个参数$8"
echo "第九个参数$9"
echo "第十个参数$10"
echo "第十个参数${10}"
在以上代码中输入10个参数:
~/Desktop $ ./param2 a b c d e f g h i j
脚本名./param2
第一个参数a
第二个参数b
第三个参数c
第四个参数d
第五个参数e
第六个参数f
第七个参数g
第八个参数h
第九个参数i
第十个参数a0
第十个参数j
可以发现如果用$10
来表示第十个参数,shell编译器会识别为$1
与"0"
,因此输出的会是第一个参数与一个字符串0
(尽管只有一个字符),若是需要获得第十个参数,需要写成${10}
。
-
传参在Linux命令中,命令后面的参数都会有-
来打头,以区分是什么参数有什么作用,比如:
ls -l # 查看文件的详细信息
ps -ef # 查看进程详情
rm -rf # 递归的删除文件及文件夹
在我自己写脚本的时候,也遇到了这种需求,比如我的一个脚本在最开始的时候会挂载一个硬盘,硬盘默认位置是/dev/sda1
,挂载位置默认是/mnt/500G
(这是一个500G的硬盘),若是插入了其他磁盘设备那么该硬盘可能会变为/dev/sdb1
甚至dc、dd等,当然挂载位置也可能因为我的需求改变,因此我写了以下脚本:
DEV="/dev/sda1"
MNT="/mnt/500G"
if [ $1 ]; then
DEV=$1
fi
if [ $2 ]; then
MNT=$2
fi
sudo mount $DEV $MNT
# ...
这样的话就可以自己指定磁盘与挂载位置,但是有一个问题,我可以使用一个参数指定挂载磁盘,比如我要将磁盘改为/dev/sdb1
,我只需要(假设该脚本文件名称为aa
)
aa /dev/sdb1
就可以获取第一个参数以指定磁盘,但是我却不可以仅用一个参数指定MNT
也就是挂载位置,因为这个参数被放在第二位,因此即使我的挂载磁盘不改变仅改变挂载位置,也需要重新输入一遍DEV
,如下:
aa /dev/sda1 /mnt/Other_File
这样显然是很麻烦的,因此就考虑到是否可以直接用-d
来指定磁盘,用-m
来指定挂载位置呢?于是乎需要挂载的时候仅使用:
mount -d /dev/sdb1 # 指定磁盘
mount -m /mnt/600G # 指定挂载位置
于是乎,正片开始,使用-
来传参:
#!/bin/bash
while getopts ":d:m:" opt
do
case $opt in
d)
echo "-d:参数为::"$OPTARG
;;
m)
echo "-m:参数为::"$OPTARG
;;
?)
echo "未知参数"
exit 1;;
esac
done
以上脚本通过一个while循环,查找输入的参数的前缀,如果有-m
字样的内容,就向下进行case
(类似于Java中的Switch),然后若是能匹配到下面的字母就进行输出参数,匹配不到的话就输出为止参数,改脚本的运行结果如下:
└─$ ./param4 -m 123 -d 123456 -f 1234565432sfdgsd
-m:参数为::123
-d:参数为::123456
未知参数
这样就可以避免掉用数字传参必须要按照位置排序的弊端
写到这里,尽可以使用./
(或者路径的方式)来使用,若是想像Linux命令一样,仅输入一个命令就能执行的话,可以将脚本复制到/bin
目录下(或者link过去)。
参考文章:「CSDN」shell中脚本参数传递的两种方式