我正在尝试设置一个 cron 作业来对通常在交互式环境中运行的软件运行回归测试(CASA,对于那些好奇的人来说:http://casa.nrao.edu/我有一个 shell 脚本,以 MWE 形式 ( mwe.sh
) 执行下列操作:
casapy -c mwe.py
在哪里执行该脚本。 casapy
是一个相当复杂的业务,它在内部完成很多事情,包括导入和设置用于多处理的 ipython 客户端。
这是我的问题:如果我以交互方式运行代码,即casapy -c mwe.py
在 bash shell 命令行中输入,它可以正常工作。如果我运行:
source mwe.sh
代码仍然按预期运行并执行测试。太棒了!
如果我运行
bash mwe.sh
启动脚本永久挂起。我已将此问题追溯到启动脚本中的几个不同位置,这些位置都可能独立失败。
所以,我的问题是:在交互式 shell 环境中启动命令和在脚本中启动命令有什么区别?特别是,可以缩小到source file.sh
和之间的区别的差异是什么sh file.sh
?
特别是,在我尝试运行的 cron 作业上下文中,是否有任何方法可以执行与source
在交互式命令行上执行文件等效的操作?
编辑:最后一条信息 - 我认为这种故障只发生在 mac 上,而不是在 linux 上,但我不知道这是否提供了任何有用的信息,因为这两个平台的底层代码有些不同。
答案1
source foo.sh
运行脚本这当前 Bash shell,非常类似于简单地source foo.sh
用文件内容替换命令foo.sh
。sh foo.sh
在上下文中运行脚本新sh
壳,在许多操作系统上它甚至不是 Bash(这可能是脚本不起作用的一个原因)。
答案2
在交互式 shell 环境中启动命令与从脚本内部启动命令之间的区别在于环境。
source foo.sh
要了解和之间的区别,sh foo.sh
您必须知道无论哪种方式都会发生什么:
source foo.sh
:
source
是 bash 独有的内置命令。这意味着当您调用 时source
,没有可执行文件,例如/bin/source
或 so。bash
它本身会解析命令行界面,以获取所谓的shell 内置命令。该source
命令是的内置函数bash
...
从文件名读取并执行命令在当前 shell 环境中并返回从 filename 执行的最后一个命令的退出状态。
因此,这就像您逐行复制和粘贴文件foo.sh
并Enter在每行之后按下 一样。当 nobash
运行时,也没有source
命令。
sh foo.sh
:
/bin/sh
这将使用一个参数调用默认 shell ,命令文件。这是包含命令的文件的路径名。该文件不必是可执行文件。也没有必要哈希邦行。因此,新的shell 启动 ( /bin/sh
),在新的 shell 中,文件中的命令逐行执行。但是,现在环境是不是当前的 shell 环境. 它是 shell 生成的环境。