Hi Ian,

Ian Campbell <i...@hellion.org.uk> wrote:
> It seems there is an interesting (and new to me, or at least I'd never
> fully appreciated the behaviour) corner case of the `if $(foo); then`
> syntax, which is that if `foo` exits producing no output then its exit
> code is apparently used for the condition. If `foo` does produce output
> then the shell will attempt to execute that and use the resulting exit
> code.
> 
> These just run true or false and take the output:
> 
>    $ dash -c 'if true ; then echo YES ; else echo NO ; fi'
>    YES
>    $ dash -c 'if false ; then echo YES ; else echo NO ; fi'
>    NO
> 
> These run true or false, see the output is "" and so use the exit code:
> 
>    $ dash -c 'if $(true) ; then echo YES ; else echo NO ; fi'
>    YES
>    $ dash -c 'if $(false) ; then echo YES ; else echo NO ; fi'
>    NO
> 
> These run `echo` (which always succeeds) then runs the resulting "true"
> or "false" and uses the exit code:
> 
>    $ dash -c 'if $(echo true) ; then echo YES ; else echo NO ; fi'
>    YES
>    $ dash -c 'if $(echo false) ; then echo YES ; else echo NO ; fi'
>    NO
> 
> This runs `echo` (which always succeeds) then tries to run the
> resulting "foo" and fails because that isn't a command:
> 
>    $ dash -c 'if $(echo bar) ; then echo YES ; else echo NO ; fi'
>    dash: 1: bar: not found
>    NO
> 
> `git status` outputs nothing when the tree is clean, and I think the
> `$($git status -s -uno $DI_COPY/packages/po)` case uses that to succeed
> on a clean tree, however if the tree was dirty you'd get the "not
> found" stuff for something relating to the output.
> 
>    $ git status -s -uno build/Makefile
>    $ echo $?
>    0
>    $ dash -c 'if $(git status -s -uno build/Makefile ) ; then echo CLEAN ; 
> else echo DIRTY ; fi'
>    CLEAN
>    $ echo "FOO" >> build/Makefile
>    $ git status -s -uno build/Makefile
>    M build/Makefile
>    $ echo $?
>    0
>    $ dash -c 'if $(git status -s -uno build/Makefile ) ; then echo CLEAN ; 
> else echo DIRTY ; fi'
>    dash: 1: M: not found
>    DIRTY
> 
> Notice that the original svn version had a `| grep -q ^C` which was
> checking if any line started with a "C" (for Changed I suppose),
> produced no output (`-q`) but exited with an error code reflecting the
> presence of any lines. You could do something similar but you'd need to
> check for more than M (modified) since git status has a variety of
> error codes, including (A)dded, (D)eleted, (R)enamed etc.
> 
> `git status` doesn't seem to have an option which makes the error code
> reflect the dirtiness. In the past I've used:
> 
>    # Update cache, otherwise files which have an updated
>    # timestamp but no actual changes are marked as changes
>    # because `git diff-index` only uses the `lstat` result and
>    # not the actual file contents. Running `git update-index
>    # --refresh` updates the cache.
>    git update-index -q --refresh
>    if git diff-index --quiet HEAD -- path/to/something ; then clean ;
>    else dirty ; fi
> 
> (--quiet enable --exit-code which makes the exit status meaningful).
> 
> For perhaps less git magic you could also just write it as:
>    if [ -z "$(git status -s -uno path/to/something)" ] ; then clean ; else 
> dirty ; fi
> or inversely:
>    if [ -n "$(git status -s -uno path/to/something)" ] ; then dirty ; else 
> clean ; fi

Thank you for your very detailed explanation!

First I will try to get it running with above (minimalist) variant.


Holger

-- 
============================================================
Created with Sylpheed 3.5.1 under 
        D E B I A N   L I N U X   9   " S T R E T C H " .

Registered Linux User #311290 - https://linuxcounter.net/
============================================================

Reply via email to