Skip to content

$PATH is searched on every execution, even for tracked aliases #992

@aweeraman

Description

@aweeraman

When a command runs a second time, ksh re-walks the $PATH in full even though the previous lookup is already cached as a tracked alias. This has no functional impact, but would be a good performance improvement if the caching is honored.

Comparative reproducer:

d=$(mktemp -d)
for s in bash mksh zsh ksh93; do
  echo "===== $s ====="
  PATH="$d:/usr/bin:/bin" strace -f -e trace=execve,newfstatat "$s" -c '
  echo "-- FIRST RUN --" >&2
  ls >/dev/null 2>&1
  echo "-- SECOND RUN --" >&2
  ls >/dev/null 2>&1' 2>&1 | grep -E "^-- (FIRST|SECOND)|\"[^\"]*/ls\""
  echo
done
rmdir "$d"

Output (On 1.0.10/Debian):

===== bash =====
-- FIRST RUN --
newfstatat(AT_FDCWD, "/tmp/tmp.NXIp9QJ7Ls/ls", 0xffffef373208, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, 0) = 0
[pid 161640] execve("/usr/bin/ls", ["ls"], 0xaaaad6fe2430 /* 79 vars */) = 0
-- SECOND RUN --
[pid 161641] execve("/usr/bin/ls", ["ls"], 0xaaaad6fe2430 /* 79 vars */) = 0

===== mksh =====
-- FIRST RUN --
newfstatat(AT_FDCWD, "/tmp/tmp.NXIp9QJ7Ls/ls", 0xffffffb844d8, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, 0) = 0
[pid 161653] execve("/usr/bin/ls", ["ls"], 0xaaaadf2d97c8 /* 80 vars */) = 0
-- SECOND RUN --
[pid 161681] execve("/usr/bin/ls", ["ls"], 0xaaaadf2d9cf8 /* 80 vars */) = 0

===== zsh =====
-- FIRST RUN --
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, 0) = 0
[pid 161686] execve("/usr/bin/ls", ["ls"], 0xaaaacff7f000 /* 82 vars */) = 0
-- SECOND RUN --
execve("/usr/bin/ls", ["ls"], 0xaaaacff7f000 /* 82 vars */) = 0

===== ksh93 =====
-- FIRST RUN --
newfstatat(AT_FDCWD, "/tmp/tmp.NXIp9QJ7Ls/ls", 0xffffdedd5ca8, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, AT_SYMLINK_NOFOLLOW) = 0
[pid 161694] execve("/usr/bin/ls", ["ls"], 0xaaab0b5690e8 /* 81 vars */) = 0
-- SECOND RUN --
newfstatat(AT_FDCWD, "/tmp/tmp.NXIp9QJ7Ls/ls", 0xffffdedd5ca8, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/bin/ls", {st_mode=S_IFREG|0755, st_size=199680, ...}, AT_SYMLINK_NOFOLLOW) = 0
execve("/tmp/tmp.NXIp9QJ7Ls/ls", ["ls"], 0xaaab0b5690d8 /* 81 vars */) = -1 ENOENT (No such file or directory)
execve("/usr/bin/ls", ["ls"], 0xaaab0b5690d8 /* 81 vars */) = 0

Also, there appears to be a redundant execve on the first PATH entry in the second run, even though the binary is not present at that location.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is not workingenhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions