For a school assignment, I‘m trying to loop through directories and subdirectories recursively to sum up the size of files. The issue I’m having is that the construction:
for f in ./* ./.*; do
# summing logic here
done
Is getting stuck on f = ./.
It works fine stepping into each directory, but once it gets to a directory that it fully processes, after the last file, f
gets set to ./.
. I have logic to check if f
is a directory, which it does, and then steps into f
to process it. And loop there forever.
I‘ve tried including code to check if the string f
matches to “./.”
or ”./..”
, but it does not ever evaluate to true. What is the mistake I’m making?
MAIN QUESTION: Why is if [[ "$f" != "./." ]] || [[ "$f" != "./.." ]]; then
not working and what can I do to get the same result? Additionally, if I try something like for f in ./* ./.* ; do echo $f done
, I don’t see ./.
and ./..
get printed out. How is f
getting set to those values in my script?
I’ve seen answers to similar questions that involve the bash-builtin shopt
, but I use zsh and the school’s test server uses csh. I’m really hoping for something platform agnostic.
Minor note: As the code is right now, the assignment is done. We are only required to sum the sizes of the files in the current working directory, excluding subdirectories. I was curious about making the script recursive and am only doing this part to satisfy my interest. Thanks for the assistance.
#!bin/bash
total_size=0
get_file_size() {
stat --printf="%s" "$1"
}
add_file_sizes() {
for f in ./* ./.*; do
echo "Currently processing: $f"
if [ -d "$f" ] && [ "$1" == -r ]; then
echo "$f is a directory"
if [ "$f" != "./." ] || [ "$f" != "./.." ]; then
echo "$f is not ./. or ./.."
cd "$f"
pwd
add_file_sizes "-r"
echo "$total_size"
cd ../
fi
fi
if [ ! -d "$f" ]; then
echo "$f is not a directory"
total_size=$((total_size + $(get_file_size "$f")))
echo "$total_size"
fi
done
}
add_file_sizes $1
echo "$total_size"
Edit: Here’s some output:
Currently processing: list_size.sh
list_size.sh is not a directory
625
Currently processing: output.txt
output.txt is not a directory
759
Currently processing: test_dir
test_dir is a directory
test_dir is not ./. or ./..
/home/joe/dev/csc60/test_dir
Currently processing: file1
file1 is not a directory
759
Currently processing: file2
file2 is not a directory
759
Currently processing: test_subdir
test_subdir is a directory
test_subdir is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
EDIT 2: Tweaked the initial for loop and generally improved script in response to a suggestion in an answer.
Output when I change for loop to for f in * .[!.]*
:
Currently processing: list_size.sh
list_size.sh is not a directory
578
Currently processing: list_size_tweaked.sh
list_size_tweaked.sh is not a directory
1156
Currently processing: output_tweaked.txt
output_tweaked.txt is not a directory
1394
Currently processing: output.txt
output.txt is not a directory
1394
Currently processing: test_dir
test_dir is a directory
test_dir is not ./. or ./..
/home/joe/dev/csc60/test_dir
Currently processing: file1
file1 is not a directory
1394
Currently processing: file2
file2 is not a directory
1394
Currently processing: test_subdir
test_subdir is a directory
test_subdir is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
1394
Currently processing: .[!.]*
.[!.]* is not a directory
1394
stat: cannot stat '.[!.]*': No such file or directory
./list_size_tweaked.sh: line 25: total_size + : syntax error: operand expected (error token is "+ ")
7670
This seems to happen because there are no dotfiles in the directory, so the glob doesn’t expand.