Repository: xonsh/xonsh

Issue:
Xonsh appimage "xpip" fails due to built in sudo and appimage mount options
<!--- Provide a general summary of the issue in the Title above -->
<!--- If you have a question along the lines of "How do I do this Bash command in xonsh"
please first look over the Bash to Xonsh translation guide: https://xon.sh/bash_to_xsh.html
If you don't find an answer there, please do open an issue! -->

## xonfig


```
blank, stock, unmodified
```

</details>

## Expected Behavior
<!--- Tell us what should happen -->
I run `xpip` successfully

## Current Behavior
<!--- Tell us what happens instead of the expected behavior -->
<!--- If part of your bug report is a traceback, please first enter debug mode before triggering the error
To enter debug mode, set the environment variable `XONSH_DEBUG=1` _before_ starting `xonsh`.
On Linux and OSX, an easy way to to do this is to run `env XONSH_DEBUG=1 xonsh` -->

I start `Xonsh` as my main user from the .AppImage and attempt to call xpip:

```
solidhal@solidhal-dev ~ $ xonsh

                                                                        Welcome to the xonsh shell (0.9.24.dev89)

                                                                                ~ No frills in the shell ~

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
xonfig tutorial    ->    Launch the tutorial in the browser
xonfig web         ->    Run the configuration tool in the browser and claim your shell
(Note: Run the configuration tool or create a ~/.xonshrc file to suppress the welcome screen)

solidhal@solidhal-dev ~ $ xpip
[sudo] password for solidhal:
sudo: /tmp/.mount_xonshoqrLJa/opt/python3.8/bin/../../../usr/bin/python3.8: command not found
```
Versus when I start the same `Xonsh` AppImage with sudo, making me the root user:

```
solidhal@solidhal-dev:~/Downloads$ sudo ./xonsh

                                                                        Welcome to the xonsh shell (0.9.24.dev89)

                                                                              ~ Conches for the xonsh god! ~

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
xonfig tutorial    ->    Launch the tutorial in the browser
xonfig web         ->    Run the configuration tool in the browser and claim your shell
(Note: Run the configuration tool or create a ~/.xonshrc file to suppress the welcome screen)

root@solidhal-dev /home/solidhal/Downloads # xpip

Usage:
  /tmp/.mount_xonshLkQGyf/usr/bin/python3.8 -m pip <command> [options]
... rest of help/usage cut ...
```

So, why does it work when I start `Xonsh` with sudo vs just regularly? Two reasons:
1) the `sudo` in xpip is baked in, which forces us to root permissions in both cases
2) The `Xonsh` Appimages mounts are only accessible to the user which mounted them due to the `user_id` and `group_id` settings

This results in even the root user getting no permissions to even read the mounted appimage. We can show this with a simple test `ls`:
```
solidhal@solidhal-dev ~ $ sudo ls /tmp/.mount_xonshoqrLJa/opt/python3.8/
ls: cannot access '/tmp/.mount_xonshoqrLJa/opt/python3.8/': Permission denied
solidhal@solidhal-dev ~ $ ls /tmp/.mount_xonshoqrLJa/opt/python3.8/
bin  include  lib
```

and if we look at the mount points as a normal user:
```
d?????????  ? ?        ?           ?            ? .mount_xonshLkQGyf
drwxr-xr-x  4 root     root        0 Oct 16 18:16 .mount_xonshoqrLJa
```
and then with sudo 
```
drwxr-xr-x  4 root     root        0 Oct 16 18:16 .mount_xonshLkQGyf
d?????????  ? ?        ?           ?            ? .mount_xonshoqrLJa
```
the permissions look correct, but only to the user that mounted them

finally, we can see the culprit in `mount`
```
/home/solidhal/Downloads/xonsh on /tmp/.mount_xonshoqrLJa type fuse.xonsh (ro,nosuid,nodev,relatime,user_id=1000,group_id=1000)
/home/solidhal/Downloads/xonsh on /tmp/.mount_xonshLkQGyf type fuse.xonsh (ro,nosuid,nodev,relatime,user_id=0,group_id=0)
```

</details>

## Steps to Reproduce
<!--- Please try to write out a minimal reproducible snippet to trigger the bug, it will help us fix it! -->

download appimage, give executable permissions, run `./xonsh`, run `xpip`, cry in weird permissions issues

## Workaround

Call the Xonsh pip directly instead of using the alias that automatically adds sudo:
```
solidhal@solidhal-dev ~/Downloads $ which xpip
sudo /tmp/.mount_xonsheTOTsO/usr/bin/python3.8 -m pip
solidhal@solidhal-dev ~/Downloads $ /tmp/.mount_xonsheTOTsO/usr/bin/python3.8 -m pip

Usage:
  /tmp/.mount_xonsheTOTsO/usr/bin/python3.8 -m pip <command> [options]
```


## For community
⬇️  **Please click the 👍 reaction instead of leaving a `+1` or 👍  comment**



Discussion:

Resolving patch:
diff --git a/xonsh/aliases.py b/xonsh/aliases.py
--- a/xonsh/aliases.py
+++ b/xonsh/aliases.py
@@ -22,6 +22,7 @@
     ON_OPENBSD,
     ON_DRAGONFLY,
     ON_POSIX,
+    IN_APPIMAGE,
 )
 from xonsh.tools import (
     XonshError,
@@ -765,7 +766,7 @@ def detect_xpip_alias():
 
     basecmd = [sys.executable, "-m", "pip"]
     try:
-        if ON_WINDOWS:
+        if ON_WINDOWS or IN_APPIMAGE:
             # XXX: Does windows have an installation mode that requires UAC?
             return basecmd
         elif not os.access(os.path.dirname(sys.executable), os.W_OK):
diff --git a/xonsh/platform.py b/xonsh/platform.py
--- a/xonsh/platform.py
+++ b/xonsh/platform.py
@@ -65,6 +65,12 @@ def distro():
     lambda: (sys.platform.startswith("openbsd")), globals(), "ON_OPENBSD"
 )
 """``True`` if on a OpenBSD operating system, else ``False``."""
+IN_APPIMAGE = LazyBool(
+    lambda: ("APPIMAGE" in os.environ and "APPDIR" in os.environ),
+    globals(),
+    "IN_APPIMAGE",
+)
+"""``True`` if in AppImage, else ``False``."""
 
 
 @lazybool


Test patch: