سؤال

I have this bash "for in" loop that looks for pdf files in a directory and prompt them (simplified for the example)

#!/bin/bash
for pic in "$INPUT"/*.pdf
do
    echo "found: ${pic}"
done

This script works well when there are pdf files in $INPUT directory, however, when there are no pdf files in the directory, I get :

found: /home/.../input-folder/*.pdf

Is it the expected behavior ? How can I deal with it with a for in loop ? Do I need to use ls or find ?

I tried with and without quotes around "$INPUT". There are no spaces in files names and directory names.

هل كانت مفيدة؟

المحلول

This is the expected behavior. According to the bash man page, in the Pathname Expansion section:

After word splitting, unless the -f option has been set, bash scans each word for the characters *, ?, and [. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern. If no matching file names are found, and the shell option nullglob is not enabled, the word is left unchanged.

As a result, if no matches for "$INPUT"/*.pdf are found, the loop will be executed on the pattern itself. But in the next sentence of the man page:

If the nullglob option is set, and no matches are found, the word is removed.

That's what you want! So just do:

#!/bin/bash
shopt -s nullglob
for pic in "$INPUT"/*.pdf
do
    echo "found: ${pic}"
done

(But be aware that this may change the behavior of other things in unexpected ways. For example, try running shopt -s nullglob; ls *.unmatchedextension and see what happens.)

نصائح أخرى

I would just add a file exists test like this:

#!/bin/bash
if test -e `echo "$INPUT"/*.pdf | cut -d' ' -f1`
then
    for pic in "$INPUT"/*.pdf
    do
        echo "found: ${pic}"
    done
fi
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top