Skip to content

shutil.which doesn't work in Docker container #132971

Open
@kentdlee

Description

@kentdlee

Bug report

Bug description:

import shutil

target_fp = shutil.which(head_proc)
if target_fp is not None:
    perm = os.stat(target_fp)
    # This checks the permission bits as an extra check.
    # In a Docker container "which" was not returning
    # executable correctly when headproc was not in the
    # current working directory. This gets the user
    # permission value (rwx) and the remainder of 2
    # division (odd or even). If even, then executable
    # bit is not set and remainder is 0. bool(0) is False.
    # bool(1) is True.
    executable = bool(int(oct(perm.st_mode)[-3]) % 2)
    if not executable:
        target_fp = None
print(target_fp)

This only occurred in a Docker container, but was not a problem outside a container on an Ubuntu Linux box.

When head_proc is the name of a file in the current working directory (i.e. test.py) that is not executable, the shutil.which correctly returns None. However, when the current working directory is not where the file resides (i.e. subdir/test.py or /path/to/test.py) then shutil.which returns the filename and path incorrectly, indicating that it is executable, when it is not.

os.access also returns an incorrect value when mode is os.R_OK | os.X_OK when the current working directory is not where the file exists. If os.access is called on a file in the current working directory in a Docker container, it works as advertised. The code above demonstrates a work-around using os.stat that fixes it for now until this can be fixed.

CPython versions tested on:

3.11

Operating systems tested on:

Other

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsDocumentation in the Doc direasytype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions