0

I have two files, a.py:

import os, subprocess

os.chroot(".")
subprocess.run(["./b.sh"])

and b.sh:

#!/usr/bin/env bash
echo whateva

in an otherwise empty directory. b.sh has executable permission. Why does python3 a.py fail with:

Traceback (most recent call last):
  File "/yadda/yadda/a.py", line 5, in <module>
  File "/usr/lib/python3.11/subprocess.py", line 548, in run
  File "/usr/lib/python3.11/subprocess.py", line 1024, in __init__
  File "/usr/lib/python3.11/subprocess.py", line 1917, in _execute_child
FileNotFoundError: [Errno 2] No such file or directory: './b.sh'

This is running as root, uname -a is Linux me 6.4.1-arch2-1 #1 SMP PREEMPT_DYNAMIC Tue, 04 Jul 2023 08:39:40 +0000 x86_64 GNU/Linux (I get the same behavior in a Ubuntu Docker container). What am I not understanding? Do I need a shell binary in the chroot?

Thank you!

5
  • os.chroot(".") is changing the root directory to the current directory. So after that, Python/subprocess is looking for b.sh in the new root folder, not the original path. Try using an absolute path for "b.sh" Commented Jul 21, 2023 at 21:06
  • 2
    Does /usr/bin/env exist in the chroot? What about bash? If you're running things in a chroot you need to include all the necessary dependencies (which may also include shared libraries). Commented Jul 21, 2023 at 21:08
  • @Moid still gives me the same error. Commented Jul 21, 2023 at 21:11
  • @larsks that makes sense-- in the context of my project, a.py is running in a directory with cross-compiled binaries and libraries for bash, binutils, gcc, coreutils a lot of standard stuff. Do you have any idea of how I could figure out what library or binary Python is expecting but missing? Or what component is not working as expected? Right now I'm looking at github.com/python/cpython/blob/main/Modules/_posixsubprocess.c, which I guess is a C module within subprocess.py in python3.10 Commented Jul 21, 2023 at 21:14
  • 1
    What is inside the chroot? Do dynamic libraries needed to run env and bash and echo are inside the chroot? Do I need a shell binary in the chroot? Yes, you definitely need many files in the chroot to run shell including the shell binary. Commented Jul 21, 2023 at 22:37

1 Answer 1

1

You are missing the env executable, or it exist in a different path under your chrooted tree (i.e. not under /usr/env/). This can be easily demonstrated even without chroot. Let's remove the chroot, and change b.sh as follows:

#!/usr/bin/no_such_file bash
echo whateva

Unix (in my case MacOS, but also Linux) will fail executing no_such_file like so:

>>> subprocess.run(["./b.sh"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 505, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 951, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 1821, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: './b.sh'
>>>

But simply changing it to a valid executable (back to env) will load just fine:

>>> subprocess.run(["./b.sh"])
whateva
CompletedProcess(args=['./b.sh'], returncode=0)
>>>

If you don't need the shell script to be portable, and as you mentioned in a comment that you already have a bash cross-compiled binary, you can simply use that instead of env, such as #!/bin/bash. The path to the binary must be within the chroot environment, so in case it resides elsewhere - make sure to update it accordingly.

Diving a bit deeper, execve(2)'s man page somewhat explains that ENOENT is set if the executable cannot be found. I've also found this page which might provide a better explanation as to why the failure seems to be related to b.sh existence instead of the binary itself.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.