我正在尝试获取一个包含许多函数的大型脚本,这需要一些时间。同时我想显示一个对话框“获取资源请稍候...”。获取资源后我想使用我的函数。但使用对话框似乎取消了获取资源。获取资源确实通过对话框进行处理,但函数未运行。
文件:main.script.sh
#!/bin/bash
long task...
function PrintDate(){
date
}
文件:job1.sh
#!/bin/bash
source main.script.sh | dialog --progressbox "sourcing please wait..." 20 80
PrintDate
命令提示符:
bash job1.sh
我得到的输出
PrintDate: command not found
答案1
挑剔之处:
- 你的“shebangs”是错误的——它们应该开始
#!
。 - 实际上,您不需要在要作为源的文件中放置“shebang”。您可能希望将其去掉,这样可以清楚地表明该文件是要作为源的,而不是作为普通脚本运行的。(具体来说,您可能应该以类似这样的注释开头
# This file is meant to be sourced and not run as an ordinary script.
) - 严格来说,你不需要在要运行的文件中添加“shebang” ,尽管它并没有什么坏处。
bash scriptname
- 当然,你会得到
PrintDate: command not found
。你的main.script.sh
文件没有定义PrintDate
;它正在定义PritnDate
。
但你的问题的真正答案是:
- 整个要点
source
是源脚本在当前主 shell 进程中被读取和解释,但是当你将它作为管道的一部分时,你会强制它在子进程中运行。 诀窍是创建管道而不创建管道。这样做的诀窍是使用流程替代 (一个 bash 扩展命令替换)。此命令:
source main.script.sh > >(dialog --progressbox "sourcing please wait..." 20 80)
将创建一个子进程来运行该
dialog
程序,并创建一个从主 shell 进程到该子进程的管道,但随后它使该管道看起来像一个普通文件,并将命令的输出发送source
到管道,同时使其看起来像标准输出的普通重定向。因此,source
在主 shell 进程中运行(在本例中,是bash
运行job1.sh
脚本的进程),因此您的函数在脚本中定义job1.sh
。