将多个数组作为参数传递给 Bash 脚本?

2024-04-02

我看过,但只看到了脚本中传递的一个数组的答案。

我想将多个数组传递给 bash 脚本,该脚本将它们分配为单独的变量,如下所示:

./myScript.sh ${array1[@]} ${array2[@]} ${array3[@]}

这样:var1=array1 and var2=array2 and var3=array3

我尝试过多种选择,但是variableName=("$@")将所有数组组合到每个变量中。我希望在我的 bash 脚本中有一个代表每个数组的变量。


shell 将单个参数向量(也就是说,一个简单的 C 字符串数组)传递给正在运行的程序。这是操作系统级别的限制:有不存在任何方法在参数列表中的两个程序(任何两个程序,用任何语言编写!)之间传递结构化数据,除非将该结构编码在此 C 字符串数组的成员内容中。


方法:长度前缀

如果效率是一个目标(无论是在易于解析还是在使用的空间量方面)ARG_MAX命令行和环境存储的限制),一种可以考虑的方法是为每个数组添加一个描述其长度的参数作为前缀。

但是,通过提供长度参数,您可以指示该参数列表的哪些部分应该是给定数组的一部分:

./myScript \
  "${#array1[@]}" "${array1[@]}" \
  "${#array2[@]}" "${array2[@]}" \
  "${#array3[@]}" "${array3[@]}"

...然后,在脚本内,您可以使用长度参数将内容拆分回数组:

#!/usr/bin/env bash

array1=( "${@:2:$1}" ); shift "$(( $1 + 1 ))"
array2=( "${@:2:$1}" ); shift "$(( $1 + 1 ))"
array3=( "${@:2:$1}" ); shift "$(( $1 + 1 ))"

declare -p array1 array2 array3

如果运行为./myScript 3 a b c 2 X Y 1 z,其输出为:

declare -a array1='([0]="a" [1]="b" [2]="c")'
declare -a array2='([0]="X" [1]="Y")'
declare -a array3='([0]="z")'

方法:每个参数数组名称前缀

顺便说一句,Python 世界中常见的做法(特别是对于使用argparse library https://docs.python.org/2/library/argparse.html) 是允许多次传递参数以修改给定数组。在 shell 中,这看起来像:

./myScript \
  "${array1[@]/#/--array1=}" \
  "${array2[@]/#/--array2=}" \
  "${array3[@]/#/--array3=}"

然后解析它的代码可能如下所示:

#!/usr/bin/env bash
declare -a args array1 array2 array3
while (( $# )); do
  case $1 in
    --array1=*) array1+=( "${1#*=}" );;
    --array2=*) array2+=( "${1#*=}" );;
    --array3=*) array3+=( "${1#*=}" );;
    *)          args+=( "$1" );;
  esac
  shift
done

因此,如果你的原始值是array1=( one two three ) array2=( aye bee ) array3=( "hello world" ),调用约定为:

./myScript --array1=one --array1=two --array1=three \
           --array2=aye --array2=bee \
           --array3="hello world"

方法:NUL 分隔流

另一种方法是为每个数组传递一个文件名,从中可以读取以 NUL 分隔的内容列表。这种方法的一个主要优点是数组内容的大小不计入ARG_MAX,操作系统强制执行的命令行长度限制。此外,对于可用的操作系统,下面的内容不会创建真正的磁盘文件,而是创建/dev/fd-style 链接到由写入每个数组内容的子 shell 写入的 FIFO。

