[Slackbuilds-users] [template] find .. strip doesn't work with whitespaces and '
Arkadiusz Drabczyk
arkadiusz at drabczyk.org
Mon Jul 30 14:34:57 UTC 2018
Probably not the most important issue but it piqued my interest today.
Example list of files:
$ ls -1
'l'ibsuper.so
'libsuper.so
lib super.so
libsuper.so
Using find ... strip line from the current template:
$ find . -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs stat --format=%n || true
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
./libsuper.so
./libsuper.so
I noticed that this issue was first attempted to be fixed in fdf8673:
$ find . -print | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs stat --format=%n || true
It didn't work of course because -print0 was not used and fix was
provided in commit 9fb8a16 which is also what we use today.
Current approach not only fails with filenames that contain ' but also
with filenames that contain whitespaces:
$ ls -1
lib super.so
libsuper.so
$ find . -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs stat --format=%n || true
./libsuper.so
stat: cannot stat './lib': No such file or directory
stat: cannot stat 'super.so': No such file or directory
As crazy as it seems for someone to include whitespace or ' in library
name I checked that gcc and ld.so don't have problems with that and as
fix was added to the repository I guess someone had to already
encounter this problem.
IMO the problem with the current approach is that list of files is not
passed correctly to the second xargs after cut. A suggested fix would
be:
$ find . -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF | cut -d : -f1 | tr '\n' '\0' | xargs -0 stat --format=%n || true
or:
$ find . -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF | cut -d : -f1 | xargs -d '\n' stat --format=%n || true
There are 2 problems with that - first, it looks strange and second,
it doesn't work correctly with filenames that contain newlines.
Arguably, newlines in filenames are even less common that whitespaces
and single quotes. Alternative fix that also works with newlines:
$ find . -print0 | while read -rd $'\0' x; do file "$x" | grep -e "executable" -e "shared" | grep ELF >/dev/null && stat --format=%n "$x"; done
Its disadvantage is that it's much slower than the first fix:
$ time find . -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF | cut -d : -f1 | xargs -d '\n' stat --format=%n || true
./libsuper.so
./'libsuper.so
./lib super.so
./'l'ibsuper.so
real 0m0.019s
user 0m0.034s
sys 0m0.011s
$ time find . -print0 | while read -rd $'\0' x; do file "$x" | grep -e "executable" -e "shared" | grep ELF >/dev/null && stat --format=%n "$x"; done./libsuper.so
./libsuper.so
./'libsuper.so
./lib super.so
./'l'ibsuper.so
real 0m0.073s
user 0m0.094s
sys 0m0.034s
--
Arkadiusz Drabczyk <arkadiusz at drabczyk.org>
More information about the SlackBuilds-users
mailing list