#1633 PR merged
: unnessary cat command removed¶
Labels: cleanup
, fixed / solved / done
ProBackup-nl opened issue at 2017-12-08 00:13:¶
jsmeix commented at 2017-12-11 10:59:¶
@schlomo
could you have a look if that change could cause
any kind of subtle unexpeted side-effect because
we have same kind of code also in other scripts
usr/share/rear/layout/save/GNU/Linux/240_swaps_layout.sh done < <(cat /proc/swaps) usr/share/rear/lib/layout-functions.sh done < <(cat $LAYOUT_FILE) usr/share/rear/restore/NETFS/default/510_set_capabilities.sh done < <(cat $capabilities_file) usr/share/rear/restore/BLOCKCLONE/default/510_set_capabilities.sh done < <(cat $capabilities_file)
so that I have a dim feeling there might be actually
a valid reason for that overcomplicated looking construct?
schlomo commented at 2017-12-11 11:16:¶
The reason is to be able to set variables in the while
loop that are
valid afterwards. <(<
doesn't exist while $(<
does. If the while
loop is part of a pipe then it is in a subprocess and variables set
there don't affect the mother process of the actual script.
So in these specific examples it will probably be OK to replace the
subshell with a plain < some_file
, if we have a filter or more code in
the subprocess then not.
It might be that I used the same pattern even in places where it was not strictly necessary.
To illustrate:
katar:~ schlomoschapiro$ unset baz ; while read foo bar ; do echo XX $foo YY $bar ; baz=$foo ; done < <(< /etc/shells ) ; declare -p baz
-bash: declare: baz: not found
katar:~ schlomoschapiro$ unset baz ; while read foo bar ; do echo XX $foo YY $bar ; baz=$foo ; done < <(cat /etc/shells ) ; declare -p baz
XX # YY List of acceptable shells for chpass(1).
XX # YY Ftpd will not allow users to connect who are not using
XX # YY one of these shells.
XX YY
XX /bin/bash YY
XX /bin/csh YY
XX /bin/ksh YY
XX /bin/sh YY
XX /bin/tcsh YY
XX /bin/zsh YY
declare -- baz="/bin/zsh"
katar:~ schlomoschapiro$ unset baz ; cat /etc/shells | while read foo bar ; do echo XX $foo YY $bar ; baz=$foo ; done ; declare -p baz
XX # YY List of acceptable shells for chpass(1).
XX # YY Ftpd will not allow users to connect who are not using
XX # YY one of these shells.
XX YY
XX /bin/bash YY
XX /bin/csh YY
XX /bin/ksh YY
XX /bin/sh YY
XX /bin/tcsh YY
XX /bin/zsh YY
-bash: declare: baz: not found
katar:~ schlomoschapiro$ echo $(< /etc/shells)
# List of acceptable shells for chpass(1). # Ftpd will not allow users to connect who are not using # one of these shells. /bin/bash /bin/csh /bin/ksh /bin/sh /bin/tcsh /bin/zsh
katar:~ schlomoschapiro$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
Copyright (C) 2007 Free Software Foundation, Inc.
jsmeix commented at 2018-01-02 13:48:¶
@schlomo
I fail to understand how command < <( < /some/file )
is meant to work.
Reasoning:
< /some/file
redirects STDIN but does not output anything.
Accordingly the command <( < /some/file )
process substitution
would provide the output of < /some/file
to be read by command
from a FIFO file name argument
in the form command FIFO_file_name
e.g. command /dev/fd/123
cf.
https://github.com/rear/rear/issues/1658#issue-283891743
therein what diff -U0 ...
reports which actual files diff
gets.
But there is no output of < /some/file
so that nothing can be read by command
(except EOF).
In the end this way any command
finishes immediately, e.g.:
# time head -v -c 2 < <( < /dev/urandom ) ==> standard input <== real 0m0.004s user 0m0.000s sys 0m0.000s
But this pull request is not about to replace
command < <( cat /some/file )
by a non-working
command < <( < /some/file )
Instead this pull request is about to simplify
command < <( cat /some/file )
by
command < /some/file
i.e. by elimiating the needless cat
plus FIFO in between
and let commnad
directly read from the file.
I think this simplification can only make things work better
because an actual regular file is e.g. seekable in contrast
to a FIFO stream (according to the 'ESPIPE' error in "man lseek")
so that even more things work when using regular files directly.
jsmeix commented at 2018-01-02 14:02:¶
@schlomo
in your example in
https://github.com/rear/rear/pull/1633#issuecomment-350695491
did you perhaps mean a non-working way
where a variable is set in a separated sub-process like
# unset var ; cat /etc/shells | { var=hello ; head -v -n 2 ; } ; declare -p var ==> standard input <== /bin/ash /bin/bash -bash: declare: var: not found
versus working ways
where a variable is set in the same process like
# unset var ; { var=hello ; head -v -n 2 ; } < <( cat /etc/shells ) ; declare -p var ==> standard input <== /bin/ash /bin/bash declare -- var="hello" # unset var ; { var=hello ; head -v -n 2 ; } < /etc/shells ; declare -p var ==> standard input <== /bin/ash /bin/bash declare -- var="hello"
[Export of Github issue for rear/rear.]