3

I am working on this bash script that is supposed to delete files with a particular extension and I don't want it to return a no such file or directory output when I check if those files still exist. Instead, I want it to return a custom message like: "you have already removed the files". here is the script:

#!/usr/bin/env bash
read -p "are you sure you want to delete the files? Y/N " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]
then
  rm *.torrent
  rm *.zip 
  rm *.deb
echo "all those files have been deleted............."
fi
mots
  • 195
  • 1
  • 4
  • 22

2 Answers2

2

You could do like this:

rm *.torrent *.zip *.deb 2>/dev/null \
&& echo "all those files have been deleted............." \
|| echo "you have already removed the files"

This will work as expected when all files exist, and when none of them exist.

You didn't mention what to do if some of them exist but not all. For example there are some .torrent files but there are no .zip files.

To add a third case, where only some of the files were there (and now removed), you would need to check the exit code of the removal for each file type, and produce the report based on that.

Here's one way to do that:

rm *.torrent 2>/dev/null && t=0 || t=1
rm *.zip 2>/dev/null && z=0 || z=1
rm *.deb 2>/dev/null && d=0 || d=1

case $t$z$d in
  000)
    echo "all those files have been deleted............." ;;
  111)
    echo "you have already removed the files" ;;
  *)
    echo "you have already removed some of the files, and now all are removed" ;;
esac
janos
  • 120,954
  • 29
  • 226
  • 236
1

There are a few relatively elegant options available to you.

One would be to wrap rm in a function that checks if there are any files of the type you want to delete in your folder. You could use ls to check if there are any files matching your wildcard, as per this question:

#!/usr/bin/env bash

rm_check() {
    if ls *."${1}" 1> /dev/null 2>&1; then
        rm *."${1}"
        echo "All *.${1} files have been deleted"
    else
        echo "No *.${1} files were found"
    fi
}

read -p "are you sure you want to delete the files? Y/N " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    rm_check torrent
    rm_check zip 
    rm_check deb
fi

This version is nice because it has everything laid out the way you originally planned.

A cleaner version, in my opinion, would be one that only looked at files that matched your pattern to begin with. As I suggested in the comments, you could do it with a single find command:

#!/usr/bin/env bash
read -p "are you sure you want to delete the files? Y/N " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]];  then
    find -name '*.torrent' -o -name '*.zip' -o -name '*.deb' -delete
    echo "all those files have been deleted............."
fi

This method makes your script very short. The only possible disadvantage of this method for your purpose is that it will not report which file types are missing.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264