首页 > 系统相关 >【Shell】getopt、set

【Shell】getopt、set

时间:2024-09-15 12:50:30浏览次数:10  
标签:选项 Shell -- shift echo set 参数 file getopt

getopt 的用途

Shell 脚本中,getopt 主要用于解析用户通过命令行传递的选项和参数,支持短选项(如 -a)和长选项(如 --all),并且可以处理带参数的选项(如 -f filename--file=filename)。

getopt 的基本用法

基本的 getopt 语法如下:

getopt optstring parameters
  • optstring:定义可以接受的选项(短选项和长选项)。

    • 短选项:类似于 -a-b,如果选项需要参数,则在选项后加上 :,例如 -f filename
    • 长选项:使用 --longoption,可以通过 --longoption=value--longoption value 传递参数。
  • parameters:脚本传入的参数,通常是 $@$*

1. 短选项解析

短选项通常是单个字符,比如 -a-b,可以连在一起,也可以带参数。

示例:
#!/bin/bash

# 定义可用选项,a 和 b 是标志选项,f 需要一个参数
options=$(getopt -o abf: -- "$@")

if [ $? -ne 0 ]; then
    echo "Failed to parse options."
    exit 1
fi

# 设置命令行参数为解析后的值
eval set -- "$options"

while true; do
    case "$1" in
        -a)
            echo "Option a"
            shift
            ;;
        -b)
            echo "Option b"
            shift
            ;;
        -f)
            echo "Option f with argument: $2"
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Invalid option"
            exit 1
            ;;
    esac
done

# 处理其他参数
for arg in "$@"; do
    echo "Argument: $arg"
done

说明:

  • -o abf::指定可接受的短选项,ab 是不带参数的选项,f: 代表 -f 选项必须带参数。
  • "$@":传递所有命令行参数给 getopt
  • eval set -- "$options":将解析后的选项重新设置为脚本参数。
  • shift:用于跳过当前处理的选项。shift 2 跳过两个参数(选项和参数值),shift 1 跳过一个参数(仅选项)。

运行脚本:

./script.sh -a -f myfile.txt argument1

输出:

Option a
Option f with argument: myfile.txt
Argument: argument1

2. 长选项解析

getopt 还支持长选项(如 --file),这通常有助于使命令行参数更加自解释。

示例:
#!/bin/bash

# 定义短选项 a, f: 和长选项 help, file:
options=$(getopt -o af: --long help,file: -- "$@")

if [ $? -ne 0 ]; then
    echo "Failed to parse options."
    exit 1
fi

# 设置命令行参数为解析后的值
eval set -- "$options"

while true; do
    case "$1" in
        -a)
            echo "Option a"
            shift
            ;;
        -f|--file)
            echo "Option file with argument: $2"
            shift 2
            ;;
        --help)
            echo "Usage: script.sh [options]"
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Invalid option"
            exit 1
            ;;
    esac
done

# 处理其他参数
for arg in "$@"; do
    echo "Argument: $arg"
done

说明:

  • --long help,file::定义长选项,file: 表示 --file 必须有参数,help 是无参数的选项。
  • -f|--file:使用 case 匹配时,短选项和长选项可以一起处理。

运行脚本:

./script.sh -a --file=myfile.txt --help argument1

输出:

Option a
Option file with argument: myfile.txt
Usage: script.sh [options]
Argument: argument1

3. 短选项和长选项混用

getopt 可以同时解析短选项和长选项,用户可以自由选择使用哪种方式。

示例:
#!/bin/bash

# 短选项 -a -b 和 -f:,长选项 --file 和 --verbose
options=$(getopt -o abf: --long file:,verbose -- "$@")

if [ $? -ne 0 ]; then
    echo "Failed to parse options."
    exit 1
fi

eval set -- "$options"

while true; do
    case "$1" in
        -a)
            echo "Option a"
            shift
            ;;
        -b)
            echo "Option b"
            shift
            ;;
        -f|--file)
            echo "Option file with argument: $2"
            shift 2
            ;;
        --verbose)
            echo "Verbose mode enabled"
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Invalid option"
            exit 1
            ;;
    esac
done

# 处理其他参数
for arg in "$@"; do
    echo "Argument: $arg"
done

运行脚本:

./script.sh -a -f myfile.txt --verbose argument1

输出:

Option a
Option file with argument: myfile.txt
Verbose mode enabled
Argument: argument1

