3

Ok yes this is a homework assignment BUT I am NOT looking to have the answers given to me.

The scenario is that I need a script that searches all my users home directories for bad words. I need the script to report to the screen certain info like username and word found and path. It should ask a user if it is good or bad and if bad be put into a file of list of bad file names, if good remove from list and no longer flagged by the script.

What I have so far is wanting to somehow do a loop. I do know that if I do a grep -r -e kill -e steal /home/* I get a list of what I need. I also know that the list is separated by delimiters which I can pipe to get a variable for the things I need. I also know that I can put it to a file with a > filename.txt

What I have no clue is how to start a loop that would do this...

 for each line in filename.txt
 UNAME=...
 LOC=...
 TXT=...
 echo "Username: $UNAME, Line with bad word found: $TXT, and Path and file name: $LOC. Is this a BAD file? (Y)"
 Read YORN

 if ["$YORN" = "Y" ]; then
 >> (line of text from grep) badfiles.txt
 fi

Next or whatever goes there...

The Requirements: Create a script to run to look for bad words such as (at the minimum) bomb, kill, our full name separated with a space, quit, and steal. You must run once to report to the screen and find all documents to show 1- Username 2- Line containing bad word and 3- path and filename. We are then supposed to change our script or do something to it so that we know where the files are then to ignore the files with legitimate uses for example kill process or quit a program (removes a flag)

What I have done: I have created users and documents to test including these words. I have ran my script (below) and put the output of my command into a file then I loop through the file line by line. For now I just have it echo-ing my variables to see if I am on the right track...

SCRIPT:

grep -r -e kill -e Anne -e bomb -e quit -e steal /home/* > /opt/badword.txt

while read line
do
LOC=`echo -e "$line" | cut -d : -f 1`
TXT=`echo -e "$line" | cut -d : -f 2`
UNAME=`echo -e "$line" | cut -d "/" -f 3`
echo $LOC
echo $TXT
echo $UNAME
done <badword.txt

OUTPUT ON SCREEN FROM RUNNING THIS SCRIPT:

[root@AnneCentOS opt]# ./script4
/home/brownb/doc1
hello my name is xxx i am going to plant a bomb
brownb
/home/brownb/doc2
I want to kill you
brownb
/home/mammaj/doc67
kill process
mammaj
/home/mammaj/doc22
Anne needs to go
mammaj
/home/swiftt/doc
I want to steal a bunch of money so i never have to work again
swiftt
/home/swiftt/doc300
I want to quit this job!
swiftt
[root@AnneCentOS opt]# 

IN MY badword.txt:

/home/brownb/doc1:hello my name is xxx i am going to plant a bomb
/home/brownb/doc2:I want to kill you
/home/mammaj/doc67:kill process
/home/mammaj/doc22:Anne needs to go
/home/swiftt/doc:I want to steal a bunch of money so i never have to work again
/home/swiftt/doc300:I want to quit this job!

Finally I want to add a line after each line to ask user is this is a good file? I want to add an if statement that if the answer = Y then I can remove the line from badword.txt, I THINK I know how to create the question and if statement just don't know if there is a way to remove a specific line from the document I created.

  • In the editor, the "{}" button will add code formatting to whatever you select (or you can put four spaces in front of each line yourself)... please use it, makes the question much more readable. I'm going to edit formatting into your question. – derobert Mar 6 '15 at 18:31
  • Answer updated. – derobert Mar 6 '15 at 18:42
  • You might want to modify your grep command so it finds "Kill" and "KILL", but not "skill", "bombastic", or "stealth". – G-Man Mar 7 '15 at 0:45
3

A couple pointers:

  • You're planning on just scanning /home to find all the home directories. It's probably well beyond an Intro to Linux class, but that actually won't work on more complicated setups. getent passwd might be a little better, but again that's surely beyond Linux I.

  • I'm not completely clear if you're looking for bad words in the file names or the contents. If the names, find is an easy way to search file names (find PATHS '(' -iname '*badword1*' -or -iname '*badword2*' -or … ')' -print)

  • If you're looking in the contents, grep is indeed the way to go. You'll probably want -H to make it always print the file name. -n (print line number, counting from 1) or -b (print byte offset) may be useful as well. Alternatively, -l will give you just the file names that match. (Also, not all files are plain text; results may be weird on binary files).

  • The shell command to read from a file is read. Since you plan on prompting the user during the loop, you'll have to read from somewhere other than stdin (by passing -u). Normally, you'd use it in a while loop. Also, note that the redirect comes after the command—in this case, the command is the entire loop!

    while read -r -u 5 WORD1 WORD2; do
        true   # do something with $WORD1 and $WORD2 here
    done 5<filename.txt
    
  • Word splitting is done by read based on $IFS, like almost all shell commands. So if you set it to ',', it'd split based on commas. If you set it to ':', that could prove useful ☺.

  • You can split paths apart using a variety of methods. cut can do it, basename and dirname get you specific parts. sed and awk can of course do it as well, but are probably overkill. If you're using Bash, then its extended expansion is the easiest (and fastest) way. It's in the man page under "Parameter Expansion". For example:

    $ foo='/home/bob'
    $ echo "${foo#/home/}"
    bob
    

Update:

  • Rather than removing a specific line, I'd suggest that you just write a new file with all the lines the user said aren't OK. You could use something like sed to delete one line from a file, but (behind the scenes) it's actually writing a new file without the line. Generally speaking, filesystems do not allow you shorten a file, except from the end.

  • The prompt is fairly easy, read even has an option for it. But you're going to get a surprising result since you left out all the 5 stuff I had in my example.

  • Check out set -x for debugging.

  • I have worked on it more and have edited my original question with what I found so far... – Anne Mar 6 '15 at 18:24
  • I am so lost...I don't understand any of the help I get so I will just take it to class on Thursday and see what I get. Thank you for trying to help but it is way over my head. – Anne Mar 10 '15 at 15:00

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.