Force tcsh to check whether command exist in the path before attempting to execute it

I’ve noticed that tcsh, regardless of whether "-f" flag is passed on the shebang line, will iterate through $PATH, and try to execute the command from that path until the command is found. Whereas bash first checks whether the command is present in that location.

This tcsh behaviour leads to a lot of failed entries in the audit logs as our audit has been configured to capture execve system calls. For instance when sleep is called from within a tcsh script, one of the failed audit entries shows it tried to run sleep with absolute path: "/usr/local/bin/sleep".

type=SYSCALL msg=audit(1710330471.326:37838): arch=c000003e syscall=59 success=no exit=-2 a0=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="" exe="/usr/bin/tcsh" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="non_sys_execs"

type=CWD msg=audit(1710330471.326:37838): cwd="/tmp"

type=PATH msg=audit(1710330471.326:37838): item=0 name="/usr/local/bin/sleep" objtype=UNKNOWN cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0

type=PROCTITLE msg=audit(1710330471.326:37838): proctitle=2F62696E2F637368002E2F6373685F746573742E7368

Strace shows bash stats first, before attempting an access:

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

The order in which it traverses the paths matches the order the paths are defined in $PATH.

Unfortunately changing the order around on all our servers will not be possible, also it’s unclear what the implications would be of putting /bin/ ahead of /usr/local/bin etc. Whilst, I doubt it, but just in case, is there perhaps some runtime or install configuration to force tcsh to stat first just like bash does?

Is there anything else that could be done at all to avoid these failures (apart from amending scripts to use the full path or filtering out these execve calls from audit capture)?

Asked By: Maikol


The trick was to force tcsh to enable command hashing, which as it turns out get’s disabled if it’s called with "-f" flag, which was the case in my problematic scripts.

At the top of the script I just added:

rehash 4096

See the answer in: Enabling command hashing in tcsh, for a very detailed description of command hashing in tcsh.

Answered By: Maikol
Categories: Answers Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.