2

I am coding a BASH script that should remove a file based on its name, content or simply close the program. Specifically, I am having trouble with deleting a file based on its contents ( case 2 ). I am able to populate a file with any files that match the contents. However, my code malfunctions when the user is supposed to input whether or not they want to delete the file (using read). Instead of asking the user for input, the variable automatically gets filled with the location of the file to delete.

#!/bin/bash

#set -x
#Programmer: Redacted
#Z: ID: Redacted
#Assignment:  cleaner.sh

directory=`pwd` #sets the directory variable to pwd
string="string"
file="file"
fileFound=matched.txt
possibleFiles=''
result=''
function askDelete #asks for verification
{
    #echo "$fileName was found, still want to delete it? (y/n)"
    read -p "$fileName was found, still want to delete it? (y/n)" continue
    echo "Continue is equal to: $continue"
}


echo    "Welcome to my CLEANER script!"
echo    "Enter 1: delete by filename."
echo    "Enter 2: delete by a string within the file."
echo    "Enter 3 or quit: exit this program."
read command
    case $command in
    "file")
        command=1 ;;
    "string")
        command=2 ;;
    esac

case $command in
    1)
            #Prompts user for which file they want to delete
        echo "What file would you like to delete? "
        read fileName
        #find $PWD -type f -name "$fileName"
        #result= -x $fileName
        if [ -a "$fileName" ]
            then
                askDelete
                if [ $continue == 'y' ] || [ $continue == 'Y' ]
                    then
                        rm $fileName
                        echo "File has been removed"
                    else
                        echo "File has not been removed"
                fi

            else
                echo "No files were found"
        fi

    ;;

    #case where user entered 2
    #user wants to enter a string within the files to delete
    2)
        touch 'matched.txt' #creates the file that will be used
        echo "Enter the string that you wish to have the files containing it to be destroyed"
        read pattern    #user enters what they want to search for
        find $PWD -type f 1>possibleFiles.txt
        #echo $PWD
        #grep -q "$pattern" 'foundFile.txt' 1> matched.txt
        echo 'This is where it breaks'
        cat possibleFiles.txt | while read fileName
        do
            #\echo $fileName
            grep -q "$pattern" "$fileName" 1> matched.txt
            if [ $? == 0 ]
            then
                askDelete
                if [ $continue == 'y' ] || [ $continue == 'Y' ]
                    then
                        rm $fileName
                    else
                        echo  "No found files have been removed"
                fi
            else
                echo "No matches for the pattern were found"
            fi
        done
#
#       if [ $? == 0 ]
#           then
#               askDelete
#               if [ $continue == "Y" ] || [ $continue == "y" ]
#                   then
#                       #cat matched.txt 
#                       for file in 'matched.txt'
#                       do
    #                       echo 'bleh'
#                       done
    #               else
#                       echo  "No found files have been removed"
#               fi
#           else
#               echo "No matches for the pattern were found"
#       fi
#       fi
        ;;

    #case where user entered 3
    #user wants to exit
    3)
        echo "Goodbye friend"
        exit
    ;;

    *)
        echo Digit 1, 2 or 3 must be entered
esac

I believe the problem lies somewhere inside of the askDelete function near the top of the program. Specifically the line: read -p "$fileName was found, still want to delete it? (y/n)" continue

Any help is appreciated

3

Because the whole block while...done has stdin redirected (indirectly throught a pipe and then) from the file possibleFiles.txt, every command inside this block inherits the same stdin. So while that's what you want for read that's really not what you want for askDelete, because it's eating one line of input from the same possibleFiles.txt used by read.

Fortunately, the tty (your terminal) is still available through /dev/tty. Just replace inside the loop askDelete with askDelete </dev/tty and everything should work as intended.

You should still add more verifications: for example this program can't run outside a terminal (giving prefilled y/n answers with some other file) with this simple correction because /dev/tty won't work anymore: you'd have to find ways to not "overwrite" stdin.

| improve this answer | |

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.