shell 使用 getopt 获取命令行参数。

在使用 getopt 解析命令行参数时,可以处理像 -t 1.1 这样的参数。以下是一个示例脚本,展示了如何使用 getopt 来解析这些参数。

#!/bin/bash

# 使用 getopt 来解析命令行参数
TEMP=$(getopt -o t: --long tag: -n 'example.bash' -- "$@")

# 检查 getopt 的返回值,如果 getopt 返回一个错误代码,那么脚本退出
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

# 重新设置被解析的参数,将 getopt 生成的参数重新设置到 $@ 中。
eval set -- "$TEMP"

# 初始化变量
TAG_VALUE=""

# 解析选项
while true ; do
    case "$1" in
		-t|--tag) # 如果匹配到 `-t` 或 `--test`,则将其参数保存到 `TEST_VALUE` 中,并用 `shift 2` 移动到下一个参数。	        
            TAG_VALUE="$2"; shift 2 ;;
        --) shift ; break ;; # 遇到 `--` 时结束选项解析。
        *) echo "Internal error!" ; exit 1 ;; # 捕捉任何未知的选项。
    esac
done

# 输出解析结果
echo "Tag value: $TAG_VALUE"

# 剩余的非选项参数
echo "Remaining arguments: $@"
  • -o t:: 短选项 t 需要一个参数。

  • --long tag:: 长选项 --tag 需要一个参数。

  • -n 'example.bash': 为错误信息指定脚本名称。

  • -- "$@": 处理所有传递给脚本的参数。

  • getopt 返回的字符串是处理后的参数列表,将其赋值给变量 TEMP。这些处理后的参数可能包括一些添加的标记和分隔符(例如 --)以帮助进一步的参数解析。

  • -- 是一个特殊标记,用于告诉 getopt 解析器,后面的所有内容都是非选项参数,即使它们看起来像选项。例如,-t 是一个选项,但 -- -t 后面的 -t 会被视为一个普通参数而不是选项。

getopt 解析命令行参数的过程中,eval set -- "$TEMP" 这一行的目的是重新设置脚本的参数列表,以便可以按照标准的方式解析和处理这些参数。

  • eval 是一个 shell 内建命令,它会重新计算(或执行)传递给它的字符串。当你使用 eval set -- "$TEMP" 时,eval 会将 $TEMP 的内容作为命令来执行。
    例如:

    expression="3 + 4" 
    eval result=$((expression)) 
    echo "Result: $result"	
    

    这段脚本将计算 3 + 4 的结果并输出 Result: 7

    cmd="ls -l" 
    eval $cmd	
    

    这段脚本将执行 ls -l 命令,列出当前目录的详细信息。

  • set -- 会重置位置参数 ($1, $2, 等)。并确保后续的参数被视为普通参数而不是选项。当后面跟上 "$TEMP" 的内容时,它会将这些内容设置为新的位置参数。
    例如:

    set -- -t somefile.txt 
    echo $1 # 输出: -t 
    echo $2 # 输出: somefile.txt	
    

当你使用 getopt 来解析命令行参数时,返回的字符串中可能包含一些复杂的内容,例如引号和空格。为了正确处理这些内容并重新设置脚本的参数列表,使用 eval 可以确保这些参数被正确解析和传递。如果你直接使用 set -- "$TEMP",则 $TEMP 的内容会被视为单个字符串参数,而不是多个参数。

例如:

#!/bin/bash

TEMP=$(getopt -o t: --long test: -n 'example.sh' -- "$@")

if [ $? != 0 ]; then
    echo "Terminating..." >&2
    exit 1
fi

set -- "$TEMP"
echo "Before eval: $TEMP"
echo "\$1: $1"
echo "\$2: $2"
echo "\$3: $3"

eval set -- "$TEMP"
echo "After eval: $TEMP"
echo "\$1: $1"
echo "\$2: $2"
echo "\$3: $3"

输出:

$ ./example.sh -t "value with spaces" otherarg
Before eval:  -t 'value with spaces' -- 'otherarg'
$1:  -t 'value with spaces' -- 'otherarg'
$2:
$3:
After eval:  -t 'value with spaces' -- 'otherarg'
$1: -t
$2: value with spaces
$3: --

getopt 返回的字符串已经包含了所有解析后的选项和参数,这样可以确保参数的顺序和格式符合预期。通过 eval set -- "$TEMP",你可以将这些解析后的参数重新传递给脚本的参数列表,使得后续的 while 循环可以正确地解析这些参数。

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

例如:依次读取输入的参数并打印参数个数

#!/bin/bash
while [ $# != 0 ]; do
	echo "prama is $1, prama size is $#"
	shift
done

输入如下命令运行:

./shift_test.sh a b c
prama is a, prama size is 3
prama is b, prama size is 2
prama is c, prama size is 1

每次运行 shift(不带参数的),销毁一个参数,后面的参数前移。

Shift 命令一次移动参数的个数由其所带的参数指定。例如当 shell 程序处理完前九个命令行参数后,可以使用 shift 9 命令把 $10 移到 $1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值