Search code examples
bashshellsyntaxfindpipe

Different errors in $() command substitution


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?


Solution

  • 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:

    function lt() { find $1 -name "*.jpg" -o -name "*.mp4" -o -name "*.mp3"; }
    for us in /home/*
    do
       if [ -d "$us" ]; then
            N_MP3=$(lt "$us" | grep "\.mp3$" | wc -l)
       fi
    done