rmyorston / busybox-w32

WIN32 native port of BusyBox.
https://frippery.org/busybox
Other
693 stars 126 forks source link

`PATH` - implicitly added current directory #368

Closed naksyl closed 1 year ago

naksyl commented 1 year ago

Today some installer put extra semicolon on PATH. This leads to unexpected results.

Cases when current directory is added implicitly:

~ $ cat hello
#!/bin/echo

~ $ PATH='C:/Windows'

~ $ hello
lash: hello: not found

~ $ PATH='C:/Windows;'

~ $ hello
hello

~ $ PATH='C:/Windows;C:/Windows/System32'

~ $ hello
lash: hello: not found

~ $ PATH='C:/Windows;;C:/Windows/System32'

~ $ hello
hello

~ $ PATH=''

~ $ hello
hello
avih commented 1 year ago

Except for empty/unset, this is specified:

PATH This variable shall represent the sequence of path prefixes that certain functions and utilities apply in searching for an executable file known only by a filename. The prefixes shall be separated by a ( ':' ). A zero-length prefix is a legacy feature that indicates the current working directory. It appears as two adjacent characters ( "::" ), as an initial preceding the rest of the list, or as a trailing following the rest of the list.

On linux, all shells which I have access to also interpret leadiing/trailing/double separator in PATH as current directory (bash, dash, ksh93, loksh, mksh, pdksh, bosh, yash, free/net bsd sh, and nore).

However, it's also noted that:

A strictly conforming application shall use an actual pathname (such as .) to represent the current working directory in PATH

Meaning, as far as I can tell, that anyone who sets PATH should specify current dir as . and not empty prefix, but I think PATH should stilll be interpreted including the legacy behavior - as evident in all shells.

As for empty (nul) PATH, most shells still interpret it as current dir.

As for unset PATH, it's interpreted as current dir by bash, dash, busybox ash, freebsh sh, netbsd sh.

So overall, butsybox sh does align with the common shells.

naksyl commented 1 year ago

So overall, butsybox sh does align with the common shells.

I just not expected such behavior but if this aligns with standard so shall be that way. closing

avih commented 1 year ago

For future reference, you can add this to your ~/.profile:

# remove empty elements (current-dir) in PATH
PATH=$(printf %s "${PATH-}" | sed -E -e 's/^;+//' -e 's/;+/;/g' -e 's/;+$//')
[ "$PATH" ] || export "PATH=z:/non/existing/dir"

I believe -E (ERE for +) is non standard (yet), but it works in gnu and busybox sed.

naksyl commented 1 year ago

Thanks for the tip. Just applied.