返回

tcsh 命令执行检查:如何解决 tcsh 特有的问题

Linux

tcsh 命令执行检查

作为一名程序员,经常需要解决棘手的问题。最近,我遇到了一个 tcsh 特有的问题,迫使我在命令执行前检查该命令是否存在于路径中。

问题

tcsh 会迭代 $PATH,并尝试从该路径执行命令,直到找到该命令为止,即使 shebang 行中传递了 -f 标志。这会导致大量失败的审计条目,因为我的审计配置为捕获 execve 系统调用。

以从 tcsh 脚本中调用 sleep 为例,失败的审计条目显示它尝试使用绝对路径 /usr/local/bin/sleep 运行 sleep

type=SYSCALL msg=audit(1710330471.326:37838): arch=c000003e syscall=59 success=no exit=-2a0=2601590 a1=261e010 a2=261d110 a3=7ffdc4a409e0 items=1 ppid=8930 pid=8938 auid=1011478343 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=863 comm="csh_test.sh" exe="/usr/bin/tcsh" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="non_sys_execs"`

解决方法

要避免这些失败,有几种选择:

  1. 修改脚本使用完整路径: 通过在命令前添加完整路径,可以强制 tcsh 直接执行该命令。

  2. 从审计捕获中过滤掉 execve 调用: 如果修改脚本不可行,则可以从审计捕获中过滤掉这些 execve 调用。

  3. 配置运行时或安装配置: 在 tcsh 中配置运行时或安装配置,使其在执行命令前检查命令是否存在于路径中。不过,目前尚不清楚此选项是否存在。

Bash 的行为

与 tcsh 相比,bash 在统计命令是否存在于该位置之前,会先检查 $PATH。这消除了不必要的尝试,从而提高了性能并减少了失败审计条目。

stat("/usr/local/bin/sleep", 0x7ffdd8de5630) = -1 ENOENT (No such file or directory)
stat("/usr/local/sbin/sleep", 0x7ffdd8de5630) = -1 ENOENT (No such file or directory)
stat("/sbin/sleep", 0x7ffdd8de5630)     = -1 ENOENT (No such file or directory)
stat("/bin/sleep", {st_mode=S_IFREG|0755, st_size=33128, ...}) = 0

结论

为了解决 tcsh 命令执行检查问题,可以修改脚本使用完整路径、从审计捕获中过滤掉 execve 调用,或者探索配置运行时或安装配置的可能性。了解 tcsh 与 bash 在命令执行方面的不同行为对于解决此类问题至关重要。

常见问题解答

1. 为什么强制 tcsh 检查命令存在性很重要?

避免不必要的尝试,提高性能并减少失败审计条目。

2. 如何从审计捕获中过滤掉 execve 调用?

这取决于使用的审计工具,但通常涉及创建规则或策略来忽略这些调用。

3. 配置运行时或安装配置是否存在风险?

更改运行时或安装配置可能会对其他功能产生意外后果,因此在实施前应仔细考虑和测试。

4. tcsh 在什么情况下比 bash 更合适?

tcsh 在历史上用于某些特定用例,例如 shell 脚本编程。但是,bash 通常更强大、更灵活。

5. 我应该将 tcsh 切换为 bash 吗?

这取决于具体需求和现有代码库。对于大多数用途,bash 是更受欢迎、功能更丰富的选择。