在 Shell 脚本中,结合 getoptset 命令可以更好地解析和处理命令行选项。set 的作用是在 getopt 解析完选项后,重新配置脚本的参数,从而使处理更加方便。

4. set 的作用

在使用 getopt 时,解析后的选项和参数返回给 Shell 可能不会立即影响脚本的参数位置顺序(即 $1$2 等)。为了让这些解析后的选项能够正确地在脚本中使用,需要借助 set --getopt 的输出重新设置为 Shell 脚本的参数。

set -- 的作用是把解析后的选项(即 getopt 的输出)传递给脚本的参数列表,之后我们可以使用标准的参数引用方式(如 $1$2)来处理它们。

综合使用 getoptset

下面我们结合 getoptset,展示一个包含短选项、长选项、带参数选项的完整示例。

示例脚本:解析短选项、长选项,结合 set 使用

#!/bin/bash

# 定义短选项 (-a, -b, -f) 和长选项 (--file, --verbose)
options=$(getopt -o abf: --long file:,verbose -- "$@")

# 检查 getopt 的返回值,确定是否成功解析
if [ $? -ne 0 ]; then
    echo "Failed to parse options." >&2
    exit 1
fi

# 使用 set -- 把 getopt 的输出重新设置为命令行参数
eval set -- "$options"

# 初始化变量
file=""
verbose=0

# 解析参数
while true; do
    case "$1" in
        -a)
            echo "Option a is set"
            shift
            ;;
        -b)
            echo "Option b is set"
            shift
            ;;
        -f|--file)
            file="$2"
            echo "File option is set with argument: $file"
            shift 2
            ;;
        --verbose)
            verbose=1
            echo "Verbose mode enabled"
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Invalid option" >&2
            exit 1
            ;;
    esac
done

# 输出其他命令行参数(非选项)
for arg in "$@"; do
    echo "Remaining argument: $arg"
done

# 基于参数的条件处理
if [ $verbose -eq 1 ]; then
    echo "Verbose mode is active"
fi
if [ -n "$file" ]; then
    echo "Processing file: $file"
fi

运行示例:

假设这个脚本命名为 script.sh,然后你可以传递各种选项和参数来执行它:

./script.sh -a -f myfile.txt --verbose arg1 arg2

输出:

Option a is set
File option is set with argument: myfile.txt
Verbose mode enabled
Remaining argument: arg1
Remaining argument: arg2
Verbose mode is active
Processing file: myfile.txt

代码解析:

  1. getopt 解析选项

    • getopt -o abf: --long file:,verbose -- "$@" 解析脚本的命令行参数。
    • -o abf: 定义了三个短选项:-a-b(无参数),-f 需要一个参数。
    • --long file:,verbose 定义了两个长选项:--file(需要参数)和 --verbose(无参数)。
  2. set -- "$options"

    • getopt 解析的结果可能是一个包含空格和特殊字符的字符串。使用 eval set -- "$options" 可以将 getopt 返回的结果重新设置为当前脚本的命令行参数。set -- 重置了位置参数,使 $1$2 等能按解析后的选项顺序访问。
  3. shift 的使用

    • shift 用于跳过当前参数(即 $1),在每次处理一个选项后,需要调用 shift 来移动到下一个参数。
    • shift 2 用于带参数的选项,跳过选项本身和其对应的参数。
  4. 处理剩余参数

    • 使用 "$@" 来处理未作为选项的参数,通常是在 -- 后面的自由参数。这些参数可能是文件名、路径等。

示例 2:带有错误处理的 getopt 脚本

为了让脚本更 robust,可以添加错误处理逻辑,提示用户如何使用脚本。

#!/bin/bash

# 显示脚本的使用说明
usage() {
    echo "Usage: $0 [-a] [-b] [-f <file>] [--verbose] [other_args]"
    exit 1
}

# 解析选项
options=$(getopt -o abf: --long file:,verbose -- "$@")
if [ $? -ne 0 ]; then
    usage
fi

# 设置位置参数
eval set -- "$options"

# 解析选项
while true; do
    case "$1" in
        -a)
            echo "Option a is set"
            shift
            ;;
        -b)
            echo "Option b is set"
            shift
            ;;
        -f|--file)
            if [ -n "$2" ]; then
                echo "File option is set with argument: $2"
                shift 2
            else
                echo "Error: -f or --file requires a filename"
                usage
            fi
            ;;
        --verbose)
            echo "Verbose mode enabled"
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Invalid option"
            usage
            ;;
    esac
done

# 处理剩余参数
for arg in "$@"; do
    echo "Remaining argument: $arg"
