Skip to content

pipx run produces PermissionError when combined with bash process substitution #1292

@Bobronium

Description

@Bobronium

Describe the bug
Attempting to run a Python script through bash process substitution with pipx results in a PermissionError. The same script runs without issues when executed directly with Python. This indicates a potential issue with how pipx handles file descriptors or temporary files created by process substitution.

How to reproduce
Install pipx==1.4.3

$ pip install pipx-in-pipx
$ pipx inject pipx pipx==1.4.3
$ pipx run <(echo 'print("Hello World!")')
Traceback (most recent call last):
  File "/Users/bobronium/.local/bin/pipx", line 8, in <module>
    sys.exit(cli())
  File "/Users/bobronium/.local/pipx/venvs/pipx/lib/python3.10/site-packages/pipx/main.py", line 921, in cli
    return run_pipx_command(parsed_pipx_args)
  File "/Users/bobronium/.local/pipx/venvs/pipx/lib/python3.10/site-packages/pipx/main.py", line 204, in run_pipx_command
    commands.run(
  File "/Users/bobronium/.local/pipx/venvs/pipx/lib/python3.10/site-packages/pipx/commands/run.py", line 205, in run
    run_package(
  File "/Users/bobronium/.local/pipx/venvs/pipx/lib/python3.10/site-packages/pipx/commands/run.py", line 141, in run_package
    run_pypackage_bin(pypackage_bin_path, app_args)
  File "/Users/bobronium/.local/pipx/venvs/pipx/lib/python3.10/site-packages/pipx/util.py", line 102, in run_pypackage_bin
    exec_app(
  File "/Users/bobronium/.local/pipx/venvs/pipx/lib/python3.10/site-packages/pipx/util.py", line 385, in exec_app
    os.execvpe(str(cmd[0]), [str(x) for x in cmd], env)
  File "/Users/bobronium/.pyenv/versions/3.10.1/lib/python3.10/os.py", line 583, in execvpe
    _execvpe(file, args, env)
  File "/Users/bobronium/.pyenv/versions/3.10.1/lib/python3.10/os.py", line 596, in _execvpe
    exec_func(file, *argrest)
PermissionError: [Errno 13] Permission denied: '/dev/fd/11'

Expected behavior

Pipx should execute the script provided through process substitution, printing "Hello World!" to the console, similar to the direct Python execution:

$ python <(echo 'print("Hello World!")')
Hello World!

Context
Supporting this behaviour would allow to run scripts in-place using a clipboard:

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

import requests
from rich.pretty import pprint

resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
$ pipx run <(pbpaste)

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting responseAwaiting re-engagement by contributorenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions