I have a piece of perl code:
if (glob("$data_dir/*$archivefrom*")) {
my $command1 = "zip -r -T -m $backup_dir/$archivefrom.zip $data_dir/*$archivefrom*";
my $err_cmd1 =system("$command1");
if ($err_cmd1 != 0){print "Error $command1\n";exit 1;}
}
sometimes the if returns true but the zip would not match anything, why would that happen? There is no concurrent processes that would remove files in the meantime, it's just glob is returning something different from zip archive match for files, it returns non-empty result even though it should be empty.
The
glob
function in scalar context becomes an iterator, not a test for file existence! This can be demonstrated by the following code:Output:
That is,
glob
remembers the first pattern it was given, then iterates over all matches, but not use any new patterns it was given until the iterator is exhausted. Therefore in your expressionglob("$data_dir/*$archivefrom*")
, updated values in the$data_dir
and$archivefrom
variables are not recognized. You will also get oneundef
return value at the end of all possibilities. Then theif
branch obviously isn't executed.To test if at least one file matching your pattern exists, you have to fetch all matches at once, thus avoiding the iteration. Use list context for that. We could use the pseudoperator
()=
to count the number of matches – anything ≥ 1 is fine. We can also assign the first match to a variable, and use it in yoursystem
command, to avoid shell interpolation issues: