linux - 自定义 bash 命令在终端中有效,但在脚本中无效
问题描述
我有两个脚本:
失败定义.sh:
#!/bin/bash -eu
function fail() {
echo -e "$(error "$@")"
exit 1
}
布拉什:
#!/bin/bash -eu
fail "test"
之后source fail_def.sh
,我可以在终端中使用 fail 命令而不会出现任何问题。但是,当我打电话时bla.sh
,我总是得到line 2: fail: command not found
。
不管我是通过./bla.sh
bashbla.sh
还是 bash调用它./bla.sh
,错误仍然存在。
添加source fail_def.sh
到开头bla.sh
可以解决问题,但我想避免这种情况。
我正在开发一个在 Mac 上运行的 Ubuntu docker 容器,以防万一。
我试图用谷歌搜索该问题并发现了一些类似的问题,但其中大多数似乎与不获取文件或混合不同的 shell 实现有关,这两种情况似乎都不是。
我必须做什么才能让 fail 命令在脚本中工作?
解决方案
预计!
shell 运行带有 she-bang 分隔符的脚本总是作为一个单独的进程运行,因此在不同的 shell 命名空间上。运行脚本的新 shell 没有 source'd 函数。
要调试此类信息,请在脚本上添加一行echo $BASHPID
打印当前 bash 进程的进程 ID,并生成测试结果bla.sh
#!/bin/bash -eu
$ echo $BASHPID
11700
$ bash bla.sh
6788
fail.sh: line 3: fail: command not found
它们脚本您在单独的进程上运行,其中导入的函数不共享。其中一种方法是您自己对第二个脚本进行错误处理,并通过 source-ing 第二个脚本。在第二个脚本
$ cat fail.sh
echo $BASHPID
set -e
fail "test"
set +e
现在运行它
$ source fail.sh
11700
11700
bash: error: command not found
这很明显,因为error
不是可用的内置外壳。在上述情况下观察进程 ID 相同。
推荐阅读
- xcode - 在 XCode 中找不到 Mapbox 框架错误
- c++ - 如何将 ocaml 代码编译为本机以供 C++ 使用
- assembly - 使用 AVR 反转字节中的位
- postgresql - 如何配置 PostgreSQL 以接受除 postgres / admin 之外的所有传入连接
- javascript - 在新页面中打开媒体而不是下载(MediaRecorder-sample)
- sql - 如何从表 B 值更新表 A 值?
- android - 找不到符号 CountryFragmentBindingImpl
- r - 有没有更快的方法来合并数据帧和循环组合?
- java - Java PreparedStatement 保留表名大小写
- php - 如何解决未捕获的错误:调用未定义的方法 stdClass::query()