Skip to content

fix: use absolute path for /bin/sh - #317

Open
waltmck wants to merge 1 commit into
wayle-rs:masterfrom
waltmck:shell-absolute-path
Open

fix: use absolute path for /bin/sh#317
waltmck wants to merge 1 commit into
wayle-rs:masterfrom
waltmck:shell-absolute-path

Conversation

@waltmck

@waltmck waltmck commented Jul 3, 2026

Copy link
Copy Markdown

Previously Wayle would resolve sh from the $PATH, which was problematic when in minimal environments (i.e. run from a systemd service). For this reason, the most common---and generally best---practice is to call the standardized FHS absolute path (/bin/sh) directly.

@Dieterbe

Dieterbe commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

I'm not sure hardcoding /bin/sh is a best practice.

Whats your $PATH? It doesn't have /bin in it ?

@waltmck

waltmck commented Jul 4, 2026

Copy link
Copy Markdown
Author

I'm not sure hardcoding /bin/sh is a best practice.

Whats your $PATH? It doesn't have /bin in it ?

I'm on NixOS so $PATH doesn't contain /bin. More importantly, in many environments (like systemd services) $PATH may not be set at all. For this reason it is ubiquitous to hardcode /bin/sh. Examples:

I can easily find hundreds of other examples if you're not convinced. In fact, this pattern is so ubiquitous that sh is the sole file in /bin on NixOS explicitly to support it (despite /bin not being in $PATH). It is so uncommon to call sh from the $PATH that I have never had this issue with any software prior to Wayle, and I cannot even think of any other software that does so.

@Dieterbe

Dieterbe commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

I agree that /bin/sh is ubiquitous, but I'm not sure it's the right solution because of a few reasons:

  1. https://man.archlinux.org/man/systemd.exec.5.en#Environment_Variables_Set_or_Propagated_by_the_Service_Manager suggests that systemd-initiated processes do have a $PATH set, and what the default $PATH is (and indeed, it doesn't include /bin/), but it says distributions can customize the $PATH to make it inline with where the executables are.
  2. I'm not sure if /bin/sh is the most desired variant of sh in each distribution. Sometimes there's multiple versions of sh, a posix compliant or basic one like dash, a more advanced one like bash, etc
  3. I also see things in the wild like /bin/env sh or /usr/bin/env sh

I'm not sure what's the correct answer, but IME, hardcoding assumptions can cause even more trouble, maybe we should explore more how we can leverage the system as it is designed (e.g. by having a correct $PATH set for the system, or maybe by using env).

You suggest that on NixOS, sh is in /bin, but the $PATH does not include /bin, then perhaps that is the root cause? The way this works on Arch is that /bin is symlinked to /bin/sh.

@waltmck

waltmck commented Jul 5, 2026

Copy link
Copy Markdown
Author

I agree that /bin/sh is ubiquitous, but I'm not sure it's the right solution because of a few reasons:

1. https://man.archlinux.org/man/systemd.exec.5.en#Environment_Variables_Set_or_Propagated_by_the_Service_Manager suggests that systemd-initiated processes do have a $PATH set, and what the default $PATH is (and indeed, it doesn't include /bin/), but it says distributions can customize the $PATH to make it inline with where the executables are.

2. I'm not sure if /bin/sh is the most desired variant of `sh` in each distribution.  Sometimes there's multiple versions of `sh`, a posix compliant or basic one like dash, a more advanced one like bash, etc

3. I also see things in the wild like `/bin/env sh` or `/usr/bin/env sh`

I'm not sure what's the correct answer, but IME, hardcoding assumptions can cause even more trouble, maybe we should explore more how we can leverage the system as it is designed (e.g. by having a correct $PATH set for the system, or maybe by using env).

You suggest that on NixOS, sh is in /bin, but the $PATH does not include /bin, then perhaps that is the root cause? The way this works on Arch is that /bin is symlinked to /bin/sh.

Okay, I'll address your concerns in order:

  1. I agree that it is in principle possible for distributions to work around the problem by altering the default behavior of systemd. However, I would respectfully argue that asking all of them to do so only to accommodate one misbehaving application is unreasonable.
  2. By specification, /bin/sh is required to exist. It may be (and almost always is, since nobody uses the original Bourne shell) a symlink to the default POSIX shell. All common POSIX-compatible shells (including dash, bash, and zsh) behave in POSIX compatibility mode when argv[0] is sh in order to support this pattern, and the standard modern Linux way to change the default POSIX-compatible shell is to make /bin/sh point to a different executable. Directly calling /bin/sh is not a hack, as you seem to be implying: it is the idiomatic way to use the configured default POSIX shell interpreter of the system.
  3. This is a mild and mostly harmless antipattern, probably from people who are used to using /usr/bin/env bash or similar. sh is really a special case explicitly covered by the POSIX standard.

Is there any specific concern you have over this change? In my opinion, a pretty compelling reason would be needed to break from the ubiquitous standard across Linux applications (such as any that call to system(3)).

@Dieterbe

Dieterbe commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Directly calling /bin/sh is not a hack, as you seem to be implying

I'm not implying anything. I'm trying to have a productive conversation around what the best solution is, and that includes bringing up questions/considerations and considering alternative approaches. It may be that hardcoding /bin/sh is the best solution. I have no opinion yet.
In my experience in software, i've seen plenty cases where these types of solutions (hardcoding things, especially when it's in a layer "above" a primitive that should either just work, or be configured properly, or when choosing a solution without considering alternative solutions) backfire eventually.

I agree that it is in principle possible for distributions to work around the problem by altering the default behavior of systemd

it seems to me that any distro implementing systemd should also implement what is described in https://man.archlinux.org/man/systemd.exec.5.en#Environment_Variables_Set_or_Propagated_by_the_Service_Manager so that systemd can do its job properly. I consider that proper setup, not a workaround. It's totally possible that i'm missing something, but it seems worth looking into first why on NixOS binaries are "invisible" because they are in directories that are not included in the systemd path. Perhaps it's a bug that needs fixing, or perhaps it's done deliberately for some reason. In which case hardcoding /bin/sh seems indeed like a good choice.

@waltmck

waltmck commented Jul 5, 2026

Copy link
Copy Markdown
Author

I'm not implying anything. I'm trying to have a productive conversation around what the best solution is, and that includes bringing up questions/considerations and considering alternative approaches.

I apologize for my tone, I did not mean to come off as passive-aggressive.

If the goal is to interpret shell scripts with a POSIX compatible shell, my claim is that hardcoding /bin/sh---as required by POSIX and commonly implemented including by the C standard library---is the "least unexpected" way of doing things.

By the way, there is a good reason is that things are done this way instead of by resolving sh from the $PATH: one of the important things /bin/sh does is set environment variables in the standardized POSIX way (namely by reading $ENV and, if a login shell, /etc/profile and ~/.profile). Since these can set $PATH, resolving the shell from the path may cause a circular dependency.

If you strongly disagree with systemd's behavior, I would suggest that you open a PR against systemd changing the default $PATH to include /bin: this would be the correct route toward your suggestion, rather than asking every distro to change the default downstream. However, until such an upstream change is made I think it would be better to follow the standard best practice (i.e. the behavior of the C standard library) so that Wayle will work in all environments.

@Dieterbe

Dieterbe commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

I apologize for my tone, I did not mean to come off as passive-aggressive.

👍 appreciated.

seems just using /bin/sh is indeed fine. We may want to add notices to the documentation that when configuring commands, only posix sh syntax is allowed.

(we still don't agree re: systemd but that has become a separate topic at this point, no need to continue discussing that)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants