bash - 从外部覆盖命令
问题描述
我有几个带有文件 stamp1.txt 和 stamp0.txt 的目录,我想要覆盖 cat 命令。例如,我需要它来禁止将“stamp1”文件归档到库中。
所以我写了一个叫做“realname”的小过滤程序和bash脚本来覆盖原来的cat命令。
function cat() {
local e=""
for s in $@
do
if realname $s; then
e=$e" "$s;
fi
done
command cat $e;
}
所以命令:
cat dir1/stamp1.txt dir2/stamp0.txt
将转换为
cat dir2/stamp0.txt
这个例子工作得很好
ar cruv some_lib.a `cat dir1/stamp1.txt dir2/stamp0.txt`
但是当我运行一些makefile来构建一些软件时——在这个过程中使用了原始的cat,也没有被覆盖。
如何在不更改 makefile 的情况下覆盖 cat 或任何其他命令以使其适用于 make 过程(makefile 是 3rdparty 软件,我不想每次需要升级时都对其进行修补)?
解决方案
简短版本:您不能(而且您可能不希望这样做)。
更长的版本:您已经定义了一个 shell 函数。实际上,您甚至可以将该 shell 函数导出到环境中export -f cat
。但是,除非 Makefile 说bash -c cat ...
的不仅仅是cat
(或其他相同效果的引用),否则它不会给你你想要的行为。
如果你真的坚持......并且 Makefile 没有使用硬编码路径(例如/bin/cat
)。你可以写你自己的猫,把它放在某个地方,让这个位置在其他可能的命中之前cat
(只是把它放在前面)。
还有一些机会(查看 make 文件)它使用变量(例如CAT
)来知道要调用什么,因此如果是这种情况,您可以提供自己的定义。
无论如何。我不鼓励您使用此类解决方法,因为这样做会混淆机器的实际行为。这里声明了一些东西......环境中的其他东西赋予了它不同的含义。这是一个非常常见的错误来源,最终导致不明显(更难解决)的错误。
功能位的示例/说明。我有一个 Makefile:
all:
@echo foo
并定义和导出一个“覆盖”回声的功能。echo() { /bin/echo "$@" bar; } ; export -f echo
. 我运行 make 并得到:
$ make
foo
因为 make 只是寻找echo
in PATH
(尝试exec
并一旦找到它,它就会运行它)。如果我将其更改为中间有 bash 步骤,则导出的函数将启动,但是......这是在 make 中使用命令的常用方法,您必须编辑您不想要的 Makefile:
all:
@bash -c 'echo foo'
这将为您带来您想要的结果:
$ make
foo bar
我提到的另一个选项。我已将该函数的行为放入脚本/tmp/bin/echo
阅读中:
#!/bin/bash
/bin/echo "$@" bar
我已经修改了PATH
env var export PATH=/tmp/bin:$PATH
。现在即使使用 Makefile 的第一种形式:
all:
@echo foo
我得到:
$ make
foo bar
但是,如果给出的 Makefile/bin/echo
相反,我就没有这样的运气了。您仍然可以更改二进制文件...或通过强制共享库预加载来更改其行为...但听起来很极端,并充分揭示了为什么这确实可能不是采用它的最佳方向。
推荐阅读
- php - 如何返回多维数组中特定列包含非空值的数组?
- sql - SQL - 批量插入不重复
- javascript - 我可以检测我的 PWA 是作为应用程序启动还是作为网站访问?
- java - 设置控制器时出现异常
- swift - didReceiveMessage 接收并响应消息但未调用方法
- numpy - 为什么以大于 9 的幂提高 numpy 数组会返回错误结果?
- python - Pandas 分配给链式 .loc 视图(不是副本)和 SettingWithCopyWarning
- reactjs - 将json输出分配给reactjs中的javascript变量
- javascript - 以角度计算/获取隐藏的div宽度
- android - 如何模糊像 WhatsApp 一样展开的折叠工具栏图像?