The bash script snippet

folder="some folder's name"
if [ "$a" != "$folder"'/*.pdf' ]
    echo check

never prints check.

I'd expect it to print check iff there is at least 1 file whose name ends in .pdf in folder $folder.

echo $a and echo "$folder"'/*.pdf' print exactly what I'd expect them to print: The former prints the matched paths iff there is at least 1 *.pdf file in the specified folder and otherwise prints what the latter prints. The latter always prints the name of the specified older concatenated with /*.pdf.

  1. Why does bash behave like that?
  2. How do I make it work?
  • 3
    The proper way to do it is described here: Test if there are files matching a pattern in order to execute a script – don_crissti Oct 23 '17 at 19:20
  • With bash, that condition ([ "$#" -gt 0 ]) always passes. It think this is because bash just doesn't replace the asterisk if there is no match, so there always is at least 1 result. – UTF-8 Oct 23 '17 at 22:41
  • No. If you bother reading the answer there you'll see there's a shopt -s nullglob before that condition. – don_crissti Oct 23 '17 at 22:43
  • Oh, you're right. I'm sorry. With that option set, it works. Thank you. – UTF-8 Oct 23 '17 at 22:53

This expression "$folder/"*".pdf" will expand to all possible filenames that end with .pdf.
Why? The * sign retains its special meaning i.e. globbing.

While this string "$folder"'/*.pdf' is just a concatenation of 2 separate strings "$folder" and '/*.pdf'.
As * sign enclosed in single quotes - it loses its special meaning.

According to your main goal check if the current folder has at least one .pdf file and printing some "pdf file found!" phrase on success:

if [ ! -z `find foldername -type f -name "*.pdf" -print -quit` ]; then 
    echo "pdf file found!"
  • That's the plan. So the condition should be true if there are PDFs in the specified folder, right? (Note the exclamation point.) – UTF-8 Oct 23 '17 at 20:02
  • @UTF-8, your final goal is to echo "check" if the current folder has at least one *.pdf file, right? – RomanPerekhrest Oct 23 '17 at 20:08
  • Yes, that's what I'm trying to do. – UTF-8 Oct 23 '17 at 20:41
  • @UTF-8, see my update – RomanPerekhrest Oct 23 '17 at 20:47
  • This fails on a number of occasions. I'm not entirely sure what occasions, though: pastebin.com/nasQePMx – UTF-8 Oct 23 '17 at 22:47

Your if statement doesn't work, because $a enclosed in double quotes is just a string containing a * (compare echo "$a" with echo $a). If you remove the double quotes, your if statements fails as soon as there are more than one files matching.

don_crissti's link has good solutions.

  • We both agree that the right expression doesn't depend on the folder's contents, right? If there is no file in the folder, bash doesn't replace the wild card * in the variable assignment. So my plan is to check whether that replacement happened. – UTF-8 Oct 23 '17 at 20:06
  • Yes, Bash does not replace * when there is no match (corrected my answer). I still don't think you can handle the case of >1 matches (many pdf files in the folder) this way. If you are not enclosing $a in ", the if statement is going to fail with too many arguments. If you are enclosing $a in ", * is not going to be resolved/replaced by file names. Thus, I don't think if in combination with file name expansion is a good idea. I have been using ls' exit status before, but there other options. – sborsky Oct 23 '17 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.