Score:1

Permission denied error for binary in certain circumstances

gb flag

I've got a binary on my machine that's ended up in a really odd state, and I can't tell what specifically is up with it. I've exhausted all the diagnostics I know about (including some new ones I found from googling), so I figured I would ask for suggestions here and hopefully learn something!

The binary in question is flutter (though I don't think that's particularly relevant). It lives on my machine at /home/alyssa/.local/bin/flutter/bin/flutter. My $PATH contains ~/.local/bin/flutter/bin - this is injected via .bashrc.

The Symptoms

  • From a terminal, I can run flutter --version without error.
  • which flutter returns no output and exit code 1.
  • type flutter returns flutter is /home/alyssa/.local/bin/flutter/bin/flutter as expected.
  • whereis flutter returns flutter: /home/alyssa/.local/bin/flutter
  • However, certain sub-processes fail to run flutter commands with a permissions error. The simplest one to replicate is via python3's subprocess:
$ python3 -c "import subprocess; subprocess.run(['flutter', '--version'])"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.6/subprocess.py", line 423, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.6/subprocess.py", line 729, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1364, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
PermissionError: [Errno 13] Permission denied: 'flutter'

Things I've looked at

  • I've run the python3 recipe for several other binaries and it works as expected (prints the version with no error).
  • I've run env, whoami and whereis via the same python3 recipe to compare to my raw terminal, and the outputs are all the same. So I believe that the subprocess that's kicked off is running as the same user with the same $PATH, and therefore shouldn't have a problem.
  • Just in case, I did a find . -name 'flutter' -type f - this didn't find any other binaries knocking around on my filesystem.
  • namei -olm ~/.local/bin/flutter/bin/flutter suggests the permissions on all the relevant files/folders are fine:
$ namei -olm ~/.local/bin/flutter/bin/flutter
f: /home/alyssa/.local/bin/flutter/bin/flutter
drwxr-xr-x root   root   /
drwxr-xr-x root   root   home
drwxr-xr-x alyssa alyssa alyssa
drwxr-xr-x alyssa alyssa .local
drwxr-xr-x alyssa alyssa bin
drwxr-xr-x alyssa alyssa flutter
drwxr-xr-x alyssa alyssa bin
-rwxr-xr-x alyssa alyssa flutter
  • One thing that I do believe is different is that the subprocess isn't running using /bin/bash. I believe this because I am unable to run type flutter using that recipe - it can't find type because that's a bash built-in. But that doesn't give me the root cause - there's got to be something wrong with the file or my $PATH or something that's the real issue.

Versions

  • OS: Ubuntu 18.04.6 LTS
  • Bash: GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
  • Python: 3.6.9

Any suggestions for other diagnostics / things I could try would be much appreciated!

hr flag
The fact that `which flutter` has exit status 1 suggests that `/home/alyssa/.local/bin/flutter/bin/flutter` is not actually in the shell's current PATH - does `type flutter` say anything about it being hashed?
Alyssa avatar
gb flag
Nope, nothing about it being hashed. I've verified that the directory is on the path (via `echo $PATH`) in both my terminal and within the python subprocess (via `python3 -c "import subprocess; subprocess.run(['echo', '$PATH'])"`).
Alyssa avatar
gb flag
Also, if it not being on the path were the problem, I'd expect the python error to be `No such file or directory` rather than `Permission denied` (this is what happens if I run the same command but deliberately pick a binary that doesn't exist)
hr flag
Just fyi, in `python3 -c "import subprocess; subprocess.run(['echo', '$PATH'])")` the outer double quotes permit `$PATH` to be expanded by the interactive shell before the `-c` argument is passed to python3 (use `set -x` in the shell to confirm)
Alyssa avatar
gb flag
Ahh, yes that's true - good catch! I don't think it changes things, however - `python3 -c "import subprocess; subprocess.run(['env'])")` outputs the same `PATH` value amongst everything else
hr flag
So far as diagnostics go, have you tried `subprocess.run(['/home/alyssa/.local/bin/flutter/bin/flutter', '--version'])"` ? How about `subprocess.run(['which', 'flutter'])"` ? Also, does `type -a flutter` show any additional hits?
Alyssa avatar
gb flag
`python3 -c "import subprocess; subprocess.run(['/home/alyssa/.local/bin/flutter/bin/flutter', '--version'])"` works, prints the version info. `python3 -c "import subprocess; subprocess.run(['which', 'flutter'])"` returns no output. `type -a flutter` returns the same as without `-a`: `flutter is /home/alyssa/.local/bin/flutter/bin/flutter`. The first command suggests that the permission denied is maybe happening at the point where the subprocess is trying to determine where flutter lives, as opposed to accessing the binary itself?
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.