rmyorston / busybox-w32

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

Cannot multiply by `expr` in cmd.exe or pwsh #339

Closed ikasoba closed 1 year ago

ikasoba commented 1 year ago

There seems to be a strange bug that prevents multiplication by expr in shells other than the one provided by busybox-w32 (e.g. cmd.exe or pwsh). I think the version of busybox-w32 is FRP-5007-g82accfc19 since I downloaded the latest version today. The OS used is Windows 10 Home 22H2.

cmd.exe

C:\Users\user>expr 2 * 2
expr: syntax error

C:\Users\user>expr 2 \* 2
expr: syntax error

C:\Users\user>expr 2 "*" 2
expr: syntax error

C:\Users\user>busybox sh -c "expr 2 \* 2"
4

pwsh

PS C:\Users\user> expr 2 * 2
expr: syntax error
PS C:\Users\user> expr 2 \* 2
expr: syntax error
PS C:\Users\user> expr 2 `* 2
expr: syntax error
PS C:\Users\user> expr 2 "*" 2
expr: syntax error
PS C:\Users\user> busybox sh -c "expr 2 \* 2"
4
rmyorston commented 1 year ago

It's not a bug, just a difference in how Windows and Unix handle command line arguments.

Since busybox-w32 is a Windows application it follows Windows conventions to process command line argument when it's run from cmd.exe or pwsh. When applets are run from the shell the command line is processed using Unix conventions.

When expr is run from cmd.exe or pwsh the * argument is expanded to all the filenames in the current directory. This doesn't work as a multiplication operator :-(

There is an escape hatch: setting the environment variable BB_GLOBBING to zero disables Windows' wildcard expansion. Normally you wouldn't want to do that. It means, for example, that ls *.exe won't list the executables.

To make expr work as expected with cmd.exe (and then undo the effect) do this:

C:\Users\rmy>set BB_GLOBBING=0

C:\Users\rmy>expr 2 * 2
4

C:\Users\rmy>set BB_GLOBBING=

C:\Users\rmy>ls *.exe
busybox.exe

C:\Users\rmy>

For PowerShell:

PS C:\Users\rmy> $Env:BB_GLOBBING = 0
PS C:\Users\rmy> expr 2 * 2
4
PS C:\Users\rmy> $Env:BB_GLOBBING = $null
PS C:\Users\rmy> ls *.exe
busybox.exe
PS C:\Users\rmy>
ikasoba commented 1 year ago

I see that I can disable it with BB_GLOBBING. Thank you very much! m( )m