done

运行脚本时,如果输入了不正确的选项,脚本会打印帮助信息,并退出:

./script.sh -a -f

输出:

Error: -f or --file requires a filename
Usage: ./script.sh [-a] [-b] [-f <file>] [--verbose] [other_args]

标签:选项,Shell,--,shift,echo,set,参数,file,getopt
From: https://blog.csdn.net/W__winter/article/details/142030008

相关文章

  • redis基本数据结构-set
    文章目录1.set的基本介绍1.1.set底层结构之hash表的简单介绍1.2.常用命令2.常见的业务场景2.1.标签系统2.2.社交网络好友关系1.set的基本介绍参考链接:https://mp.weixin.qq.com/s/srkd73bS2n3mjIADLVg72Aredis的set数据结构是一个无序的集合,可以存储不......
  • 工具分享 | JenkinsExploit-GUI - 一款Jenkins综合漏洞利用工具,一键getshell。
    0x00工具介绍JenkinsExploit-GUI是一款Jenkins综合漏洞利用工具。0x01下载链接JenkinsExploit-GUI下载链接:夸克网盘分享0x02功能介绍CVE-2015-8103/CVE-2016-0788CVE-2016-0792CVE-2017-1000353CVE-2018-1000600CVE-2018-1000861CVE-2018-1999002CVE-20......
  • 【工具使用】【Shell脚本】【gitlab】下拉所有的仓库代码并指定分支推送给客户仓库
    1 前言这不是项目要结束了么,项目验收要交付源代码,客户在阿里云上买了个云效,需要把我们公司的代码同步上去。首先云效支持各种导入,比如直接贴上你的gitlab地址,再加个token他就会自己同步,但我不能这么做,主要是因为我们公司有的别的项目代码也在一块,只是分支不一样,并且做事情要......
  • Linux相关命令及shell命令
    一、链接文件1.1软链接(符号链接)ls-l能看到类型为链接文件的都是软连接软连接类似于windows的快捷方式创建软连接的方式:ln-s被链接的文件文件名要生成的文件名注意:1.我们一般创建软连接时最好使用绝对路径否则一旦相对位置发生变化链接就会失效。2.如果被链......
  • dedecms靶场(四种webshell姿势)
    姿势一:通过文件管理器上传WebShell1.登陆到后台点击【核心】【文件式管理器】【文件上传】将准备好的一句话木马上传2.点击访问成功蚁剑连接姿势二:修改模板文件拿WebShell1.点击【模板】【默认模板管理】【index.htm】【修改】在文件修改中添加一句话木马保存2.......
  • aspcms webshell漏洞复现
    1.【ip】/admin_aspcms/login.asp访问后台,admin123456登录2.点击【扩展功能】【幻灯片设置】点击【保存】开启代理进行抓包3.在抓取的数据包中修改slideTextStatus字段的值为以下代码并进行发包访问影响文件字段值1%25><%25Eval(Request(chr(65)))%25><%25密码是......
  • JAVA进阶-set,Comparable排序,数据结构-树
    day07-set,Comparable排序,数据结构-树泛型Set概述和特点TreeSet集合概述和特点Comparable排序自然排序Comparable的使用使用空参构造创建TreeSet集合自定义Student类实现Comparable接口重写里面的comparaTo方法自然排序简单原理图比较器排序Compara......
  • 通过shell脚本一键修改Linux主机名和IP地址脚本
    目录1.前言 2.shell脚本的具体实现以及解析 1.1脚本功能概述1.2脚本结构分析3.致谢1.前言 在复杂的Linux系统管理中,高效准确地进行配置调整是至关重要的任务。当面临需要同时修改主机名和IP地址的情况时,手动操作不仅繁琐易错,还会耗费大量的时间和精力。想象......
  • 在shell中使用github copilot
    brewinstallghghauthloginghextensioninstallgithub/gh-copilot createalias:aliascopilot='ghcopilot';echo'aliascopilot="ghcopilot"'>>~/.zshrc&&source~/.zshrcaliasgcs='ghcopilotsuggest&#......
  • 第158天:安全开发-Python-Socket编程&反弹Shell&分离免杀&端口探针&域名爆破
    前置知识使用socket模块1.导入模块首先,你需要导入Python的socket模块。importsocket2.创建套接字使用socket.socket()函数创建一个新的套接字。这个函数可以接收两个参数:地址族和套接字类型。   地址族(AddressFamily):AF_INET用于IPv4,AF_INET6用于IP......