Re: built-in '[' and '/usr/bin/[' yield different results
On 11/13/18 10:29 AM, Service wrote: # ensure that file1 exists and that file2 does not exist There's your problem. It is inherently ambiguous what timestamp to use when a file is missing (infinitely new or infinitely old, or always an error for not existing); bash's -nt picked one way, while other shells have picked the other. POSIX is silent on the matter (-nt is an extension outside of POSIX), so there is nothing portable you can rely on. /bin/touch file1 /bin/rm -f file2 # built-in if [ file1 -nt file2 ]; then echo nt; else echo not_nt; fi # external if /usr/bin/[ file1 -nt file2 ]; then echo nt; else echo not_nt; fi # Output is as expected: nt nt That is, bash's builtin '[' and coreutil's external '[' happened to pick the same thing: a missing file is treated as infinitely old. 2. This does not work: # Put the above commands into a script, say check.sh # Run with: /bin/sh < check.sh # Or : /bin/sh ./check.sh # Or : /usr/bin/env ./check.sh # Output is always not ok: not_nt nt Most likely, this is because your /bin/sh is not bash, but probably dash, and dash has picked a missing file as being treated as always an error. That does not make it a bug in bash, though, but a difference in behavior of your /bin/sh. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: built-in '[' and '/usr/bin/[' yield different results
On 13.11. 18:29, Service wrote: # Put the above commands into a script, say check.sh # Run with: /bin/sh < check.sh # Or : /bin/sh ./check.sh # Or : /usr/bin/env ./check.sh # Output is always not ok: not_nt nt $ cat check.sh export PATH="" /bin/touch file1 /bin/rm -f file2 if [ file1 -nt file2 ]; then echo nt; else echo not_nt; fi if /usr/bin/[ file1 -nt file2 ]; then echo nt; else echo not_nt; fi $ bash ./check.sh nt nt $ /bin/sh ./check.sh not_nt nt Isn't that Windows Linux thingy based on Ubuntu? /bin/sh isn't Bash by default on Debian and Ubuntu, so it might be you're just not running the script with Bash. -- Ilkka Virta / itvi...@iki.fi
Re: built-in '[' and '/usr/bin/[' yield different results
On Tue, Nov 13, 2018 at 05:29:42PM +0100, Service wrote: > Repeat-By: > Under Windows 10, WSL. Then why did you send this to a debian.org address? > Start "bash", terminal with shell pops up. > 2. This does not work: > > # Put the above commands into a script, say check.sh > # Run with: /bin/sh < check.sh > # Or : /bin/sh ./check.sh In both of these cases, you're explicitly calling /bin/sh rather than bash. So you are not using bash's builtin [. You are using WSL's sh's builtin [ command. You might start by identifying which shell WSL uses as its sh. > # Or : /usr/bin/env ./check.sh In this case, it would use the shebang line of check.sh to decide which shell to run. However, I suspect you did not include a shebang line at all. In that case, /usr/bin/env will decide how to handle the exec format error. It might decide to spawn sh for you, in which case this would explain why the result matches the first two results.
built-in '[' and '/usr/bin/[' yield different results
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/bash-vEMnMR/bash-4.4.18=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -Wno-parentheses -Wno-format-security uname output: Linux COOL4 4.4.0-17134-Microsoft #345-Microsoft Wed Sep 19 17:47:00 PST 2018 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.4 Patch Level: 19 Release Status: release Description: It seems that the built-in 'test' does not work properly when run in a sub-shell. Repeat-By: Under Windows 10, WSL. Start "bash", terminal with shell pops up. 1. This works when typed directly: # make everything explicit export PATH="" # ensure that file1 exists and that file2 does not exist /bin/touch file1 /bin/rm -f file2 # built-in if [ file1 -nt file2 ]; then echo nt; else echo not_nt; fi # external if /usr/bin/[ file1 -nt file2 ]; then echo nt; else echo not_nt; fi # Output is as expected: nt nt 2. This does not work: # Put the above commands into a script, say check.sh # Run with: /bin/sh < check.sh # Or : /bin/sh ./check.sh # Or : /usr/bin/env ./check.sh # Output is always not ok: not_nt nt