To whom it may concern,
Bash has long maintained a legacy feature whereby, in interactive
sessions, a literal tilde (`~`) at the start of a `PATH` element (e.g.,
`~/bin`) is expanded to the user’s home directory at the time a command
is executed. While this behavior can sometimes “help” users find
commands in their home directory, it is neither consistent with POSIX
nor universally understood. In particular, when Bash is invoked as
`/bin/sh` or in POSIX mode, tilde expansion in `PATH` is disabled,
leading to potential confusion and hard-to-debug issues.
Given that a number of legacy systems and scripts may depend on this
behavior—and that it can easily be mistaken for a more portable
feature—the behavior should be formally documented. Furthermore,
preserving it (while discouraging its use in new code) spares users from
having to build custom versions of Bash for environments that rely on
this quirk.
Why Document This Behavior?
Clarity and Portability:
Many users naturally assume that writing
```bash
export PATH="~/bin:$PATH"
```
is equivalent to
```bash
export PATH="$HOME/bin:$PATH"
```
in all contexts. However, because Bash in interactive mode expands
the tilde at command execution time while POSIX mode (or `/bin/sh`
invocations) does not, scripts may work as expected in one context and
fail in another. Documenting this inconsistency would alert developers
to the subtle differences, promoting best practices in portable
scripting.
Preventing Inadvertent Errors:
As legacy systems evolve and environments become more heterogeneous,
the likelihood of encountering the non-expanded tilde in non-interactive
contexts increases. Clear documentation would help prevent unexpected
command-not-found errors when scripts (or applications invoking
`system(3)`) rely on the interactive shell’s behavior.
Historical Consistency and Backward Compatibility:
The behavior has been part of Bash since its early days. Removing or
modifying it without proper notice would break existing scripts that,
knowingly or not, depend on tilde expansion in the `PATH`. By
documenting the behavior—and marking it as legacy—we provide a clear
notice that while this feature is maintained for backward compatibility,
its use in new scripts is discouraged.
Supporting Legacy Systems:
Numerous systems in the field, including embedded devices and
enterprise environments, might still be running scripts that use this
behavior. Maintaining and documenting it means that system
administrators and developers do not have to invest in building or
patching custom Bash versions to preserve compatibility.
Proposed Additions to the Bash Reference Manual
To address the above points, the following text (or similar language) is
proposed for inclusion in the Bash Reference Manual:
Tilde Expansion in the `PATH` Variable
Description:
In interactive Bash sessions, any element of the `PATH` variable that
begins with a tilde (e.g., `~` or `~/bin`) is automatically expanded to
the corresponding home directory of the current user at the time a
command is executed. For example, if the user's home directory is
`/home/alice`, then an entry `~/bin` in the `PATH` is interpreted as
`/home/alice/bin` during command lookup.
Behavior Details:
Interactive Bash:
When Bash is invoked in its default interactive mode, the tilde
expansion is performed as if the entry were unquoted. This expansion
occurs at the time of command execution and allows commands located in
the user’s home directory (e.g., in `/home/alice/bin`) to be found even
if the `PATH` contains a literal tilde.
Bash in POSIX Mode or as `/bin/sh`:
When Bash is invoked as `/bin/sh` or with POSIX mode enabled (see
[Bash POSIX
Mode](https://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html)),
tilde expansion in `PATH` is not performed. In these contexts, a literal
tilde remains unexpanded, and any command lookup that relies on such
expansion will fail.
Recommendations for Script Authors:
For portable scripts and applications, it is recommended to explicitly
use the `$HOME` variable when specifying paths:
```bash
export PATH="$HOME/bin:$PATH"
```
This practice ensures consistent behavior regardless of the shell’s
mode of operation.
Legacy Support Notice:
This tilde expansion behavior in `PATH` is maintained for backward
compatibility with legacy systems. Although its reliance in new scripts
is discouraged, it remains documented and supported to avoid forcing
users of older systems to build custom versions of Bash. Future releases
may mark this feature as obsolescent, and users are encouraged to
transition to explicit variable expansions to meet modern portability
standards.
Supporting the Case for Preservation
Technical and Standards Considerations
POSIX Standards:
The IEEE Std 1003.1-2017 (commonly known as POSIX.1-2017) does not
mandate tilde expansion for `PATH` elements. Bash’s behavior in POSIX
mode is therefore in line with the standard. However, the interactive
expansion is a historical extension that, while noncompliant with POSIX,
remains useful in certain contexts.
Backward Compatibility:
Many existing scripts in use across various environments—especially
those that originated before the widespread adoption of POSIX-compliant
shells—depend on the interactive expansion of `~` in `PATH`. Maintaining
this behavior while clearly documenting it allows both legacy systems
and new projects to coexist without forcing unnecessary modifications.
Practical Benefits
Avoiding Custom Builds:
Users and system administrators working in environments with legacy
systems often prefer to use the system-provided Bash version. By
documenting and preserving this behavior, there is no need for custom
compilations or patches solely to retain expected functionality.
Ease of Migration:
Clear documentation enables developers to quickly understand the
potential pitfalls when migrating scripts between different shell
invocation modes. With explicit warnings and recommendations, developers
can plan refactoring efforts to replace `~` with `$HOME` where
portability is required.
In closing
Documenting the tilde expansion behavior in `PATH` is critical for both
clarity and long-term compatibility. It ensures that users and
developers are aware of the discrepancy between interactive and POSIX
modes, thereby preventing subtle bugs and easing maintenance burdens.
Moreover, preserving this legacy functionality—while clearly warning
against its use in new code—strikes a balance between honoring
historical behavior and promoting best practices in modern scripting.
By including a dedicated section in the Bash Reference Manual that
explains this behavior and its limitations, the maintainers of Bash can
offer better guidance to users. This change would support legacy systems
in continued operation while encouraging the use of portable, explicit
path expansions in new developments.
References:
Bash POSIX Mode Documentation:
[Bash POSIX
Mode](https://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html)
IEEE Std 1003.1-2017 (POSIX.1-2017):
This standard outlines the behavior expected of POSIX-compliant
shells, which does not include tilde expansion in `PATH` elements.
Historical Discussions on comp.unix.shell:
Various discussions have highlighted the confusion arising from this
undocumented behavior, reinforcing the need for clear documentation in
the official manual.
This proposal aims to foster a better understanding of Bash’s behavior
among both legacy users and modern script writers, ensuring that the
benefits of backward compatibility do not come at the cost of clarity
and portability.