Machine data not displaying output every 15 Seconds - bash

The following script is meant to output "vmstat" for example every 15 seconds, but for some reason it only does this if there's activity or when I kill the script, in other cases it just sits there.
#!/bin/bash
#!/bin/sh
ps -ef | grep -v grep | grep "vmstat 15" | awk '{ print $2 }' | xargs kill
ps -ef | grep -v grep | grep "iostat 15" | awk '{ print $2 }' | xargs kill
ps -ef | grep -v grep | grep "mpstat 15" | awk '{ print $2 }' | xargs kill
today=`date +%Y-%m-%d.%H:%M:%S`
find /var/log/ -name data_collection -type d -exec mv /var/log/data_collection /home/Beer/"data_collection_${today}" \;
mkdir -p /var/log/data_collection
vmstat 15 | /home/Beer/./addtimestamp.pl > /var/log/data_collection/vm_stat &
iostat 15 | /home/Beer/./addtimestamp.pl > /var/log/data_collection/ios_stat &
mpstat 15 | /home/Beer/./addtimestamp.pl > /var/log/data_collection/mp_stat &
Im guessing the '&' symbol at the end has something to do with this, I only did this so I can execute each command at once.

Since feature requests to mark a comment as an answer remain declined, I copy the above solution here.
What is in addtimestamp.pl? It could be that it's buffering input, and not flushing every time it reads something. – Diego Basch
#DiegoBasch that's exactly correct, I just added a '$|=1;' to the Perl script now and it started to work, basically setting the it to line buffer. Ill add the answer. – I AM L

Related

Bash command output as variable returning /bin/bash

When I run the following command in my terminal I get the expected value :
delayedjobs="$(ps aux | grep delayed_job | grep -v grep | awk '{print $11}' | awk 'END{print}' | cut -d "." -f2)" && echo $delayedjobs
However, when I run the following script, the variable returns as "/bin/bash"
#!/bin/bash
delayedjobs="$(ps aux | grep delayed_job | grep -v grep | awk '{print $11}' | awk 'END{print}' | cut -d "." -f2)"
echo ${delayedjobs}
root#central:/home/tblake# ./myscript.sh
/bin/bash
Can anyone explain this? Im having a heck of a time figuring this out.
Has you named your skript delayed_job ? Your script detect his own process.

Killing parent process only, not both child and parent in bash

I'm trying to kill process by name. It's supposed to kill children processes first then the parent later but I only get parent killed. Help needed please. EDIT: SOLVED
Please try it this way:
PID=$(ps -aef | grep `whoami` | grep $argument | grep -v grep | grep -v $$ | awk '{print $2}'
for x in ${PID[#]}; do
CPID=$(ps -aef | grep `whoami` | grep $PID | grep -v grep | grep -v $$ | awk '{print $3}'
for y in ${CPID[#]}; do
kill $y
done
kill $x
done

simple bash script not terminating

I have very simple bash script:
#!/bin/bash
echo -n "A: ";
grep -v ">" | grep -o "A" $1 | wc -l;
I type
./script.sh 1.fasta
I got
A: 131
But the curcor is still blicking and my script is not finishing. What's wrong here?
Thank you.
This is the problem command:
grep -v ">" | grep -o "A" $1 | wc -l;
Since first command grep -v ">" is waiting for the input from STDIN as you haven't supplied any file to be searched by grep.
PS: Even grep -o "A" $1 is also problem since piped command will take input from output of the previous command in chain.
Probably you meant:
grep -v ">" "$1" | grep -o "A" | wc -l
Your first grep does not have a file argument so it will read from standard input:
grep -v ">" | grep -o "A" $1 | wc -l;
(read stdin) (read $1)
The reason why you get the 131 is because your second grep does have a file argument so it's getting all lines in $1 that have an A. However it's still waiting around for the end of the first grep to finish (which you can do with CTRL-D).
What you probably wanted to do is this:
grep -v ">" "$1" | grep -o "A" | wc -l
This will find all lines in $1 without a >, then all occurrences of A in that, counting them.

Count the number of processes and kill them

I am writing a script to kill all instances of the same process. As it is going to be used on Linux, AIX, HP-UX and Solaris, I need to use only built-in bash (sh) functions. That's why killall, pkill, etc. don't work for me.
Once there is only one instance of a process it should be just killed in traditional way:
kill -TERM `ps -ef | grep -v grep | grep $process | awk '{print $2}'`
However sometimes the program has extra instances running and that's why ps -ef | … returns more than one PID. That needs to be reported.
example:
bash-3.2$ ps -ef | grep -v grep | grep perl | awk '{print $2}'
5267
5268
5269
5270
5271
My thought was to store those values in a temporary variable and then send kill signal to each in a for loop.
bash-3.2$ tmp=`ps -ef | grep -v grep | grep perl | awk '{print $2}'`
bash-3.2$ echo $tmp
5267 5268 5269 5270 5271
However I still need the information if such a case occurred (how many instances were present).
It seems I need to check the whole string stored in the tmp variable and maybe count spaces?
Anyway the questions reduces to how to check how many values the $tmp variable stores?
For maximum portability and reliability, use -A (POSIX synonym of -e) and a custom format with -o rather than -f.
Your filtering of the output of ps is brittle: it may match other processes. You've had to exclude the grep process, and you may need to exclude your script as well, and there may be other completely innocent processes caught in the fray (such as your script itself) because their command line happens to contain $process as a substring. Make your filtering as strict as possible. With ps -o pid= -o comm=, you get just two columns (PID and command without arguments) with no header.
You don't need to use a loop to do the killing, kill accepts multiple arguments. For the counting, let the shell do it: you have a whitespace-separated list of numbers, to let the shell do the word splitting (with $(…) outside quotes) and count the number of resulting words ($#).
count_and_kill_processes () {
set -- $(ps -A -o pid= -o comm= |
awk -v "name=$process" '$2 == name {print $1}')
count=$#
if [ $# -ne 0 ]; then kill "$#"; fi
}
count_and_kill_processes foo
# now the number of killed processes is in $count
If your shell is bash or ksh on all machines, you can use an array.
pids=($(ps -A -o pid= -o comm= |
awk -v "name=$process" '$2 == name {print $1}') )
if [[ $# -ne 0 ]]; then kill "$#"; fi
# the number of killed processes is ${#pids}
use xargs:
ps aux | grep -ie perl | awk '{print $2}' | xargs kill -9
You can use a loop which should work in both cases:
for pid in $(ps -ef | grep -v grep | grep $process | awk '{print $2}'); do
echo $pid
done
Or count the number of matches:
if [ $(ps -ef | grep -v grep | grep $process | awk '{print $2}' | wc -l) -gt 1 ]
then
# more than one
fi

Bash script giving undesired output

I am facing with the following bash script:
#! /bin/bash
processname=$1
x=1
while [ $x -eq 1 ] ; do
ps -el | grep $processname | awk ' {if($15!="grep") print "The memory consumed by the process " $15 " is = "$9} ' >> out.log
sleep 30
done
and I am running this with :
$ ./myscript.sh Firefox
but when i see the output in the file, apart from the firefox process i am also getting information for /bin/bash process
The memory consumed by the process /Applications/Firefox.app/Contents/MacOS/firefox is = 911328
The memory consumed by the process /bin/bash is = 768
Can some one help me with this so that I only want to get information related to Firefox process and nothing else(/bin.bash etc)
The common trick is to change grep Firefox to grep [F]irefox. In this case, you can achieve it with
ps | grep '['${processname:0:1}']'${processname:1}
This is normal and because the $processname is Firefox. Since your command also monitors it, there is a process that uses it.
For example, try ps -el | grep Firefox and you will get two process lines matching (if you have one instance of Firefox running), one is Firefox, the other is the grep command looking for Firefox.
Piping your output in grep -v /bin/bash' should solve this. Eg:
ps -el | grep $processname | awk ...
becomes:
ps -el | grep $processname | grep -v 'grep' | awk ...
You calling
ps -el | grep $processname | awk ' {if($15!="grep") print "The memory consumed by the process " $15 " is = "$9} '
This means that you run awk and connect it's input with output of grep. Then grep is started and gets output of ps -el as input.
At the moment when bash will start ps you have grep and awk running.
Solution: run ps -el and remember it's output. Then run grep and awk. It should be like this:
ps -el > ps.tmp
grep $processname ps.tmp | awk ' {if($15!="grep") print "The memory consumed by the process " $15 " is = "$9} ' >> out.log
Probably this could be done without using tmp file. Like TMP=$(ps -el). But I don't know how to run grep filter on variable

Resources