I’m getting different errors running the code below (it counts the number of .mp3 files in each user directory):
for us in /home/*
do
if [ -d $us ]
then
LT=$(find $us -name "*.jpg" -o -name "*.mp4" -o -name "*.mp3")
N_MP3=$("$LT" | grep ".mp3$" | wc -l)
N_MP3=$($LT | grep ".mp3$" | wc -l)
N_MP3=$(find $us -name "*.jpg" -o -name "*.mp4" -o -name "*.mp3" | grep ".mp3$" | wc -l)
fi
done
Considerer that we have, in some user directory, let’s say user=ubuntu, the files:
- sample.jpg
- sample.mp3
So let’s run the code:
(1) Doing "$LT" | …, I get the message:
/home/ubuntu/Desktop/Songs/sample.mp3 /home/ubuntu/Desktop/Images/sample.jpg: No such file or directory
which means "$LT" command was executed and found all .mp4, .mp3 or .jpg files in my user and then gives that error.
(2) Doing $LT | …, which is equivalent to $(find $us -name ".jpg" -o -name ".mp4" -o -name "*.mp3") | … I get the message /home/ubuntu/Desktop/Songs/sample.mp3: Permission denied. It means $LT command was executed and found only .mp3 file and then gives that error.
If I delete sample.jpg from my user=ubuntu, then in both cases I got the same error message: /home/ubuntu/Desktop/Songs/sample.mp3: Permission denied.
I know (but don’t know why) I should use an echo command before $LT, but I’d like to know what’s happening in theses cases which I didn’t use echo before. Please, can someone shed a light on these errors?
2
Answers
This happens due to word splitting.
When you word split, the first word will become the command name, and remaining words will become arguments.
When you don’t word split, the entire value will be used as the command name.
Bash shows the command name you tried to execute when it’s not found, which is why the values are reflected in the error message:
LT=$( ...)
You’re using command substitution, so you’re not storing a string for later reuse, you’re trying to execute the output of the find command; that’s not going to work.
Slightly more elegant: