pkgx icon indicating copy to clipboard operation
pkgx copied to clipboard

[Linux] Error when trying to install package using 'sudo pkgm install'

Open tclementdev opened this issue 3 months ago • 11 comments

On Fedora Silverblue, I installed pkgx:

> curl https://pkgx.sh | sh
> ls /usr/local/bin
mash pkgm pkgx

Then tried to install a package inside /usr/local/bin using pkgm:

> sudo pkgm install fish
sudo: unable to execute /root/.pkgx/pkgx.sh/v2.7.0/bin/pkgx: Permission denied

It seems like it is trying to install things in the context of the root user, rather than installing things in /usr/local/bin.

Not using sudo works:

> pkgm install fish
> which fish
~/.local/bin/fish

Based on the documentation, I expected sudo pkgm install fish to properly install the package in /usr/local/bin. Am I missing something here?

tclementdev avatar Dec 02 '25 11:12 tclementdev

running with sudo is fraught, since it messes up permissions. see:

https://github.com/pkgxdev/pkgm#intricacies

it should prompt you for a sudo password in order to hard/symlink.

jhheider avatar Dec 03 '25 21:12 jhheider

I'm confused as to what you mean here. The documentation and pkgm --help both encourage to use sudo pkgm install. Is there another way? Not using sudo will not install to /usr/local and instead install to ~/.local.

tclementdev avatar Dec 03 '25 22:12 tclementdev

Ah, I missed the note. Perhaps something has changed, but originally it would install the hard and soft links using audio itself without altering the base directory.

jhheider avatar Dec 03 '25 22:12 jhheider

It worked the last time I tried on macOS. Seems like this is a bug/regression that is specific to Linux/Fedora.

tclementdev avatar Dec 03 '25 22:12 tclementdev

In case that helps, I edited my copy of /root/.pkgx/pkgx.sh/pkgm/v.0.11.1/bin/pkgm and added a log:

function get_pkgx() {
    for (const path of Deno.env.get("PATH")!.split(":")) {
        console.log(path)

And it seems the path list is prefixed with pkgx bin directories including the one leading to the root copy of the pkgx binary.

/root/.pkgx/info-zip.org/unzip/v6.0.0/bin
/root/.pkgx/deno.land/v2.5.6/bin
/root/.pkgx/pkgx.sh/pkgm/v0.11.1/bin
/root/.pkgx/pkgx.sh/v2.7.0/bin

Which causes the following path to be passed to query_pkgx():

/root/.pkgx/pkgx.sh/v2.7.0/bin/pkgx

Then in query_pkgx(), it executes the command with the root pkgx:

cmd: /usr/bin/sudo
args: [ "-u", "thomas", "/root/.pkgx/pkgx.sh/v2.7.0/bin/pkgx", "+fish" ]

And this is where it fails since the local user doesn't have access to that root path:

sudo: unable to execute /root/.pkgx/pkgx.sh/v2.7.0/bin/pkgx: Permission denied

tclementdev avatar Dec 05 '25 10:12 tclementdev

Printing the root paths show the pkgx bin directories are not there:

$ sudo printenv PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/var/lib/snapd/snap/bin

So I assume they are added by the sudo called pkgx instance before it calls onto pkgm?

tclementdev avatar Dec 05 '25 11:12 tclementdev

Ok, I think it comes down to this.

On macOS:

$ sudo printenv HOME
/Users/thomas

On Fedora:

$ sudo printenv HOME
/root

I think on Linux, the code needs to be updated to first look into SUDO_HOME (or similar).

$ sudo printenv SUDO_HOME
/home/thomas

tclementdev avatar Dec 08 '25 22:12 tclementdev

it might be as simple as adding SUDO_HOME around line 291 in pkgm.ts: https://github.com/pkgxdev/pkgm/blob/e3934de9bc129e465bbdfea79e2b1a4e7d24ebe4/pkgm.ts#L287-L295.

but if that's not the solution, one or more of the 5 instances of Path.home() is likely the culprit: https://github.com/pkgxdev/libpkgx/blob/65b6528dbee4075ee036716c31ca8faa7c8e6136/src/utils/Path.ts#L34-L44.

i suspect it'll be the latter. the easiest way to test that is to simply inline that function with SUDO_HOME support, and use it instead for testing.

jhheider avatar Dec 08 '25 22:12 jhheider

I added this near the top of get_pkgx_dir() in config.rs:

if let Ok(path) = env::var("SUDO_HOME") {
    let path = PathBuf::from(path);
    if path.is_absolute() {
        return Ok(path);
    }
}

This seems to fix sudo pkgx <package>, now runs things from my home directory instead of the root user. This is the same behavior as on macOS now.

But pkgm now fails for another reason:

error: Uncaught (in promise) Error: Invalid cross-device link (os error 18): link '/home/thomas/.pkgx/fishshe11.com/v4.2.1/share/doc/fish/CHANGELOG.rst' → '/usr/local/pkgs/Fishshel1.com/v4.2.1/share/doc/Fish/CHANGELOG.rst '
    await Deno.link(sourcePath, targetPath);

Seems like on Fedora my home directory and /usr/local/ live on different filesystems, and pkgm doesn't expect that.

tclementdev avatar Dec 08 '25 22:12 tclementdev

I think we can probably fall back to a regular copy if the hard link fails. Then it finally works, sudo pkgm install fish installed fish in /usr/local/bin/. I'll create pull requests soon, hopefully we can integrate those changes :)

tclementdev avatar Dec 09 '25 07:12 tclementdev

Done ☝

tclementdev avatar Dec 09 '25 20:12 tclementdev

Is the project still maintained?

tclementdev avatar Jan 15 '26 21:01 tclementdev

Yes, we've just been dug in on other stuff at the moment. I'll tag mxcl to take a look at your pr.

jhheider avatar Jan 15 '26 21:01 jhheider

I don't know if this is related or if I should open a new issue. This makes no sense to me:

root# pkgm install pipenv
Error: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }
root# sudo pkgm install pipenv
/usr/local/bin/pip3.9
/usr/local/bin/pip3.8
... (finishes installing)

magnusviri avatar Jan 17 '26 05:01 magnusviri

This is a different thing. It looks like maybe the root user home directory is either missing or isn't writable? I'm not sure.

Typically you'd invoke those tools from a non-root user.

tclementdev avatar Jan 17 '26 08:01 tclementdev