Linux 需要一种优雅的方式来重载由另一个工具动态创建和调用的Bash脚本中的命令吗

Linux 需要一种优雅的方式来重载由另一个工具动态创建和调用的Bash脚本中的命令吗,linux,bash,alias,Linux,Bash,Alias,有很多关于如何在Bash中重载命令的帖子,要么通过创建别名或函数,要么只是更改脚本本身或如何调用脚本;这些方法对我来说非常有意义,但不适用于我试图解决的问题 在半导体行业,使用EDA工具在Tcl解释器中提供API命令是很常见的;在我的例子中,EDA工具生成一个Bash脚本,然后执行一个API调用,因此我只能在脚本执行后访问脚本,并且不能修改它的调用方式,因为这是在后台发生的;也没有合适的方法来修改写入脚本的感兴趣的命令 更复杂的是,这个脚本是由奇点容器中的EDA工具生成和调用的;另外,正在调用的

有很多关于如何在Bash中重载命令的帖子,要么通过创建别名或函数,要么只是更改脚本本身或如何调用脚本;这些方法对我来说非常有意义,但不适用于我试图解决的问题

在半导体行业,使用EDA工具在Tcl解释器中提供API命令是很常见的;在我的例子中,EDA工具生成一个Bash脚本,然后执行一个API调用,因此我只能在脚本执行后访问脚本,并且不能修改它的调用方式,因为这是在后台发生的;也没有合适的方法来修改写入脚本的感兴趣的命令

更复杂的是,这个脚本是由奇点容器中的EDA工具生成和调用的;另外,正在调用的命令驻留在不同的EDA工具容器中,因此必须将此命令“vsim”转换为对工作负载管理器(slurm)的ssh调用。例子:
vsim
必须转换为:
ssh“srun-vsim”

同样,在父shell中设置名为“vsim”的别名或函数对我不起作用;子流程没有继承别名/函数(我很难接受)。我还尝试创建一个名为“vlog”的符号链接,它指向一个静态调度程序脚本;我不希望将调度程序的路径硬编码为文件路径;我更愿意使用变量,如
vlog->…/$VERSION/bin/dispatch\u for_flows
,但符号链接不是动态的

我想我还是应该使用符号链接的方法,但不是指向调度程序,而是指向一个对调度程序的插值路径执行单行的包装器,但我仍然不相信设置别名并不能解决问题。多年来,我编写了Csh脚本,其中包含了绕过用户别名的命令的完整路径;对于Bash,看起来别名永远不会被继承,即使在父shell或/etc/profile中启用shopt'expanand_alias'。我错过了什么

有人能让下面的例子起作用吗?我希望脚本从父shell继承别名,并在执行时不出现“command not found”错误,也不修改脚本或如何调用脚本。同样,在脚本执行之前,我无法访问它,也无法控制它的调用方式;bash是父shell,bash是脚本,我在操作系统上有根访问权限,因此如果需要,我可以更改bash的版本(使用4.4.19(1)-release(x86_64-redhat-linux-gnu))

有人能让下面的例子起作用吗

不,这在别名中是不可能的-您不能导出别名。但是您可以导出一个函数

$ hello() { echo world; }
$ export -f hello
$ ./test.bash
world
您可以在路径中创建自定义命令:

$ printf "%s\n" "#!/bin/bash" "echo world" > /usr/local/bin/hello
$ chmod +x /usr/local/bin/hello
类似地,添加自定义命令,并使用命令将新路径添加到path和export

有人能让下面的例子起作用吗

不,这在别名中是不可能的-您不能导出别名。但是您可以导出一个函数

$ hello() { echo world; }
$ export -f hello
$ ./test.bash
world
您可以在路径中创建自定义命令:

$ printf "%s\n" "#!/bin/bash" "echo world" > /usr/local/bin/hello
$ chmod +x /usr/local/bin/hello

类似地,添加一个自定义命令并添加新路径,同时将该命令添加到path和export。

hello是一个bash函数而不是一个程序,您不能
exec
。可以执行运行函数的bash
exec bash-c hello
。很好,我不知道可以导出函数。仅供参考,我尝试了你的函数示例;它在脚本中工作,但在前面加上“exec”时就不行了,例如“`$cat test.bash”#/usr/bin/bash exec hello$./test.bash./test.bash:第2行:exec:hello:notfound```但我的问题是伪造了一个程序;函数是聪明的,但是如果我想做一个“exec”,那么这种方法就行不通了。与第二个解决方案类似,最后,容器本身需要被分解,因此为了避免重新编译的需要,我扩展了容器内部的路径,在容器外部包含一个分解目录,在这里我将删除指向执行ssh的通用脚本和对slurm的调用的符号链接。在build.def中具有函数或别名将无法缩放。所以我想我做了第二个答案。hello是一个bash函数而不是一个程序,你不能执行它。可以执行运行函数的bash
exec bash-c hello
。很好,我不知道可以导出函数。仅供参考,我尝试了你的函数示例;它在脚本中工作,但在前面加上“exec”时就不行了,例如“`$cat test.bash”#/usr/bin/bash exec hello$./test.bash./test.bash:第2行:exec:hello:notfound```但我的问题是伪造了一个程序;函数是聪明的,但是如果我想做一个“exec”,那么这种方法就行不通了。与第二个解决方案类似,最后,容器本身需要被分解,因此为了避免重新编译的需要,我扩展了容器内部的路径,在容器外部包含一个分解目录,在这里我将删除指向执行ssh的通用脚本和对slurm的调用的符号链接。在build.def中具有函数或别名将无法缩放。所以我想我做了一些类似于第二个答案的事情。我决定通过为需要存在于搜索路径中但不存在的程序创建一个符号链接目录来打破容器。符号链接指向对分派脚本的特定版本执行exec的脚本。所以调用堆栈看起来像:
eda\u script.bash
->
vsim…
($PATH中的符号链接)->
dispatch\u包装器…
(指向特定版本的调度工具的一行代码)->
../dispatch--tool vsim…
->
ssh$HOST“srun-vsim…”
我决定采用一种方法,通过创建一个符号链接目录来打破容器