Re: built-in '[' and '/usr/bin/[' yield different results

2018-11-13 Thread Eric Blake

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

2018-11-13 Thread Ilkka Virta

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

2018-11-13 Thread Greg Wooledge
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

2018-11-13 Thread Service

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