Pass variable to nawk in bash? - bash

I'm trying to pass a variable to nawk in a bash script, but it's not actually printing the $commentValue variable's contents. Everything works great, except the last part of the printf statement. Thanks!
echo -n "Service Name: "
read serviceName
echo -n "Comment: "
read commentValue
for check in $(grep "CURRENT SERVICE STATE" $nagiosLog |grep -w "$serviceName" | nawk -F": " '{print $2}' |sort -u ) ; do
echo $check | nawk -F";" -v now=$now '{ printf( "[%u]=ACKNOWLEDGE_SVC_PROBLEM;"$1";"$2";2;1;0;admin;$commentValue"\n", now)}' >> $nagiosCommand
done

$commentValue is inside an invocation to nawk, so it is considered as a variable in nawk, not a variable in bash. Since you do not have such a variable in nawk, you won't get anything there. You should first pass the variable "inside" nawk using the -v switch just like you did for the now variable; i.e.:
... | nawk -F";" -v now=$now -v "commentValue=$commentValue"
Note the quotes - they are required in case $commentValue contains whitespace.

Related

grep or sed how to get apachectl -v out in bash

My code is :
#!/bin/bash
strversion=`apache2ctl -v | awk '{print $3}' | sed 's/(Debian)//g;s/Server//g;s/built//g;s/2022-06-09T04:26:43//g'`
echo ${strversion%}
exit 0
i get this:
Apache/2.4.54
but i will have to look
Apache version 2.4.54
That's because the variable expansion is not quoted. An unquoted variable is subject to Word Splitting (and Filename Expansion)
echo "Apache2 - ${strversion%')'}"
# ...^...........................^
See also Security implications of forgetting to quote a variable in bash/POSIX shells
Try the following:
strversion=$(apache2ctl -v | head -1 | awk -F '[ /]' '{printf "%s version %s", $3, $4}')

grep not finding name in text file

text file:
Annemie;014588529
Stefaan;011802367
Jan;032569874
Hans;015253694
Trying to find the phonenumber by name but it doesn't display anything
echo -n ""
read name
number=`grep '$name' numbers.txt | awk -F';' '{print $2}'`
echo "$number"
Single quotes avoid expansion of variables.
You are searching the string $name inside numbers.txt.
Try this instead:
echo -n ""
read name
number=$(grep "$name" numbers.txt | awk -F';' '{print $2}')
echo "$number"
or even better to reduce the pipe (awk can perform the grep directly):
echo -n ""
read name
number=$(awk -F';' -v name="$name" '$1 ~ name {print $2}' numbers.txt)
echo "$number"
Single quotes prevent the shell variable name to expand.
Try like this:
#!/bin/sh
read -p "Enter name: " name
number=$(grep -F "$name" numbers.txt | awk -F';' '{print $2}')
echo "$name => $number"
Also, you should use -F for fixed string grepping, avoid old-style backtick command substitution, and use $(..) instead. If you wish, you can use -p for read prompt (in POSIX shells, sh/bash included).

Adding value to global variable in a subshell is not working

I am trying to get the total disk usage of my machine. Below is the script code:
#!/bin/sh
totalUsage=0
diskUse(){
df -H | grep -vE '^Filesystem|cdrom' | awk '{ print $5 " " $1 }' | while read output;
do
diskUsage=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
totalUsage=$((totalUsage+diskUsage))
done
}
diskUse
echo $totalUsage
While totalUsage is a global variable, I have tried to sum the individual disk usage to totalUsage in the line:
totalUsage=$((totalUsage+diskUsage))
An echo of totalUsage between do and done shows the correct value,
but when I try to echo it after my call diskUse, it stills prints a 0
Can you please help me, what is wrong here?
The variable totalUsage in a sub-shell doesn't change the value in the parent shell.
Since you tagged bash, you can use here string to modify your loop:
#!/bin/bash
totalUsage=0
diskUse(){
while read output;
do
diskUsage=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
totalUsage=$((totalUsage+diskUsage))
done <<<"$(df -H | grep -vE '^Filesystem|cdrom' | awk '{ print $5 " " $1 }')"
}
diskUse
echo $totalUsage
I suggest to insert
shopt -s lastpipe
as new line after
#!/bin/bash
From man bash:
lastpipe: If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment.

"awk" and "cut" behaving differently in bash script

I'm trying to cut the below string starting on the single quote:
name1=O'Reilly
so it leaves:
name2=Reilly
That's easy from the command line with the following commands:
echo $name | cut -d\' -f
echo $name | awk -F\' '{print $2}'
However when I run these commands from a script the string remains unaltered. I've been looking into problems with using single quotes as a delimiter but couldn't find anything. Any way to solve this issue?
That does not change the string the variable expands to, it just outputs the result of string manipulation.
If you want to create a new reference for variable name, use command substitution to save the result of cut/awk operation as variable name:
% name="O'Reilly"
% echo "$name" | awk -F\' '{print $2}'
Reilly
% name=$(echo "$name" | awk -F\' '{print $2}')
% echo "$name"
Reilly
On the other hand, if you want to declare the input as one (name1), and save the output as a different variable (name2):
% name1="O'Reilly"
% name2=$(echo "$name1" | awk -F\' '{print $2}')
% echo "$name2"
Reilly
This might be easier to get using Parameter expansion though:
$ name="O'Reilly"
$ echo "${name#*\'}"
Reilly
$ name="${name#*\'}"
$ echo "$name"
Reilly

Problem with backticks in shellscript

I am having a problem getting my shellscript working using backticks. Here is an example version of the script I am having an issue with:
#!/bin/sh
ECHO_TEXT="Echo this"
ECHO_CMD="echo ${ECHO_TEXT} | awk -F' ' '{print \$1}'"
result=`${ECHO_CMD}`;
echo $result;
result=`echo ${ECHO_TEXT} | awk -F' ' '{print \$1}'`;
echo $result;
The output of this script is:
sh-3.2$ ./test.sh
Echo this | awk -F' ' '{print $1}'
Echo
Why does the first backtick using a variable for the command not actually execute the full command but only returns the output of the first command along with the second command? I am missing something in order to get the first backtick to execute the command?
You need to use eval to get it working
result=`eval ${ECHO_CMD}`;
in place of
result=`${ECHO_CMD}`;
Without eval
${ECHO_TEXT} | awk -F' ' '{print \$1}
which will be expanded to
Echo this | awk -F' ' '{print \$1}
will be treated as argument to echo and will be output verbatim. With eval that line will actually be run.
You Hi,
you need to know eval command.
See :
#!/bin/sh
ECHO_TEXT="Echo this"
ECHO_CMD="echo ${ECHO_TEXT} | awk -F' ' '{print \$1}'"
result="`eval ${ECHO_CMD}`"
echo "$result"
result="`echo ${ECHO_TEXT} | awk -F' ' '{print $1}'`"
echo "$result"
Take a look to the doc :
help eval
In your first example echo is parsing the parameters - the shell never sees them. In the second example it works because the shell is doing the parsing and knows what to do with a pipe. If you change ECHO_CMD to be "bash echo ..." it will work.
Bash is escaping your command for you. Try
ECHO_TEXT="Echo this"
ECHO_CMD='echo ${ECHO_TEXT} | awk -F" " "'"{print \$1}"'"'
result=`${ECHO_CMD}`;
echo $result;
result=`echo ${ECHO_TEXT} | awk -F' ' '{print \$1}'`;
echo $result;
Or even better, try set -x on the first line, so you see what bash is doing

Resources