2

I'm looking into writing shells scripts as a prerequisite for a class and would like some help to get started. I'm currently doing a warm up exercise that requires me to write a shell script that, when executed, will kill any currently running process of a command I have given. For this exercise, I'm using the 'less' command (so to test I would input 'man ps | less').

However, since this is the first REAL script I'm writing (besides the traditional "Hello World!" one I've done), I'm a little stuck on how to start. I'm googled a lot and have returned some rather confusing results. I'm aware I need to start with a shebang, but I'm not sure why. I was thinking of using 'if' statement; something along the lines of

if 'less' is running
kill 'less' process
fi

But I'm not sure of how to go about that. Since I'm incredibly new at this, I also want to make sure I'm going about writing a script correctly. I'm using notepad as a text editor, and once I've written my script there, I'll save it to a directory that I access in a terminal and then run from there, correct?

Thank you very much for any advice or resources you could give me. I'm certain I can figure out harder exercises once I get the basics of writing a script down.

Kommander Kitten
  • 283
  • 2
  • 7
  • 16

3 Answers3

1

Try:

pgrep less && killall less

pgrep less looks process ids of any process named less. If a process is found, it returns true in which case the && clause is triggered. killall less kills any process named less.

See man pgrep and man killall.

Simplification

This may miss the point of your exercise, but there is no real need to test for a less process running. Just run:

killlall less

If no less process is running, then killall does nothing.

John1024
  • 109,961
  • 14
  • 137
  • 171
  • Thanks for your response. So I've tried to put this into a text editor and run it in another terminal, different from the one where the 'less' command is running, and it says 'bad interpreter: Not a directory'. When I changed the directory to where my .txt was saved, it claimed 'command not found'. What could have gone wrong? – Kommander Kitten Sep 24 '15 at 18:15
  • So I've prefaced my script with 'sh' and now it seems to be doing something! In one terminal, I've run 'ps | less' and then in another, my shell script. It says "Terminated" in the first one, so I think we've done it! My only concern is when I run "ps", I see that there are 4 other 'less' processes still active... shouldn't 'killall' get rid of all of them? – Kommander Kitten Sep 24 '15 at 18:22
  • @KommanderKitten Very good! By the way, if your course is about `bash`, it would probably be better to run `bash scriptname` rather than `sh scriptname`. On some systems, `sh` lacks all the features of `bash`. – John1024 Sep 24 '15 at 18:25
  • I'll keep that in mind. Thank you! – Kommander Kitten Sep 24 '15 at 18:47
  • @KommanderKitten _"shouldn't 'killall' get rid of all of them?"_ Yes, it should kill all _except_ for the ones that it lacks permission to kill, such as those run by other users. – John1024 Sep 24 '15 at 19:03
1

Try this simple snippet:

#!/bin/bash

# if one or more processes matching "less" are running
# (ps will return 0 which corresponds to true in that case):
if ps -C less
then
    # send all processes matching "less" the TERM signal:
    killall -TERM less
fi

For more information on available signals, see the table in the man page available via man 7 signal.

Michael Jaros
  • 4,586
  • 1
  • 22
  • 39
  • Thank you for the thorough response! A couple questions: What does '-C' do? Also, for '-TERM', a friend suggested I could use '-INT'. What is the difference, and which would be better? – Kommander Kitten Sep 24 '15 at 18:07
  • Be sure to check out `man ps` for info on `-C`. Both the `INT` and `TERM` signals usually terminate a process, but both can be caught in a signal handler, which is typically used to perform cleanup tasks before termination. `INT` will be sent to the foreground process if you press `Ctrl`+`C` in an interactive terminal session. The `KILL` signal cannot be caught and terminates a process immediately. – Michael Jaros Sep 24 '15 at 18:15
  • And as [John has pointed out](http://stackoverflow.com/a/32768011/4024473), it is not necessary to check if the program is running. – Michael Jaros Sep 24 '15 at 18:16
0

You might try the following code in bash:

#Tell which interpreter will process the code
#!/bin/bash

#Creating a variable to hold program name you want to serach and kill
#mind no-space between variable name value and equals sign
program='less'

#use ps to list all process and grep to search for the specific program name
# redirect the visible text output to /dev/null(linux black hole) since we don't want to see it on screen
ps aux | grep "$program" | grep -v grep > /dev/null

#If the given program is found $? will hold 0, since if successfull grep will return 0
if [ $? -eq 0 ]; then
    #program is running kill it with killall
    killall -9 "$program"
fi
akm
  • 830
  • 6
  • 20