./myScript \
  <( (( ${#array1[@]} )) && printf '%s\0' "${array1[@]}") \
  <( (( ${#array2[@]} )) && printf '%s\0' "${array2[@]}") \
  <( (( ${#array3[@]} )) && printf '%s\0' "${array3[@]}")

...并且,阅读(使用 bash 4.4 或更高版本,提供mapfile -d):

#!/usr/bin/env bash
mapfile -d '' array1 <"$1"
mapfile -d '' array2 <"$2"
mapfile -d '' array3 <"$3"

...或者,支持较旧的 bash 版本:

#!/usr/bin/env bash
declare -a array1 array2 array3
while IFS= read -r -d '' entry; do array1+=( "$entry" ); done <"$1"
while IFS= read -r -d '' entry; do array2+=( "$entry" ); done <"$2"
while IFS= read -r -d '' entry; do array3+=( "$entry" ); done <"$3"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将多个数组作为参数传递给 Bash 脚本? 的相关文章

  • char 数组声明中字符串文字周围的大括号有效吗? (例如 char s[] = {"Hello World"})

    偶然间我发现这条线char s Hello World 已正确编译并且似乎被视为相同char s Hello World 不是第一个 Hello World 一个包含一个 char 数组元素的数组 因此 s 的声明应为char s 事实上如
  • Python:结构体和数组与 ctypes 中的类似功能

    Python 提供了以下三个处理 C 类型以及如何处理它们的模块 struct https docs python org 3 library struct html对于 C 结构体 array https docs python org
  • 如何初始化一个最初大小未知的数组?

    假设我有这个 int x int x State Determined By Program const char pArray const int x 在使用 pArray 之前如何初始化它 因为Array的初始大小是由用户输入决定的 T
  • bash 中 :-(冒号破折号)的用法

    bash中这种风格的含义是什么 PUBLIC INTERFACE eth0 目的是什么 If PUBLIC INTERFACE存在且不为null 则返回其值 否则返回 eth0 实际上有一些记录在bash 手册页 http linux di
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 将 numpy 代码点数组与字符串相互转换

    我有一个很长的 unicode 字符串 alphabet range 0x0FFF mystr join chr random choice alphabet for in range 100 mystr re sub W mystr 我想
  • 如何避免 ArrayIndexOutOfBoundsException 或 IndexOutOfBoundsException? [复制]

    这个问题在这里已经有答案了 如果你的问题是我得到了java lang ArrayIndexOutOfBoundsException在我的代码中 我不明白为什么会发生这种情况 这意味着什么以及如何避免它 这应该是最全面的典范 https me
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are
  • C 中函数参数中的固定数组或指针之间的区别?

    之间有区别吗 void draw line float p0 2 float p1 2 float color 4 和这个 void draw line float p0 float p1 float color in C 项目清单 C 和
  • Angular JS 中的数组

    我是 Angular JS 新手 我正在将元素推送到数组中 然后想使用 ng repeat 在 html 中显示 scope groupedMedia Adding elements through a for loop scope gro
  • 重新排列数组键 php [重复]

    这个问题在这里已经有答案了 我有这个数组 Array 15 gt 13 1 16 gt Mark one answer 19 gt You see a car on the hard shoulder of a motorway with
  • bash 行长度限制从何而来?

    在运行 Bash 4 4 19 标准安装 的 Solaris 11 上 输入行似乎有 256 个字符的限制 我想了解这个限制从何而来 我浏览了手册页 但没有找到任何解决此问题的内容 仅当未使用 readline 库时才会发生这种情况 在下面
  • if [ -z "${FILE_LIST}" ] 中的 -z 是什么

    遇到了这个 什么是 z在 shell 脚本中if z FILE LIST 是相同的test And man test gives z STRING the length of STRING is zero 注意 在某些平台上 是一个符号链接
  • 远程 Informix 11.5 命令行客户端

    Informix 11 5 是否附带了与 SQL Server 的 SQLCMD 类似的命令行工具 如果是 如何连接到远程服务器并使用它执行常规 SELECT INSERT UPDATE 查询 正如 Michal Niklas 所说 IBM
  • 更改API数据输出的布局

    我是 API 集成和 PHP 的新手 我最近将 VIN 解码器集成到我的应用程序中 在输入框中输入车辆的 VIN 选择提交 然后就会显示 API 数据库中有关该车辆的所有信息 数据存储为关联数组 其中包含类别及其相应元素 例如 对于 VIN
  • 有没有办法让我简化这些回声? [复制]

    这个问题在这里已经有答案了 我仍在学习如何编写 shell 脚本 并且我面临着一个挑战 让我更容易回显 Name1 Name2 Name15 我不太确定从哪里开始 我已经想法 但如果我搞砸了 我不想看起来很傻 有什么帮助吗 我实际上还没有尝
  • 对目录中的所有文件执行命令

    有人可以提供执行以下操作的代码 假设有一个文件目录 所有这些文件都需要通过程序运行 该程序将结果输出到标准输出 我需要一个脚本 该脚本将进入一个目录 对每个文件执行命令 并将输出连接到一个大输出文件中 例如 要在 1 个文件上运行命令 cm
  • Numpy - 根据表示一维的坐标向量的条件替换数组中的值

    我有一个data多维数组 最后一个是距离 另一方面 我有距离向量r 例如 Data np ones 20 30 100 r np linspace 10 50 100 最后 我还有一个临界距离值列表 称为r0 使得 r0 shape Dat
  • 尝试使用 Javascript 解决对称差异

    我正在尝试找出对称的解决方案 使用 javascript 完成以下任务的差异 目标 接受未指定数量的数组作为参数 保留数组中数字的原始顺序 不删除单个数组中数字的重复项 删除数组中出现的重复项 因此 例如 如果输入是 1 1 2 6 2 3
  • 两种情况或 if 哪个更快? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我必须制作一个 非常 轻的脚本 它将接受用户的选项并调用脚本中的函数来执行一些任务 现在我可以使用 IF 和 CASE 选项 但我想知道两

随机推荐