如何延迟变量的评估(惰性评估)?

如何延迟变量的评估(惰性评估)?

例如,我创建了 32768 个名为 0,1,2,...32767 的目录。

我想在每次运行命令时随机选择一个作为路径。

所以我更改$PATH$PATH:/blabla/$RANDOM,但它不起作用,因为$RANDOM会立即评估。

如何才能延迟评估?

答案1

这不是任何常见 shell 的功能。

最新版本ATT kshshell 中有一个独特的功能,称为纪律函数。您可以在访问变量时执行自定义代码,如果设置.sh.value为不同的值,则使用该值而不是变量的值。

function PATH.get { .sh.value=$PATH:/blabla/$RANDOM; }

然而,即使这个功能也无法帮助您,因为PATH它仅在脚本使用变量时触发,而不是PATH在 shell 内部使用变量时触发。

如果您希望最后一个 PATH 元素如此,并且您使用的是 bash 或 zsh,则可以使用它们的“未找到命令”功能在未找到命令时调用自定义代码。在bash中:

command_not_found_handle () {
  command "/blabla/$RANDOM/$@"
}

在 zsh 中:

command_not_found_handler () {
  /blabla/$RANDOM/$1 "$@[2,$#]"
}

除了这些情况之外,没有任何 shell 功能可以帮助您。无论如何,任何 shell 功能都无法帮助您处理非由 shell 调用的程序。

你可以使用LD_PRELOAD覆盖execlpexecvpexecvpe库函数可以做一些不同的事情,而不是分解成PATH用冒号分隔的部分并将每个部分解释为一个目录。看 执行前重定向文件描述符举个LD_PRELOAD例子。

或者,您可以将 PATH 条目放在保险丝文件系统实现了一个堆栈文件系统,使给定的路径对应于一个可变的底层目录。这对于只调用execve每个 PATH 元素直到其中一个起作用的程序来说是有效的,但它会使首先遍历 PATH 条目查找现有可执行文件然后执行找到的文件的程序感到困惑。

相关内容