I'm trying to understand how to use curly braces and quotes properly in bash. I'm wondering why the third example of an ls command doesn't work.
#!/bin/bash -vx
# File name prefix.
File_name_prefix='this_is_a_file_name_prefix'
# Let's do this in the /tmp directory.
cd /tmp
# Let's make three empty files.
touch ${File_name_prefix}_1.txt
touch ${File_name_prefix}_2.txt
touch ${File_name_prefix}_3.txt
# Let's list the three files.
# This works.
ls "$File_name_prefix"*
# This works.
ls ${File_name_prefix}*
# This does not work.
ls "${File_name_prefix}*"
# This fails.
find ./ -type f -name '${File_name_prefix}*'
# This fails spectacularly.
find ./ -type f -name ${File_name_prefix}*
# But this works.
find ./ -type f -name "${File_name_prefix}*"
echo "Why?"
# Clean up.
rm ${File_name_prefix}*
exit
When you execute a command like first and second examples:
ls "$File_name_prefix"*
ls ${File_name_prefix}*
Command interpreter actually execute a command with interpolation according to directory content. A directory is used from command line itself or current directory is used (if command line has relative path),
so it executes like this (assume $File_name_prefix
is fp
and directory has files fp1
fp2
fp3
):
ls fp1 fp2 fp3
But for third example command interpreter consider quoted argument as ready to use and do not applies *
interpolation.
so it executes like this:
ls "fp*"
And because there is no file with name fp*
(with asterisk in name) but only files fp1
fp2
fp3
(as we assumes) in the directory, therefore it show empty list or says that there is no such file or directory