Junk characters being printed with tee command - linux

Script I'm utilizing is below:
#!/bin/bash
lla=$(top -n 1 | grep "load average" | awk '{print $13,$14,$15}')
mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
now=`date`
cur_time=$(echo $now | awk '{print $4}')
for i in {1..60}
do
echo "System Performance Statistics at: "$cur_time | tee -a hp.txt
echo "Linux Load Average: "$lla | tee -a hp.txt
echo "Memory Usage: "$mem_usage | tee -a hp.txt
echo "" | tee -a hp.txt
sleep 3
done
Results:
System Performance Statistics at: 19:00:29
Linux Load Average: 0.13, 0.11, 0.14^[(B^[[m^[[39;49m^[[K
Memory Usage: 82.7672
Standard out isn't showing any garbage characters at all. What do I need to change?

Added -b to top command and it works.
From man top:
-b :Batch-mode operation
Starts top in Batch mode, which could be useful for sending output
from top to other programs or to a file. In this mode, top will not
accept input and runs until the iterations limit you've set with the
`-n' command-line option or until killed.

Related

Unable to use grep for a command and excecute the shell script?

I have created a shell script to execute 5 commands from a file called elist.txt
ps -ef | grep user | grep 'process -s 9000' | cut -c -15 | cut -c 10-
ps -ef | grep user | grep 'process -s 9001' | cut -c -15 | cut -c 10-
ps -ef | grep user | grep 'process -s 9002' | cut -c -15 | cut -c 10-
ps -ef | grep user | grep 'process -s 9003' | cut -c -15 | cut -c 10-
The shell script is as follows
export PATH="/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/user/.local/bin:/home/user/bin"
input="/home/user/script/list.txt"
while IFS= read -r line
do
echo $($line)
done < "$input"
output:
error: garbage option
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
For more details see ps(1).
You can do this too. People usually do not recommend to use eval at all.
export PATH="/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/user/.local/bin:/home/user/bin"
input="/home/user/script/list.txt"
while IFS= read -r line
do
bash -c "$line"
done < "$input"
Regards!
I would use this script with eval which is a similar solution described in this answer https://stackoverflow.com/a/6002329/6778826
export PATH="/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/user/.local/bin:/home/user/bin"
input="/home/user/script/list.txt"
while read -r line
do
eval "$line"
done <$input

Run Shell Script without Command line Arguments in Linux

I am trying to run a Shell Script, but got stuck on an issue. I want to Run certain set of code when i supply arguments and remaining should run, if i dont pass any argument.
Part which i want to run with args:
#!/bin/bash
while [[ "$1" != "" ]]; do
case "$1" in
-c ) cat /proc/cpuinfo | grep cores
;;
-d ) fdisk -l | grep Disk | awk '{print $1,$2,$3,$4}' #fdisk -l 2> /dev/null | grep Disk | grep -v identifier
;;
esac
shift
done
and this part without any args
while [[ $# -eq 0 ]]; do
echo PART 2 $#
cat /proc/cpuinfo | grep cores
fdisk -l | grep Disk | awk '{print $1,$2,$3,$4}' #fdisk -l 2> /dev/null | grep Disk | grep -v identifier
break
done
I believe issue is with the Loop condition, but i cant understand what?
if [[ -n "$1" ]]; then
#
# "$1" is not empty. This is the part which runs when one or more
# arguments are supplied.
#
while [[ -n "$1" ]]; do
case "$1" in
-c) cat /proc/cpuinfo | grep cores
;;
-d) LC_ALL=C fdisk -l | grep Disk | awk '{print $1,$2,$3,$4}'
#LC_ALL=C fdisk -l 2> /dev/null | grep Disk | grep -v identifier
;;
esac
shift
done
exit
fi
#
# "$1" is empty. The following code runs when no arguments are supplied.
#
echo PART 2 $#
cat /proc/cpuinfo | grep cores
LC_ALL=C fdisk -l | grep Disk | awk '{print $1,$2,$3,$4}'
#LC_ALL=C fdisk -l 2> /dev/null | grep Disk | grep -v identifier
Note 1: Not tested.
Note 2: Whenever you feel a need to parse the output of a command looking for certain words or phrases it is a good idea to run the command in the default locale by prefixing it with LC_ALL=C. In this way you won't be surprised when in a French locale, for example, fdisk says Disque...

Custom Splash Screen on Login RHEL

I was wondering if it was possible to display a splash screen when you log into an account in a RHEL server? not via /etc/motd as that is global but to an specific user.
Ideally I would like to show uptime and services running when a service account is logged in.
Kind regards,
R,
Check manual page for sshd_config. There is Banner option and you can customize it per-user.
Also motd can be dynamic. Check this answer on ServerFault:
However, it's possible to execute a shell script at login time that will have the same result. This is usually achieved by adapting the /etc/profile script that is executed each time a user logs in. A useful practice is to put the command you want to be executed in a script named /etc/motd.sh and call this script from /etc/profile, usually at about the end of it.
You can modify the target user's .Bash_profile and put inside of it the commands to show stuffs like cpuinfo meminfo...
Here's an example.
let upSeconds="$(/usr/bin/cut -d. -f1 /proc/uptime)"
let secs=$((${upSeconds}%60))
let mins=$((${upSeconds}/60%60))
let hours=$((${upSeconds}/3600%24))
let days=$((${upSeconds}/86400))
UPTIME=`printf "%d days, %02dh%02dm%02ds" "$days" "$hours" "$mins" "$secs"`
echo "`date +"%A, %e %B %Y, %r"`
`uname -srmo`
Uptime.............: ${UPTIME}
Memory.............: `cat /proc/meminfo | grep MemFree | awk {'print $2'}`kB (Free) / `cat /proc/meminfo | grep MemTotal | awk {'print $2'}`kB (Total)
Load Averages......: ${one}, ${five}, ${fifteen} (1, 5, 15 min)
Running Processes..: `ps ax | wc -l | tr -d " "`
IP Addresses.......: `/sbin/ifconfig eth0 | /bin/grep "inet addr" | /usr/bin/cut -d ":" -f 2 | /usr/bin/cut -d " " -f 1`"
this example will show you something like this:
Friday, 15 April 2016, 04:47:41 PM
Linux 2.6.18-128.el5 x86_64 GNU/Linux
Uptime.............: 2 days, 02h05m06s
Memory.............: 1805240kB (Free) / 4037732kB (Total)
Load Averages......: 0.77, 0.74, 0.89 (1, 5, 15 min)
Running Processes..: 230
IP Addresses.......: X.X.X.X
ENJOY!

Want to make a shell script that

Want to make a shell script that runs a program, then if the memory reach over specific limit(example 3gb), it shutdown and restart itself.
While running
If memory > 3gb
Shutdown
Restart
MEM_LIMIT=3145728
MEM_USED=$(cat /proc/meminfo | grep "MemFree" | awk -F' ' '{print $2}' | tr -d " ")
if [ $MEM_USED -ge $MEM_LIMIT ]
then
reboot 0
fi

Shell script for logging cpu and memory usage of a linux process

I am looking for a way to log and graphically display cpu and RAM usage of linux processes over time. Since I couldn't find a simple tool to so (I tried zabbix and munin but installation failed) I started writing a shell script to do so
The script file parses the output of top command through awk and logs into a csv file. It
Figures out the pid of the processes through ps command
Uses top and awk to log cpu and memory usage.
Here is how the script looks like
#!/bin/sh
#A script to log the cpu and memory usage of linux processes namely - redis, logstash, elasticsearch and kibana
REDIS_PID=$(ps -ef | grep redis | grep -v grep | awk '{print $2}')
LOGSTASH_PID=$(ps -ef | grep logstash | grep -v grep | awk '{print $2}')
ELASTICSEARCH_PID=$(ps -ef | grep elasticsearch | grep -v grep | awk '{print $2}')
KIBANA_PID=$(ps -ef | grep kibana | grep -v grep | awk '{print $2}')
LOG_FILE=/var/log/user/usage.log
echo $LOG_FILE
top -b | awk -v redis="$REDIS_PID" -v logstash="$LOGSTASH_PID" '/redis|logstash/ {print $1","$9","$10","$12}'
How do I
Print the resource usage for multiple processes. Specifying multiple
variables in the awk pattern is not working. It prints the usage for
the first pid (redis in the above script)
Print current timestamp when printing the resource details (through date +"%T")
Print the process name along with the resource usage. Redis, Logstash, ElasticSearch or Kibana in the above case
Redirect the above commands output to a log file. I tried > $LOG_FILE but it didn't work.
Thoughts/Inputs?
Thanks in advance.
To figure out PIDs you can simplify your script greatly using pgrep:
REDIS_PID=$(pgrep -f redis)
LOGSTASH_PID=$(pgrep -f logstash)
ELASTICSEARCH_PID=$(pgrep -f elasticsearch)
KIBANA_PID=$(pgrep -f kibana)
EDIT: Sorry had to leave for some work and couldn't provide the full answer.
In order to capture top's output use following script:
while :; do
top -n 1 -b | awk -v redis="$REDIS_PID" -v logstash="$LOGSTASH_PID"
'$1 == redis || $1 == logstash {print $1","$9","$10","$12}' >> $LOG_FILE
sleep 3
done

Resources