Bash mail doesn't preserve new-line from grep - bash

I am trying to grep something in the script and sending it as an email.The new line in the grep output is not being reflected in the email even if I use double quotes for the variable everywhere. Can someone point out the mistake or provide a workaround? Thanks.
Note: the \n added in the script are reflected but I want the grep output stored in "${Err_state}" separated by a newline.
Code:
Err_state=`qstat | grep ${PP_Jname}* | grep 'Eqw' | cut -f3 -d' '`
if [ ! -z "${Err_state}" ]; then
err_msg="PostProcessing failed for :\n $Err_state \n\n Pls look into logs \n"
SendEmail "$err_msg"
function SendEmail() {
err_msg="${1}"
err_msg="\n\nERROR: \n"${err_msg}"\n\n Terminating script...\n";
`echo -e "ERROR generated AutoProcess.sh:\n "${err_msg}"\n" | /bin/mail -s "OS_AutoProcess_wrapper.sh: ERROR" ${email_address}`
exit 1;
}

Related

grep multiple pattern from read input

so i made a bash script the greps the name of the host on the redirected file. However, there are hosts that are named either with "-" or "_"
GTR_SRV123_EST
GTR-SRV123-EST
Right now, what i did was, grep just a portion of the FQDN, like SRV123
Is there a way i can grep the host even if i just put the FQDN GTR_SRV123_EST and it will still matched this GTR-SRV123-EST.
i have a prompt that ask for the hostname:
echo -n "Please enter the host: "
read $host
grep -i $host ${temp}/*
update:
so had it working with the help of Juan's command. However, the directory path is displayed on the output. How can i get rid of it.
/export/home/aa12s/GLB-TXU/temp/
Current output:
/export/home/aa12s/GLB-TXU/temp/GBL-ASA-A:100022FBC0D00038 gbl-asa-a-mode1 5005076801103673 active gbl-ac-wbg02
Desired output:
GBL-ASA-A:100022FBC0D00038 gbl-asa-a-mode1 5005076801103673 active gbl-ac-wbg02
Command:
grep -iE "$(echo $host| awk -F '/export/home/aa12s/GLB-TXU/temp/' '{$2=$1;a=gsub(/_/, "-",$2); print $1"|"$2}' 2>/dev/null)" ${temp}/*
Edit your pattern.
echo -n "Please enter the host: "
read host # Edit: not $host
host="${host//[_-]/\[_-\]}" # turn either into a *check* for either
grep -i "$host" ${temp}/*
Kind of hacky but give this a try:
grep -Ei "$(echo $host| awk '{$2=$1;gsub(/_/, "-",$2);print $1"|"$2}' 2>/dev/null)" ${temp}/*
To get rid of filepaths:
grep -iE "$(echo $host| awk '{$2=$1;gsub(/_/, "-",$2);print $1"|"$2}' 2>/dev/null)" ${temp}/* 2>/dev/null|awk -F \/ '{print $NF}'
NOTE: Slashes must NOT be present in the file content.
If there is no host name with both _ and - below will work.
Entered host contains only _
grep -iE $(echo $host | tr "_" "-")\|$host ${temp}/*
Entered host contains only -
grep -iE $(echo $host | tr "-" "_")\|$host ${temp}/*
Entered host contains both _ and -
grep -iE $(echo $host | tr "_" "-")\|$(echo $host | tr "-" "_")\|$host ${temp}/*
You can use backreference :
([_-]) : capture either _ ou - in group 1
\1 : reference group 1
try this command :
grep -iE "([_-])$host\1" ${temp}/*
https://regex101.com/r/uH5SHC/1/
Wiyh host=SRV123, you will capture :
GTR_SRV123_EST
GTR-SRV123-EST
and not
GTR_SRV123-EST

Duplicate the output of bash script

Below is the piece of code of my bash script, I want to get duplicate output of that script.
This is how my script runs
#bash check_script -a used_memory
Output is: used_memory: 812632
Desired Output: used_memory: 812632 | used_memory: 812632
get_vals() {
metrics=`command -h $hostname -p $port -a $pass info | grep -w $opt_var | cut -d ':' -f2 > ${filename}`
}
output() {
get_vals
if [ -s ${filename} ];
then
val1=`cat ${filename}`
echo "$opt_var: $val1"
# rm $filename;
exit $ST_OK;
else
echo "Parameter not found"
exit $ST_UK
fi
}
But when i used echo "$opt_var: $val1 | $opt_var: $val1" the output become: | used_memory: 812632
$opt_var is an argument.
I had a similar problem when capturing results from cat with Windows-formatted text files. One way to circumvent this issue is to pipe your result to dos2unix, e.g.:
val1=`cat ${filename} | dos2unix`
Also, if you want to duplicate lines, you can use sed:
sed 's/^\(.*\)$/\1 | \1/'
Then pipe it to your echo command:
echo "$opt_var: $val1" | sed 's/^\(.*\)$/\1 | \1/'
The sed expression works like that:
's/<before>/<after>/' means that you want to substitute <before> with <after>
on the <before> side: ^.*$ is a regular expression meaning you get the entire line, ^\(.*\)$ is basically the same regex but you get the entire line and you capture everything (capturing is performed inside the \(\) expression)
on the <after> side: \1 | \1 means you write the 1st captured expression (\1), then the space character, then the pipe character, then the space character and then the 1st captured expression again
So it captures your entire line and duplicates it with a "|" separator in the middle.

Why shell report "command not found" while using cat?

I'm processing a file by line, so my shell script is this:
check_vm_connectivity()
{
$res=`cat temp.txt` # this is line 10
i=0
for line in "$res"
do
i=$i+1
if [[ $i -gt 3 ]] ; then
continue
fi
echo "${line}"
done
}
The temp.txt is this:
+--------------------------------------+
| ID |
+--------------------------------------+
| cb91a52f-f0dd-443a-adfe-84c5c685d9b3 |
| 184564aa-9a7d-48ef-b8f0-ff9d51987e71 |
| f01f9739-c7a7-404c-8789-4e3e2edf314e |
| 825925cc-a816-4434-8b4b-a75301ddaefd |
when I run script, report this:
vm_connectivity.sh: line 10: =+--------------------------------------+: command not found
Why? How to fix this bug? Thank you~
May i ask why you are using
$res=`cat temp.txt`?
shouldn't it be
res=`cat temp.txt`
variables in a shell are set with var= rather than $var=
res is empty when you're entering the function, so that line
expands to the empty string, followed by an equals sign,
followed by the contents of temp.txt. The shell then interprets
that, and since a command is terminated by a newline, and
=+--------------------------------------+ has the syntax
of a command, rather than anything else, the shell tries to
run it as such.
You want: res=$(cat temp.txt)
However, it looks like you're trying to output
the first three lines, in which case just
do
head -n3 temp.txt
though from the looks of it, you probably want all except the first three
lines:
tail -n +4 temp.txt
and if you're looking for just the uuids:
tail -n +4 temp.txt | awk '{print $2}'

Bash script error with sed command, integer expression expected

I can't figure out how to fix this error on my if statement ": integer expression expected0: [: 4". I have seem and read many similar questions on here, but none seem to fix this script!
I have the command enclosed in backticks:
today=`wget -q -O- "$URL" | sed -n "/$dateToday/ {n;n;n;n;p;q;}" | sed 's/<\/\?[^>]\+>//g; s/&deg\;//g; ' | tr -d ' ' `
I have tried using $() instead of backticks.
The printf works fine but I assume when it gets to the comparison operators it thinks its a string.
If I use "/bin/sh" there is no terminal error message, but it does not fix the issue as I need this for a cron job and the above error is then printed in the email body.
Full script below:
#!/bin/bash
# Script to send weather warnings via email when there is a risk of freezing
URL='http://www.accuweather.com/en/gb/tormarton/gl9-1/daily-weather-forecast/708507'
dateToday=`date +"%b %-d"` # gets Date in 'Mmm d' format
# Get todays temperature
today=`wget -q -O- "$URL" | sed -n "/$dateToday/ {n;n;n;n;p;q;}" | sed 's/<\/\?[^>]\+>//g; s/&deg\;//g; ' | tr -d ' ' `
# if temperatures <= to the warning temperature send email alert
if [ "$today" -le 10 ] ; then
printf "Current temperature: $today\n" | mail -s "Weather warning forecast - Take precautions" address#mydomain.com
fi
Try this whitespace trimming:
today=`wget -q -O- "$URL" | sed -n "/$dateToday/ {n;n;n;n;p;q;}" | sed 's/<\/\?[^>]\+>//g; s/&deg\;//g; ' | tr -d '[:space:]'`
Full script:
#!/bin/bash
# Script to send weather warnings via email when there is a risk of freezing
URL='http://www.accuweather.com/en/gb/tormarton/gl9-1/daily-weather-forecast/708507'
dateToday=`date +"%b %-d"` # gets Date in 'Mmm d' format
# Get todays temperature
today=`wget -q -O- "$URL" | sed -n "/$dateToday/ {n;n;n;n;p;q;}" | sed 's/<\/\?[^>]\+>//g; s/&deg\;//g; ' | tr -d '[:space:]'`
# if temperatures <= to the warning temperature send email alert
if [ "$today" -le 10 ] ; then
printf "Current temperature: $today\n" | mail -s "Weather warning forecast - Take precautions" address#mydomain.com
fi

How to pass a variable space character in tr command

In a shell script I would like to replace all underscore characters with a blank space in a function that use tr but a receive an error because I don't know of to pass a space in a variable to tr
function sanitizeDirName() {
local name=$1
local f=$2
local r=$3
echo ${name##*/} | grep -E -o $re | tr $f $r
}
sanitizeDirName "~/test_1" "_" " "
Thank you
You need to quote your variables, since they are populated from user input and could have whitespaces or metacharacters (as tripleee pointed out in the comments):
echo ${name##*/} | grep -E -o "$re" | tr "$f" "$r"
If you want to remove _ then you might want to use the -d flag
echo ${name##*/} | grep -E -o $re | tr -d $f

Resources