gpt4 book ai didi

bash - 大量参数(操作数)在命令行参数传递中排在首位

转载 作者:行者123 更新时间:2023-11-29 09:00:40 31 4
gpt4 key购买 nike

我使用以下行(希望这是最佳实践,如果不正确请纠正我)来处理命令行选项:

#!/usr/bin/bash

read -r -d '' HELP <<EOF
OPTIONS:
-c Enable color output
-d Enable debug output
-v Enable verbose output
-n Only download files (mutually exclusive with -r)
-r Only remove files (mutually exclusive with -n)
-h Display this help
EOF

# DECLARE VARIABLES WITH DEFAULT VALUES
color=0
debug=0
verbose=0
download=0
remove=0


OPTIND=1 # Reset in case getopts has been used previously in the shell
invalid_options=(); # Array for invalid options

while getopts ":cdvnrh" opt; do
echo "Actual opt: $opt"
case $opt in
c)
color=1
;;
d)
debug=1
;;
v)
verbose=1
;;
n)
download=1
;;
r)
remove=1
;;
h)
echo "$HELP"
exit 1
;;
\?)
invalid_options+=($OPTARG)
;;
*)
invalid_options+=($OPTARG)
;;
esac
done

# HANDLE INVALID OPTIONS
if [ ${#invalid_options[@]} -ne 0 ]; then
echo "Invalid option(s):" >&2
for i in "${invalid_options[@]}"; do
echo $i >&2
done
echo "" >&2
echo "$HELP" >&2
exit 1
fi

# SET $1 TO FIRST MASS ARGUMENT, $2 TO SECOND MASS ARGUMENT ETC
shift $((OPTIND - 1))

# HANDLE CORRECT NUMBER OF MASS OPTIONS
if [ $# -ne 2 ]; then
echo "Correct number of mass arguments are 2"
echo "" >&2
echo "$HELP" >&2
exit 1
fi


# HANDLE MUTUALLY EXCLUSIVE OPTIONS
if [ $download -eq 1 ] && [ $remove -eq 1 ]; then
echo "Options for download and remove are mutually exclusive" >&2
echo "$HELP" >&2
exit 1
fi



echo "color: $color"
echo "debug: $debug"
echo "verbose: $verbose"
echo "download: $download"
echo "remove: $remove"
echo "\$1: $1"
echo "\$2: $2"

如果我以 mass arguments 的方式调用脚本(那些不是开关或开关参数的参数)是最后一个参数,一切正常:

$ ./getopts.sh -c -d -v -r a b
Actual opt: c
Actual opt: d
Actual opt: v
Actual opt: r
color: 1
debug: 1
verbose: 1
download: 0
remove: 1
$1: a
$2: b

问题是当我想调用脚本时,质量参数是第一个(或者在不使用参数的开关中间的某个地方)

$ ./getopts.sh a b -c -d -v -r
Correct number of mass arguments are 2

OPTIONS:
-c Enable color output
-d Enable debug output
-v Enable verbose output
-n Only download files (mutually exclusive with -r)
-r Only remove files (mutually exclusive with -d)
-h Display this help

$ ./getopts.sh -c a b -d -v -r
Actual opt: c
Correct number of mass arguments are 2

OPTIONS:
-c Enable color output
-d Enable debug output
-v Enable verbose output
-n Only download files (mutually exclusive with -r)
-r Only remove files (mutually exclusive with -d)
-h Display this help

我认为根据 (POSIX) 标准这应该没问题,因为以下基本相同的语法在我的系统上按预期工作:

$ cp test1/ test2/ -r
$ cp test1/ -r test2/

我在互联网上进行了搜索,但唯一接近我的问题的是 this one与C有关。

最佳答案

getopts 会在检测到非破折号参数(不包括提供给带参数的 破折号 参数的参数)后立即自动中断 while 循环。 POSIX标准是先有虚线参数,然后是文件。也没有 --+ 废话。简单明了。

但是,Linux 不兼容 Unix 或 POSIX。 GNU 实用程序的本质就是比标准 Unix 实用程序“更好”。更多的功能,更多的选择,以及处理事情的方式有点不同。

在 Linux 上,命令行参数可以在许多 GNU 实用程序中文件之后。

例如:

$ cp -R foo bar

在我的 Unix 认证的 Mac OS X 和 Linux 上工作,但是,

$ cp foo bar -R

仅适用于 Linux。

如果您希望 getopts 像许多 Linux 实用程序一样工作,您需要做一些工作。

首先,您必须自己处理参数,而不是依赖于 $OPTIND 来解析它们。您还需要验证您是否有论点。

我想出了这个作为做你想做的事的例子。

#! /bin/bash

while [[ $* ]]
do
OPTIND=1
echo $1
if [[ $1 =~ ^- ]]
then
getopts :a:b:cd parameter
case $parameter in
a) echo "a"
echo "the value is $OPTARG"
shift
;;
b) echo "b"
echo "the value is $OPTARG"
shift
;;
c) echo "c"
;;
d) echo "d"
;;
*) echo "This is an invalid argument: $parameter"
;;
esac
else
other_arguments="$other_arguments $1"
fi
shift
done
echo "$other_arguments"

我现在只要设置了 $* 就循环。 (也许我应该使用 $@?)我必须在循环结束时执行 shift。我还每次都将 $OPTIND 重置为 1,因为我正在自己转移参数。 $OPTARG 仍然设置,但我必须再做一次 shift 以确保一切正常。

我还必须在我的 if 语句中使用正则表达式来验证参数是否以破折号开头。

基本测试表明它有效,但我不能说它没有错误,但它确实让您了解如何处理您的程序。

您仍然可以从 getopts 获得很多功能,但它确实需要更多的工作。

关于bash - 大量参数(操作数)在命令行参数传递中排在首位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28583500/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com