检索 `ash` 中第 n 个(索引)位置参数值的更好方法是 `eval echo \$$n`?

检索 `ash` 中第 n 个(索引)位置参数值的更好方法是 `eval echo \$$n`?

我希望用户在环境select中从屏幕上的编号列表中获取文件mkinitcpio busybox ash。该列表需要从上到下填充/排序并按列打印,例如:

1) 2017-12-17   3) 2017-12-19   5) 2017-12-21   7) 2017-12-23  9) 2017-12-25
2) 2017-12-18   4) 2017-12-20   6) 2017-12-22   8) 2017-12-24

我正在逐行打印到屏幕printf。这就是为什么您通常会使用数组。由于busybox ash缺乏数组支持,该黑客方法是使用位置参数( 、等)set来创建穷人的数组。$1=2017-12-17$2=2017-12-18

现在我设法使用以下方法检索位置参数值:

file=$(eval echo \$$i)

有没有更好的方法来检索第 n 个位置参数


笔记

  1. 上面列出的列是一个简化的示例,实际文件名也包含时间戳,例如2017-12-27-060056.
  2. Mkinitcpio busybox 1.27.2 编译配置

答案1

使用:

eval "file=\${$i}"

不需要命令替换,它会在删除尾随换行符时破坏数据,并且效率低下,因为它涉及 fork() 和 pipeline() 并通过该管道在两个进程之间推送数据。

echo也不应用于任意数据。

另请注意 POSIX sh 语法中对于 9 以上的数字所需的大括号。

如果$i从用户处读取,您可能需要确保它是从 1 到 1 的十进制整数,并且首先$#不带前导0s 或+s 以避免命令注入漏洞:

valid() { # args: string min max
  case $1 in
    (*[!0123456789]* | 0* | "" | ??????????*) return 1
  esac
  [ "$1" -ge "$2" ] && [ "$1" -le "$3" ] 
}

until
  printf>&2 'Enter number: '
  IFS= read -r number
  valid "$number" 1 "$#"
do
  echo>&2 "Not a valid number. Please try again."
done
eval "file=\${$number}"

答案2

您可以使用平移。这比评估要好。

猫忙.sh

leshift () {
  shift "$1"
  echo "$1"
}
echo param debut
echo $#
echo $@
for i in "$@" ; do
  echo "$i"
done

echo param shift
read a # number from 1 to 5
b=$(leshift "$a" "$@")
echo $b

echo param fin
echo $#
echo $@
for i in "$@" ; do
  echo "$i"
done

你就这样称呼它

./busy.sh a b 'c h' d e

相关内容