Linux命令行参数如何获取?

99ANYc3cd6
预计阅读时长 20 分钟
位置: 首页 参数 正文

在 Shell 脚本中获取命令行参数

在 Shell 脚本(如 Bash)中,命令行参数通过一些特殊的变量来访问,这是最常见和最直接的方式。

linux 获取 命令行参数
(图片来源网络,侵删)

基本参数变量

假设你有一个脚本 test.sh,执行 ./test.sh arg1 arg2 arg3

变量 含义 示例 (./test.sh arg1 arg2 arg3)
$0 脚本自身的名称 ./test.sh
$1 第一个参数 arg1
$2 第二个参数 arg2
$3 第三个参数 arg3
... ... ...
$9 第九个参数 arg9
${10} 第十个参数(注意:${10} 需要花括号) arg10

示例脚本 test.sh:

#!/bin/bash
echo "脚本名称: $0"
echo "第一个参数: $1"
echo "第二个参数: $2"
echo "第三个参数: $3"

执行结果:

chmod +x test.sh  # 给脚本执行权限
./test.sh hello world "this is a test"

输出:

linux 获取 命令行参数
(图片来源网络,侵删)
脚本名称: ./test.sh
第一个参数: hello
第二个参数: world
第三个参数: this is a test

特殊参数变量

除了单个参数,还有一些特殊的变量可以提供更丰富的信息。

变量 含义
传递给脚本的参数个数
将所有参数视为一个整体(用空格连接)。
将所有参数视为多个独立的单词(通常用于循环)。
当前脚本的进程ID (PID)
上一个命令的退出状态码(0 表示成功,非 0 表示失败)。
当前 Shell 使用过的启动标志

示例脚本 special_vars.sh:

#!/bin/bash
echo "参数个数: $#"
echo "所有参数作为一个字符串: $*"
echo "所有参数作为独立单词: $@"
# 使用 $@ 循环处理参数
echo "--- 使用 $@ 循环 ---"
for arg in "$@"; do
  echo "参数: $arg"
done
# 使用 $* 循环处理参数 (注意引号的影响)
echo "--- 使用 $* 循环 ---"
for arg in "$*"; do
  echo "参数: $arg"
done

执行结果:

./special_vars.sh a b c d

输出:

linux 获取 命令行参数
(图片来源网络,侵删)
参数个数: 4
所有参数作为一个字符串: a b c d
所有参数作为独立单词: a b c d
--- 使用 $@ 循环 ---
参数: a
参数: b
参数: c
参数: d
--- 使用 $* 循环 ---
参数: a b c d

关键区别: 会将所有参数合并成一个字符串,而 会保持每个参数的独立性,在 for 循环中, 是正确处理带空格参数的方式。

高级参数处理:getopts

当你的脚本需要处理类似 ./script.sh -f filename -v 这样的选项(flags)时,手动解析 $1, $2 会变得非常麻烦,这时,getopts 是最佳选择。

getopts 是 Shell 内置命令,用于解析位置参数中的选项。

语法:

getopts optstring name [arg...]
  • optstring: 定义了有效的选项字符,如果一个选项字符后面跟着冒号 ,表示该选项需要一个参数值。
  • name: 一个变量名,getopts 会将找到的选项字符存入这个变量。
  • arg: 要解析的参数列表,默认是 。

工作原理: getopts 会循环处理参数,每次找到一个选项:

  1. 将选项字符存入 name 变量。
  2. 如果选项需要参数 (optstring 中带 ),参数值会存入 OPTARG 变量。
  3. 选项的索引存入 OPTIND 变量。
  4. 当选项解析完毕或遇到无效选项时,getopts 返回非零值,循环结束。

示例脚本 getopts_example.sh:

#!/bin/bash
# 初始化变量
input_file=""
verbose=false
# 定义选项: f: 表示 -f 需要参数; v 表示 -v 不需要参数
while getopts "f:v" opt; do
  case $opt in
    f)
      input_file="$OPTARG"
      echo "找到文件选项: -f $OPTARG"
      ;;
    v)
      verbose=true
      echo "找到详细选项: -v"
      ;;
    \?)
      echo "无效选项: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "选项 -$OPTARG 需要参数." >&2
      exit 1
      ;;
  esac
