I’m not used to writing code in bash but I’m self teaching myself. I’m trying to create a script that will query info from the process list. I’ve done that but I want to take it further and make it so:
- The script runs with one set of commands if A OS is present.
- The script runs with a different set of commands if B OS is present.
Here’s what I have so far. It works on my Centos distro but won’t work on my Ubuntu. Any help is greatly appreciated.
#!/bin/bash
pid=$(ps -eo pmem,pid | sort -nr -k 1 | cut -d " " -f 2 | head -1)
howmany=$(lsof -l -n -p $pid | wc -l)
nameofprocess=$(ps -eo pmem,fname | sort -nr -k 1 | cut -d " " -f 2 | head -1)
percent=$(ps -eo pmem,pid,fname | sort -k 1 -nr | head -1 | cut -d " " -f 1)
lsof -l -n -p $pid > ~/`date "+%Y-%m-%d-%H%M"`.process.log 2>&1
echo " "
echo "$nameofprocess has $howmany files open, and is using $percent"%" of memory."
echo "-----------------------------------"
echo "A log has been created in your home directory"
echo "-----------------------------------"
echo " "
echo ""$USER", do you want to terminate? (y/n)"
read yn
case $yn in
[yY] | [yY][Ee][Ss] )
kill -15 $pid
;;
[nN] | [n|N][O|o] )
echo "Not killing. Powering down."
echo "......."
sleep 2
;;
*) echo "Does not compute"
;;
esac
Here’s my version of your script. It works with Ubuntu and Debian. It’s probably safer than yours in some regards (I clearly had a bug in yours when a process takes more than 10% of memory, due to your awkward
cut). Moreover, yourpsare not “atomic”, so things can change between different calls ofps.First, check that your version of
pshas the--sortflag and thehoption:--sort=-pmemtellspsto sort wrt decreasingpmemhtellspsto not show any headerAll this is given to the
readbash builtin, which reads space-separated fields, here the fieldspmem,pid,fnameand puts these values in the corresponding variablespercent,pidandnameofprocess.The
mapfilecommand reads standard input (here the output of thelsofcommand) and puts each line in an array field. The size of this array is computed by the linehowmany=${#openfiles[@]}. The output oflsof, as stored in the arrayopenfilesis output to the corresponing file.Then, instead of the many
echos, we use acat <<EOF, and then thereadis use with the-p(prompt) option.I don’t know if this really answers your question, but at least, you have a well-written bash script, with less multiple useless command calls (until your
casestatement, you called 16 processes, I only called 4). Moreover, after the firstpscall, things can change in your script (even though it’s very unlikely to happen), not in mine.You might also like the following which doesn’t put the output of
lsofin an array, but uses an extrawccommand: