bash - What does -1 in "ls -1 path" mean? -
i looking @ shell code meant count of number of files in directory. reads:
count=$(ls -1 ${dirname} | wc -l)
what -1
part mean? can't find in other questions, passing references iterating on files in directory isn't looking at. also, removing command seems have no effect.
count=$(ls -1 ${dirname} | wc -l)
...is buggy way count files in directory: ls -1
tells ls
not put multiple files on single line; making sure wc -l
then, counting lines, count files.
now, let's speak "buggy":
- filenames can contain literal newlines. how version of
ls
handles implementation-defined; versions double-count such files (gnu systems won't, wouldn't want place bets about, say, random releases ofbusybox
floating around on embedded routers). - unquoted expansion of
${dirname}
allows directory name string-split , glob-expanded before being passedls
, if name contains whitespace, can become multiple arguments. should"$dirname"
or"${dirname}"
instead.
...also, inefficient, invokes multiple external tools (ls
, wc
) shell can manage internally.
if want more robust, version work posix shells:
count_entries() { set -- "${1:-.}"/*; if [ -e "$1" ]; echo "$#"; else echo 0; fi; } count=$(count_entries "$dirname") ## ideally, dirname should lower-case.
...or, if want faster-executing (not requiring subshell), see below (targeting bash):
# above, write named variable, not stdout count_entries_to_var() { local destvar=$1 set -- "${2:-.}"/* if [[ -e "$1" || -l "$1" ]]; printf -v "$destvar" %d "$#" else printf -v "$destvar" %d 0 fi } count_entries_to_var count "$dirname"
...or, if you're targeting bash , don't want bother function, can use array:
files=( "$dirname"/* ) if [[ -e "${files[0]}" || -l "${files[0]}" ]]; echo "at least 1 file exists in $dirname" echo "...in fact, there ${#files[@]} files in $dirname" else echo "no files exist in $dirname" fi
finally -- if want deal list of file names large fit in memory, , have gnu find
, consider using that:
find "$dirname" -mindepth 1 -maxdepth 1 -printf '\n' | wc -l
...which avoids putting names in stream @ (and generates stream 1 measure length in bytes rather number of lines, if 1 chose).
Comments
Post a Comment