加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-15 21:35:37 所属栏目:安全 来源:网络整理
导读:我看了,但只看到了一个脚本中传递的数组的答案. 我想将多个数组传递给bash脚本,该脚本将它们分配为单个变量,如下所示: ./myScript.sh ${array1[@]} ${array2[@]} ${array3[@]} 这样:var1 = array1和var2 = array2和var3 = array3 我尝试了多个选项,但是执
我看了,但只看到了一个脚本中传递的数组的答案.

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

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

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

我尝试了多个选项,但是执行variableName =(“$@”)将所有数组组合到每个变量中.我希望在我的bash脚本中有一个代表每个数组的变量.

解决方法

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

方法:长度前缀

如果效率是一个目标(无论是在解析的容易程度还是在命令行和环境存储的ARG_MAX限制之外使用的空间量),要考虑的一种方法是在每个数组前面加上描述其长度的参数.

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

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

…然后,在脚本中,您可以使用length参数将内容拆分回数组:

#!/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的用户)是允许多次传递参数来修改给定数组.在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 =(一二三)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样式链接到由写入每个数组内容的子shell写入的FIFO.

./myScript 
  <( (( ${#array1[@]} )) && printf '%s' "${array1[@]}") 
  <( (( ${#array2[@]} )) && printf '%s' "${array2[@]}") 
  <( (( ${#array3[@]} )) && printf '%s' "${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"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读