声明变量时防止命令替换运行

Nor*_*tfi 3 bash command-substitution variable

所以我最近注意到,在使用命令替换声明变量时,让我们这样说:

var=$(echo "this is running" > test; cat test)
Run Code Online (Sandbox Code Playgroud)

然后,它运行(该文件test将被创建),尽管我还不被称为(技术上的),我想这样:

var=$(echo "this is running" > test; cat test)
echo "$var" # is where i would "normally" call the variable
Run Code Online (Sandbox Code Playgroud)

在变量中声明命令替换时,如何防止命令替换实际运行,因此它仅在我调用所述变量时才实际运行

PS:很清楚这是一个不好的例子,但它很好地展示了我的意思,尽管“无用的使用 cat”和“无用的使用 echo”......

Sté*_*las 10

听起来您想要一个内容是动态生成的变量。

bash不支持ksh93 的纪律,或 zsh 的动态命名目录或 mksh 的值替换,这将使其更容易,但您可以使用这种 hack,使用 namerefs:

var_generator() { date --iso-8601=ns; }
var_history=()
typeset -n var='var_history[
  ${##${var_history[${#var_history[@]}]=$(var_generator)}},${#var_history[@]}-1
]'
Run Code Online (Sandbox Code Playgroud)

此处var定义为对$var_history数组元素的引用,使用数组索引动态求值并允许运行任意代码的事实(此处用于运行var_generator函数并将其输出分配给数组的新元素)。

然后:

bash-5.1$ echo "$var"
2021-03-23T13:36:43,243211696+00:00
bash-5.1$ echo "$var"
2021-03-23T13:36:45,517726619+00:00
Run Code Online (Sandbox Code Playgroud)

尽管您可以在$(var_generator)这里使用,但这听起来有点太复杂了。不过,一个优点是您仍然可以执行${var#pattern}while bash(与 相反zsh)不会让您执行的操作${$(cmd)#pattern}