0

I written shell script to get names of all the files that start with a certain name, as well as all the files that have been edited within the previous day. These file names should be assigned to a single variable. I'm running below script on SUSE Linux 15.

DESTINATIONS="main_crontab"
#get all cron files
find . -name "sample_file_*" -type f -mtime -30 -print0 | while read -d $'\0' file
do  
    DESTINATIONS+=" ${file}"
done
echo ${DESTINATIONS} 
Directory Structure:
Folder_A > sample_file_xx.text (modified today)
Folder_A > sample_file_yy.text (modified today)
Folder_A > sample_file_xx.text (modified two days before)

Expected Output:
echo ${DESTINATIONS} # sample_file_xx.text sample_file_yy.text

Current Output:
echo ${DESTINATIONS} # sample_file_xx.text
1
  • Are you sure you're actually getting sample_file_xx.text in DESTINATIONS? I'd expect DESTINATIONS to contain just main_crontab. Can you try again in a fresh shell? Also I just noticed you're running SUSE, which technically makes the question off-topic for this site. That being said I don't think in this specific case it'd make a difference,
    – kos
    Commented Jun 10 at 16:25

1 Answer 1

1

The main problem is that the while loop, being part of a pipeline, is run in a subshell, and will set DESTINATIONS in the subshell that it's run in, not in the current shell.

In addition to that:

  1. -mtime -30 will evaluate to true if the file's modification date is at most 30 days old, which is not what you want; you should change it to -not -mtime -1 (or -mtime +0 - although I find the former to be more eloquent in this case) to catch files whose modification date is at least 1 day old;
  2. You should add IFS= and -r to your read command, to prevent filenames containing leading / trailing whitespace or backslashes, such as file.txt, file.txt or files.tx\t, from being mangled;
  3. In general, you should avoid using all-caps names for variables.

A possible solution would be to run the while loop in the current shell, running the find command in a process substitution:

while IFS= read -r -d $'\0' file
do
    destinations+=" ${file}"
done < <(find . -name "sample_file_*" -type f -not -mtime -1 -print0)
echo ${destinations}

Not the answer you're looking for? Browse other questions tagged .