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 of busybox floating around on embedded routers).
  • unquoted expansion of ${dirname} allows directory name string-split , glob-expanded before being passed ls, 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

Popular posts from this blog

java - Static nested class instance -

c# - Bluetooth LE CanUpdate Characteristic property -

JavaScript - Replace variable from string in all occurrences -