done
# 移除已处理的选项,剩下的就是位置参数
shift $((OPTIND - 1))
echo "------------------------------------"
echo "输入文件: ${input_file:-'未指定'}"
echo "详细模式: 开启"
echo "剩余位置参数: $@"

执行结果:

# 有效调用
./getopts_example.sh -f mydata.txt -v arg1 arg2

输出:

找到文件选项: -f mydata.txt
找到详细选项: -v
------------------------------------
输入文件: mydata.txt
详细模式: 开启
剩余位置参数: arg1 arg2
# 无效调用
./getopts_example.sh -f

输出:

选项 -f 需要参数.

在 C/C++ 程序中获取命令行参数

在 C/C++ 中,命令行参数通过 main 函数的两个参数传递。

main 函数的参数

int main(int argc, char *argv[]);
  • argc (argument count): 一个整数,表示 argv 数组中元素的个数,即传递给程序的参数总数。注意:argv[0] 是程序自身的名称
  • argv (argument vector): 一个指向字符串数组的指针,每个字符串是一个命令行参数。

示例 C 程序 args.c:

#include <stdio.h>
int main(int argc, char *argv[]) {
    // 打印参数总数 (包含程序名)
    printf("参数总数 (argc): %d\n", argc);
    // 循环打印每个参数
    for (int i = 0; i < argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
    return 0;
}

编译和执行:

gcc args.c -o args
./args arg1 "arg with space" arg3

输出:

参数总数 (argc): 4
argv[0] = ./args
argv[1] = arg1
argv[2] = arg with space
argv[3] = arg3

C++ 版本

C++ 的版本几乎完全相同,只是语法略有不同。

示例 C++ 程序 args.cpp:

#include <iostream>
#include <vector>
#include <string>
int main(int argc, char* argv[]) {
    std::cout << "参数总数 (argc): " << argc << std::endl;
    // 使用范围 for 循环更现代
    std::cout << "所有参数:" << std::endl;
    for (int i = 0; i < argc; ++i) {
        std::cout << "argv[" << i << "] = " << argv[i] << std::endl;
    }
    return 0;
}

编译和执行:

g++ args.cpp -o args_cpp
./args_cpp arg1 "arg with space" arg3

输出与 C 版本相同。

C++17 更简洁的写法

C++17 引入了 std::string_viewstd::filesystem,让处理参数变得更方便和安全。

#include <iostream>
#include <string_view>
#include <vector>
int main(int argc, char* argv[]) {
    // 将 char* 转换为 std::string_view,避免不必要的拷贝
    std::vector<std::string_view> args(argv, argv + argc);
    std::cout << "参数总数: " << args.size() << std::endl;
    std::cout << "所有参数:" << std::endl;
    for (const auto& arg : args) {
        std::cout << "- " << arg << std::endl;
    }
    return 0;
}

环境 方法 适用场景 优点 缺点
Shell 脚本 $1, $2, ... 简单的、按顺序的参数 简单直接,无需额外工具 参数多时难以管理,无法处理选项
Shell 脚本 , , 获取参数总数或所有参数 提供元信息,方便循环 getopts 更适合复杂选项
Shell 脚本 getopts 解析 -f, -v 等选项 功能强大,能处理带参数的选项,能检测错误 语法稍复杂,需要 case 语句
C/C++ main(int argc, char *argv[]) 编译型程序 灵活、强大、性能高 需要编译,比 Shell 脚本复杂
  • 对于简单的自动化任务和快速原型,Shell 脚本 + $1, $2getopts 是首选。
  • 对于需要高性能、复杂逻辑或与系统底层交互的程序,C/C++ 是不二之选。
-- 展开阅读全文 --
头像
智能家居室内展示视频,藏着哪些生活惊喜?
« 上一篇 今天
智能电视必须配稳压器吗?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

最近发表

标签列表

目录[+]