bash脚本传递参数的方法
- 1、位置参数:如 michael michelle
- 2、特殊变量参数:如 $0 $# $@ $?
- 3、环境变量
- 4、命名参数:getopts
- 5、命名参数:getopt
- 待整理
- 10 通义千问的回答
- getopt
- 使用示例
- getopts
- 使用示例
- 总结
1、位置参数:如 michael michelle
创建脚本
#!/bin/bash
echo "第一个参数是 $1"
echo "第二个参数是 $2"
调用脚本
./ michael michelle
----------------------------------------------执行打印结果
第一个参数是 michael
第二个参数是 michelle
2、特殊变量参数:如 $0 $# $@ $?
创建脚本
#!/bin/bash
echo "The script name is $0"
echo "The number of arguments is $#"
echo "The arguments are $@"
echo "The return value of the last command is $?"
相对路径调用脚本
./ michael michelle
----------------------------------------------执行打印结果
The script name is ./
The number of arguments is 2
The arguments are michael michelle
The return value of the last command is 0
绝对路径调用脚本
/root/bbb/ aaa bbb ccc
----------------------------------------------执行打印结果
The script name is /root/bbb/
The number of arguments is 3
The arguments are aaa bbb ccc
The return value of the last command is 0
3、环境变量
在shell脚本中,可以使用$VAR
的形式来访问环境变量。在脚本里获取环境变量,可对执行环境进行检验。
#!/bin/bash
echo "HOME变量的值是=$HOME"
echo "LANG变量的值是=$LANG"
echo "PWD变量的值是=$PWD"
调用脚本
./
----------------------------------------------执行打印结果
HOME变量的值是=/root
LANG变量的值是=en_US.UTF-8
PWD变量的值是=/root/bbb
4、命名参数:getopts
getopts
是 bash 自带的命令行参数处理工具,它的语法比较简单,只支持处理单个字母选项,例如-a
、-b
等。getopts
只能处理短选项,也就是只能使用一个字母来表示选项,如果要处理长选项,需要编写更多的代码。另外,getopts处理命令行参数时会把选项和参数分别处理,不能处理连续的选项,例如-abc。
#!/bin/bash
HOST=192.168.168.168
PORT=8848
echo "HOST=${HOST} PORT=${PORT}"
while getopts ":h:p:" opt
do
case $opt in
h)
HOST=$OPTARG;;
p)
PORT=$OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
esac
done
echo "HOST=${HOST} PORT=${PORT}"
调用脚本
./
----------------------------------------------执行打印结果
HOST=192.168.168.168 PORT=8848
HOST=192.168.168.168 PORT=8848
调用脚本
./ -h 10.10.10.10 -p 8848
----------------------------------------------执行打印结果
HOST=192.168.168.168 PORT=8848
HOST=10.10.10.10 PORT=8848
调用脚本
./ -h 10.10.10.10 -p 8848 -u michael
----------------------------------------------执行打印结果
HOST=192.168.168.168 PORT=8848
Unknown parameter
5、命名参数:getopt
getopt
是GNU工具集中的一个命令行参数处理工具,它支持更多的选项和语法,可以处理短选项
和长选项
,还可以处理连续的选项
。getopt
的语法比getopts
更加复杂,需要指定一个选项字符串,包含了所有支持的选项和参数。getopt
将解析后的选项和参数保存在一个数组中,需要在代码中处理这个数组。
☞ getopt命令有以下几个参数:-o
:指定单字符选项。选项之间无需分隔符。--long
:指定长选项。长选项之间使用逗号分隔。::
:选项后添加冒号说明当前选项需要参数值。--
:分割选项和参数。
“$@”:表示将所有命令行参数作为一个字符串传递给getopt命令。
options=$(getopt -o n:a:g:p --long name:,age:,gender:,print -- "$@")会解析命令行选项和参数,并将转换后的选项和参数存储在变量options中。这个变量通常会传递给一个eval命令进行处理,例如:
eval set -- "$options"
# 测试脚本
#!/bin/bash
# 解析命令行参数
options=$(getopt -o n:a:g:p --long name:,age:,gender:,print -- "$@")
eval set -- "$options"
# 提取选项和参数
while true; do
case $1 in
-a | --age) shift; age=$1 ; shift ;;
-n | --name) shift; name=$1 ; shift ;;
-g | --gender) shift; gender=$1 ; shift ;;
-p | --print) print=true; shift ;;
--) shift ; break ;;
*) echo "Invalid option: $1" exit 1 ;;
esac
done
# 检查变量
if [ -z "$age" ]; then
echo "Error: age is required"
exit 1
fi
if [ -z "$name" ]; then
echo "Error: name is required"
exit 1
fi
if [ -z "$gender" ]; then
echo "Error: gender is required"
exit 1
fi
# 判断开关选项
if [ "$print" = true ]; then
echo "NameVal: $name; AgeVal: $age; GenderVal: $gender";
fi
# 脚本调用(长选项)
./ --name Kite --age 18 --gender f -p
NameVal: Kite; AgeVal: 18; GenderVal: f
# 脚本调用(单字符选项)
./ -n Kite -a 18 -g f -p
NameVal: Kite; AgeVal: 18; GenderVal: f
待整理
#!/bin/bash
# -uxxx -pxxx -txxx -dyyyyyMMdd
#set接受参数
v_user=""
v_pwd=""
v_table=""
v_date=$(date -d"-1 days" +"%Y%m%d")
#接收可选参数
while getopts :u:p:t:d: opt
do
case "$opt" in
u) v_user=$OPTARG;;
p) v_pwd=$OPTARG;;
t) v_table=$OPTARG;;
d) v_date=$OPTARG;;
*) echo "Unknown option: $opt" ;;
esac
done
echo "v_user=${v_user} v_pwd=${v_pwd} v_table=${v_table} v_date=${v_date}"
shift $[ $OPTIND - 1 ]
#进入脚本目录
#cd $(dirname $0)
echo $(dirname $0)
#获取根目录
#BASEHOME=$(dirname $PWD)
echo $(dirname $PWD)
[root@VM_0_11_centos test]# pwd
/root/test
[root@VM_0_11_centos test]# bash
v_user= v_pwd= v_table= v_date=20191120
.
/root
[root@VM_0_11_centos test]#
#!/bin/bash
echo $*
while getopts ":a:bc:" opt
do
case $opt in
a) echo $OPTARG $OPTIND;;
b) echo "b $OPTIND";;
c) echo "c $OPTIND";;
?) echo "error";
exit 1;;
esac
done
echo $OPTIND
shift $(( $OPTIND-1 ))
echo $0
echo $*
[root@VM_0_11_centos test]# /root/test/ -aaaa -bbbb -cccc
-aaaa -bbbb -cccc
aaa 2
b 2
b 2
b 2
b 3
c 4
4
/root/test/
结果这里有一个空行
文件内容
[N01] michael 1001
[N02] bob 1002
[N02] michelle 1003
bash读取配置文件
#!/bin/bash
while group name id
do
echo "${group} === ${name} === ${id}"
done < /root/
[N01] === michael === 1001
[N02] === bob === 1002
[N02] === michelle === 1003
getopts的使用
语法格式:
getopts [option[:]] [DESCPRITION] VARIABLE
option :表示为某个脚本可以使用的选项
":" :如果某个选项(option)后面出现了冒号(":"),则表示这个选项后面可以接参数(即一段描述信息DESCPRITION)
VARIABLE :表示将某个选项保存在变量VARIABLE中
getopts :是linux系统中的一个内置变量,一般用在循环中。每当执行循环是,getopts都会检查下一个命令选项,如果这些选项出现在option中,则表示是合法选项,否则不是合法选项。并将这些合法选项保存在VARIABLE这个变量中。
getopts :还包含两个内置变量,及OPTARG和OPTIND
OPTARG :就是将选项后面的参数(或者描述信息DESCPRITION)保存在这个变量当中。
OPTIND :这个表示命令行的下一个选项或参数的索引(文件名不算选项或参数)
---------------------------------------------------
#!/bin/bash
while getopts ':b:d:' OPT &> /dev/null;do
case $OPT in
b)
echo "The options is b"
echo $OPTARG ;;
d)
echo "The options is d"
echo $OPTARG ;;
*)
echo "Wrong Options"
exit 7 ;;
esac
# echo $OPT
# echo $OPTARG
done
echo $OPTIND
shift $[$OPTIND-1]
echo $1
----------------------------------------------------------
###执行脚本时,显示的结果如下###
[root@localhost scriptTEAM]# ./test -d 'nice' fixnale
The options is d
nice
3
fixnale
###显示信息说明如下###
当输入-d时,$OPT=d,$OPTARG='nice',因此就会显示d)...这一部分的信息。
由于这里有一个选项(-d)和一个参数('nice'),$OPTIND指向命令行中下一个选项或参数的索引位置,因此这里即为3。
shift $[$OPTIND-1]表示将文件名前面的选项和参数踢掉
=============================================================================================================
[root@localhost ~]# cat
#!/bin/bash
echo $*
while getopts ":a:bc:" opt
do
case $opt in
a) echo $OPTARG $OPTIND;;
b) echo "b $OPTIND";;
c) echo "c $OPTIND";;
?) echo "error"
exit 1;;
esac
done
echo $OPTIND
shift $(( $OPTIND-1 ))
echo $0
echo $*
-----------------------------------------------------
[root@localhost ~]# sh -a 11 -b -c 6
-a 11 -b -c 6
11 3
b 4
c 6
6
--------------------------------------------------
为什么会得到上面的结果呢?
while getopts ":a:bc:" opt #第一个冒号表示忽略错误;字符后面的冒号表示该选项必须有自己的参数。
$OPTARG 存储相应选项的参数,如上例中的11、6;
$OPTIND 总是存储原始$*中下一个要处理的选项(不是参数,而是选项,此处指的是a,b,c这三个选项,而不是那些数字,当然数字也是会占有位置的)位置。
optind初值为1,遇到"x",选项不带参数,optind+=1;遇到"x:",带参数的选项,optarg=argv[optind+1],optind+=2;遇到"x::",可选参数,属于#1和#2之一(转载过来的,这句我也看不懂)
第一行输出echo $*
第二行,optind初值为1,选项-a的参数为11,下一个要处理的选项-b位置为3,所以输出:11 3;
第三行,然后-b要处理的下一个选项-c位置为4,所以输出:b 4;
第四行,再者-c有参数,所以下一个要处理的位置+2,所以输出:c 6;
------------------------------------------------------------------
[root@localhost ~]# sh -a 11 -b -b 9 -c 6
-a 11 -b -b 5 -c 6
11 3
b 4
b 5
5
9 -c 6
------------------------------------------------------------
起初我看到以上的输出结果百思不得其解,后面多试几次选项及参数后,大概猜了一下。
第一行输出echo $*
第二行,optind初值为1,下一个要处理的选项-b位置为3,所以输出11 3;
第三行,下一个要处理的选项-b位置为4,所以输出b 4;
第四行,下一个要处理的选项-b位置为5,所以输出b 5;
程序现在遇到9,不属于getopts,所以停止循环while,下面几行就不解释了。
getopt 与 getopts 都是 Bash 中用来获取与分析命令行参数的工具,常用在 Shell 脚本中被用来分析脚本参数。
两者的比较
(1)getopts 是 Shell 内建命令,getopt 是一个独立外部工具
(2)getopts 使用语法简单,getopt 使用语法较复杂
(3)getopts 不支持长参数(如:--option ),getopt 支持
(4)getopts 不会重排所有参数的顺序,getopt 会重排参数顺序(这里的区别下面会说明)
(5)getopts 出现的目的是为了代替 getopt 较快捷的执行参数分析工作
10 通义千问的回答
getopt
和 getopts
都是 Bash 脚本中用于解析命令行参数的工具,但它们之间存在一些关键的区别。
getopt
getopt
是一个 Unix/Linux 命令行实用程序,用于解析命令行选项。它能处理带短选项(如 -f
)和长选项(如 --file
)的命令行参数,并能处理带有参数的选项(如 -f filename
)。
getopt
的主要优点是它可以处理选项和参数的复杂组合,而且它的输出格式可以被解析,以供脚本进一步处理。但是,getopt
的语法和使用相对复杂。
使用示例
#!/bin/bash
ARGS=$(getopt -o f:o: --long file:,output: -- "$@")
if [ $? != 0 ]; then
echo "Terminating..." >&2
exit 1
fi
eval set -- "$ARGS"
while true; do
case "$1" in
-f | --file ) FILE="$2"; shift 2 ;;
-o | --output ) OUTPUT="$2"; shift 2 ;;
-- ) shift; break ;;
* ) break ;;
esac
done
echo "File: $FILE"
echo "Output: $OUTPUT"
getopts
getopts
是 Bash 内置的一个函数,用于解析简单的命令行选项。它只能处理短选项,不能直接处理长选项,也不能很好地处理选项和参数混合的情况。但是,getopts
的语法简单直观,适合处理简单的命令行参数。
使用示例
#!/bin/bash
while getopts ":f:o:" opt; do
case $opt in
f )
FILE=$OPTARG
;;
o )
OUTPUT=$OPTARG
;;
\? )
echo "Invalid option: -$OPTARG" >&2
;;
: )
echo "Option -$OPTARG requires an argument." >&2
;;
esac
done
shift $((OPTIND -1))
echo "File: $FILE"
echo "Output: $OUTPUT"
总结
- getopt 更适合处理复杂的命令行选项和参数,特别是当需要处理长选项和带有参数的选项时。
- getopts 更适合处理简单的命令行选项,语法更简单,易于理解和编写。
选择哪个工具取决于你的脚本需要处理的命令行参数的复杂程度。