简体   繁体   中英

Counting the number of files, directories, and executables in the home directory using shell scripts

so I am trying to write a program that will count the files, directories, and executable in the home directory. For some reason it doesn't read the right numbers for how many files there are, directories, or executables. When I am in the command line it reads

ls ~/* | ls -f | wc -l = 31
ls ~/* | ls -d | wc -l = 1
ls ~/* | ls -x | wc -l = 5

This is my code and output

 files=0
 directories=0
 executables=0

 for i in ~/*;do
     if [[ -f "$i" ]];then
         files=$(($files + 1))
     elif [[ -d "$i" ]];then
         directories=$(($directories + 1))
     elif [[ -x "$i" ]];then
         executables=$(($executables + 1))
     fi
 done
 echo Files $files, Directories $directories, Executables $executables

Output is Files 14, Directories 2, Executables 0

Why is that happening anyone?

  • ls -f : will list without sorting. This implies -a . So, you'll get everything, including . and .. , file or directory. It's not at all like the test [[ -f $file ]] . That's why ls -f | wc -l ls -f | wc -l 's answer 31 is a lot larger than the 14 from your script.
  • ls -d : will list directory instead of content. Without any argument, this is, logically, 1, that corresponds to . (it doesn't list the content of . ). That's why you obtain 1.
  • ls -x : list entries by lines instead of columns... so this is just not going to count anything relevant whatsoever.

Your script is nearly fine… except that because of your if/elif statements, the last test is nearly never going to be checked: executable files and directories will be if 'd before!

You very likely want:

#!/bin/bash

files=0
directories=0
executables=0

for i in ~/*;do
    if [[ -f $i ]];then
        ((++files))
        if [[ -x $i ]]; then
            ((++executables))
        fi
    elif [[ -d $i ]];then
        ((++directories ))
    fi
done
printf 'Files: %s, among which %d are executable\n' "$file" "$executables"
printf 'Directories: %s\n' "$directories\n'

You need to check for directories first and next check for executable because an executable file is also a file hence your script never reaches inside this condition:

elif [[ -x "$i" ]];then

Here is the corrected version of your script:

for i in ~/*; do
    if [[ -d "$i" ]];then
       ((directories++))
    elif [[ -x "$i" ]];then
       ((executables++))
    elif [[ -f "$i" ]];then
       ((files++))
    fi
done

echo "Files: $files, Directories: $directories, Executables: $executables"

I would use find and pipe the results to awk :

find "$HOME" -mindepth 1 -maxdepth 1  -printf "%Y %M\n" \
  | awk '/f/{f++}/^f.*x/{x++}/d/{d++}END{printf "Files: %s Directories: %s Executables: %s\n",f,d,x}'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM