Running a script with top command in the background - linux

I have a script that basically prints that output of top -n1 to a file every second
In its simplest form:
while [ 1 ] ; do
top -n1
sleep 1
done
If I run my secript like:
./my_script.sh > out.log
it runs fine
If I run it in the background:
./my_script.sh > out.log &
Then it give me Stopped(SIGTTOU) error. From other Q/As I found that top is trying to read from the stdin, and when run in the background there is no stdin.
How can I achieve logging of top into a file as a background task?

You need to write top to file, and that in a loop..
#!/bin/bash
while [ 1 ] ; do
top -b -n 1 > top.txt
sleep 1
done
or
#!/bin/bash
while :
do
top -b -n 1 > top.txt
sleep 1
done

Related

Exporting top data to a file

So I've been trying to run the following command to check the consumption by the firefox process.
top -b | grep "firefox"
Now I can see the desired output in terminal for it. But now when I try to export it to a file, I'm not able to.
The command I'm running is:
top -b | grep "firefox" >> filename or top -b | grep "firefox" > filename
Please help.
You need the -n parm for top. For example,
top -b -n 1 | grep "firefox" >> firefox.out
Without -n 1 top will keep processing and will never make it to grep..
From the man page for top:
-n :Number-of-iterations limit as: -n number
Specifies the maximum number of iterations, or frames, top
should produce before ending.
Updated code with a while loop. It will loop forever unless you use
something like cntr variable. Remove the cntr code if you want
continuous monitoring:
#!/bin/sh
#
not_done=1
cntr=0
# Look for process firefox every 1 seconds
while [ "$not_done" -eq 1 ]
do
top -b -n 1 | grep "firefox" >> /tmp/firefox.out
sleep 1
((cntr=cntr+1))
# Addition logic to break out of loop after 10 iterations
if [ "$cntr" -eq 10 ]
then
not_done=0
fi
echo "cntr=$cntr"
done
You have to add in the command the flag -n
Change the number of processes to show. You will be prompted to enter the number.
To take a snapshot of a specific process in top utility, execute command with the PID (-p) flag.
Also i recommed if you want to take snapshots for the process one (PID), and get taking three snapshots of the PID:
top -p 678 -b -n3 > monitoring.out

All the process logs from container

I have a container, it starts with shell script.sh such as:
FROM bash:4.4
COPY script.sh /
COPY process.sh /
CMD ["bash", "/script.sh"]
Here is script.sh:
#!/bin/sh
sh process.sh &
for i in {1..10000}
do
sleep 1
echo "Looping ... number $i"
done
It starts another process by running process.sh script.
Here is the process.sh script:
#!/bin/sh
for i in {1..10}
do
sleep 1
echo "I am from child process ... number $i"
done
Now I want to see all the stdout message. If I go to the directory like /var/lib/docker/containers/container_sha:
I see something like below:
I am from child process ... number {1..10}
Looping ... number 1
Looping ... number 2
Looping ... number 3
Looping ... number 4
Looping ... number 5
Looping ... number 6
.....
It is obvious that, I see only the script.sh output but not process.sh
Why is that? And how can i get all the logs?
Note: docker logs containerName does the same.
{1..10} is bash syntax, and does not expand to anything in sh. So the loop runs once, with the word {1..10} (literally).
You can run process.sh with bash instead of sh
Or if you want/need sh, you could either:
Use a counter:
while c=$((c+1)); [ "$c" -le 10 ]; do
Use a program like seq (not POSIX):
for i in $(seq 10); do
Iterate arguments passed from bash like:
sh process.sh {1..10} &
and in process.sh:
for i do

Script to check if vim is open or another script is running?

I'm making a background script that requires a user to input a certain string (a function) to continue. The script runs fine, but will interrupt anything else that is open in vim or any script that is running. Is there a way I can test in my script if the command line is waiting for input to avoid interrupting something?
I'm running the script enclosed in parenthesis to hide the job completion message, so I'm using (. nightFall &)
Here is the script so far:
#!/bin/bash
# nightFall
clear
text=""
echo "Night begins to fall... Now might be a good time to rest."
while [[ "$text" != "rest" ]]
do
read -p "" text
done
Thank you in advance!
If you launch nightFall from the shell you are monitoring, you can use "ps" with the parent PID to see how many processes are launched by the shell as well:
# bg.sh
for k in `seq 1 15`; do
N=$(ps -ef | grep -sw $PPID | grep -v $$ | wc -l)
(( N -= 2 ))
[ "$N" -eq 0 ] && echo "At prompt"
[ "$N" -ne 0 ] && echo "Child processes: $N"
sleep 1
done
Note that I subtract 2 from N: one for the shell process itself and one for the bg.sh script. The remainder is = how many other child processes does the shell have.
Launch the above script from a shell in background:
bash bg.sh &
Then start any command (for example "sleep 15") and it will detect if you are at the prompt or in a command.

How to make top run in background ? It needs to run and log the output. Not die or zombie up

I am trying to make a script to log the top output to a file in the background for my embedded system. But as soon as I put it in background, it either exits or zombies up. What is the systems problem with running things in background ?
My script
TOP_LOG_FILE=top_log.txt
if [ -e $TOP_LOG_FILE ] ; then
rm $TOP_LOG_FILE
fi
while true
do
echo "##"`date`"##" >> $TOP_LOG_FILE
nohup top -n 1 >> $TOP_LOG_FILE
sleep 1
echo "##xxxxxxxxxxx##" >> $TOP_LOG_FILE
done
I am trying to execute it as
# nohup sh top_log.sh &
[4] 3051559
appending output to nohup.out
#
[4] + Stopped (tty output) nohup sh top_log.sh
and as
[5] 3121193
sh: top_log.sh: cannot execute - No such file or directory
[6] 3121194
#
[6] Done > /dev/null
[5] Done (126) top_log.sh
#
How do I actually get around this behavior?
top -n 1 -b
Tail that in a loop and append to file.
Wrap your loop in a script and launch it from terminal with &.

how to give input to secondary prompt which comes after running a script

$ cat messing_script.sh
#!/bin/sh
ext=`date '+%m%d%H%M'`
host=`hostname`
datalog=/export/admin/imsimta
dire=`date '+%m%d'`
datadir=$datalog/$host/$dire
if [ ! -d $datadir ]
then
mkdir -p $datadir 2> /dev/null
fi
dir1=/opt/sun/comms/messaging64/sbin/
cd $dir1
sleep 5
./imsimta qm
sleep 2
top > $datadir/$ext 2> /dev/null
exit
imsimta, if it spawns a shell, probably supports an option to run a string. Try one of:
./imsimta qm -c "top > $datadir/$ext"
or
./imsimta qm << EOF > $datadir/$ext
top
EOF
The second case is probably easier as echo top | ./imsimta qm, but the heredoc makes it easier to expand as needed. Neither of these is guaranteed to work, and they depend on how imsimta is implemented. I strongly recommend not discarding stderr until you have a working script.

Resources