在命令行中传递数组的名称以在函数中引用该数组

在命令行中传递数组的名称以在函数中引用该数组

我正在尝试通过更新 bash_profile 来了解更多 bash,以便我可以快速执行一些通常需要复制粘贴的 adb 命令。我发现我正在创建许多类似的函数,它们看起来都是这样的:

function andVid() {
  minInputs=0
  fileName="$(filNamInc $MEDIA_DIR/Videos/aaaAndroidVideo mp4)"
  origCmd="adb shell screenrecord --time-limit 60 /sdcard/screenrecord.mp4; sleep 3; adb pull /sdcard/screenrecord.mp4 $fileName"
  cmd="$(andAddSer $minInputs "$origCmd" "$@")"
  echo "Use ctrl+c to stop recording"
  eval $cmd
}

通常,当我看到一堆类似的函数时,我会尝试将它们合并为一个函数。所以我创建了一个函数,它接受一个参数数组,并根据数组执行相同的操作:

andVid=(4 'adb shell screenrecord --time-limit 60 /sdcard/screenrecord.mp4; sleep 3; adb pull /sdcard/screenrecord.mp4' '/Videos/aaaAndroidVideo' 'mp4')

function adbRnr() {
  minInputs=$1
  cmd=$2
  if (( $# > 3 )); then
    fileTarget=$3
    fileExtension=$4
    fileName="$(filNamInc $MEDIA_DIR$fileTarget $fileExtension)"
    cmd="$cmd $fileName"
  fi
  if (( $# > $minInputs )); then
    cmd="${cmd:0:4} -s ${@: -1} ${cmd:4}"
  fi
  eval $cmd

(注意:在这里您可以看到 andAddSer 在第一个函数中做了什么。)这意味着为了运行该函数,您需要使用如下命令行条目:

adbRnr "${andVid[@]}"

打字既慢又难记。我宁愿只输入数组的名称,然后在函数中执行整个“${[@]}”部分,这样命令行输入将如下所示:

adbRnr andVid

然而......传递数组名称已被证明是一个重大问题。我几乎尝试了用“!”调用参数的所有组合,但没有成功。例子:

andVid=(4 'adb shell screenrecord --time-limit 60 /sdcard/screenrecord.mp4; sleep 3; adb pull /sdcard/screenrecord.mp4' '/Videos/aaaAndroidVideo' 'mp4')

function arrayParser() {
  echo "${andVid[*]}"    # echos as expected
  echo $#                # echos "1" as expected
  param=$1               
  echo $param            # echos "andVid" as expected
  cmd=("${!param[3]}")
  echo $cmd              # expected "mp4", nothing printed
}

arrayParser andVid

我知道您不能只将数组传递给 bash 中的函数,但我引用的数组已经是配置文件的一部分。如何使用参数引用数组?

答案1

在函数中使用名称引用变量:

arrayParser () {
    declare -n arr="$1"

    printf 'Array: %s\n' "${arr[*]}"
    printf 'Array element at index 3: %s\n' "${arr[3]}"
}

myarray=( alpha beta gamma "bumbling bee" )
arrayParser myarray

在函数内部,对名称引用变量的任何引用都arr将引用传递给函数作为其第一个参数的变量。

名称引用变量是在bash版本 4.3 中引入的。

答案2

像这样的东西:

andVid=(4 'adb shell screenrecord --time-limit 60 /sdcard/screenrecord.mp4; sleep 3; adb pull /sdcard/screenrecord.mp4' '/Videos/aaaAndroidVideo' 'mp4')

param=andVid
cmd="\${$param[3]}"
eval echo "$cmd"

相关内容