Variable comparison in bash - linux

I am trying to find out whether disk is SSD or HDD using bash script.
logical_name="/dev/sda"
type=""
disk=$(basename $logical_name)
x=`cat $filename | grep "${disk}" | awk '{print $2}'`
if [ ! -z "$x" ]
then
if [ "$x" = "0" ]
then
type="SSD"
fi
if [ "$x" = "1" ]
then
type="HDD"
fi
fi
echo $type
Value of x is correct, 0 or 1. But after comparison, it's not assigning any value to variable type. It prints as empty. Can anyone point out what am I doing wrong here?
More information:
$filename is a file that contains output of sudo lsblk -d -o name,rota
NAME ROTA
sda 1
sdd 1
sdc 0

While I don't see any problem with the posted code, following would be a more simplified and maintainable version for doing the same.
DISK_NAMES=(SSD HDD) # names are resolved by index
filename="in1.txt"
logical_name="/dev/sda"
disk="$(basename $logical_name)"
x="$(sed -n 's/'$disk' *\([0-9]*\)/\1/p' $filename)"
# check if $x is empty here, if required
echo "$x -> ${DISK_NAMES[$x]}"

The lsblk command lets you specify a device, so you shouldn't have to grep through the lsblk output to find the device you're interested in. This also means you don't need the name column. Plus you can disable the header with -n, and the -r option (raw output) gets rid of the leading and trailing whitespace:
> hdtype() { lsblk -drno rota "$1" | sed 's/1/HDD/;s/0/SSD/'; }
> hdtype /dev/sda
HDD
As far as why your code isn't working, I'm not sure. It worked just fine in my bash terminal.

Related

Bash Script If else statement not capturing the threshold

I am currently attempting to capture the threshold in my script, but it's reading as everything is "above the threshold".
I know that the directory is at 48G and I set the threshold to 99G, expecting "Not above threshold" to appear after running the script. Please advise and see script below for reference...
#!/bin/bash
threshold=99
if [ "du -sh /data | cut -f1 | grep -Eo [0-9]+ -gt $threshold" ]
then
echo "Reducing file with a further commands. File is above the threshold..."
else
echo "Not above threshold..."
fi
You want:
if [ "$(du -sh /data | cut -f1 | grep -Eo '[0-9]+')" -gt "$threshold" ]
Double quotes create a literal string, you need to use $(command) to substitute the output of a command into the command line.
Using --threshold option
value=99
THRESHOLD=$(du -sh --threshold="${value}"G /data)
if [ -n "$THRESHOLD" ]
then
echo "Reducing file with a further commands. File is above the threshold..."
else
echo "Not above threshold..."
fi

Linux command to check the count returned from grep command is greater than specific no

Iam new to linux.
Iam trying to count the occurance of a string in a file and have to check the count is greater than particular no.
I have following command to get the count of the string from a file
grep -c "CPU" /opt/core.log
It will returns the count of that string from that file
Along with this command can I compare that result with any number .
I tried many ways but getting the o/p
like grep -c "CPU" /opt/core.log | awk '{print $1>=30}'
first count using grep -o because grep -c will count only one occurence per line. then use if else logic to know if it is greater than or not your number.
cat test.txt
CPU is main part of computer. CPU should be 32 bit or 64 bit.
laptop with less CPU is not good.
a=$(grep -ow "CPU" test.txt|wc -l|sed 's/^$//g')
echo $a
3
if [[ $a -gt 2 ]]; then; echo "Greater"; else; echo "Equal or Smaller"; fi
Greater
if [[ $a -gt 3 ]]; then; echo "Greater"; else; echo "Equal or Smaller"; fi
Equal or Smaller

shell script error when declaring command

Code below is supposed to check the memory for user and if its greater than 1000, print message
I keep getting error- line 4: impala: command not found
#!/bin/bash
while [ true ] ;do
used= `ps hax -o rss,user | awk '{a[$2]+=$1;}END{for(i in a)print i"
"int(a[i]/1024+0.5);}' | grep user`
if [[ $used > 1000 ]]; then
echo "user memory is $used"
fi
sleep 5
done
I have tried used= ps hax -o rss,user | awk '{a[$2]+=$1;}END{for(i in a)print i" "int(a[i]/1024+0.5);} | grep user'
and used= 'ps hax -o rss,user | awk '{a[$2]+=$1;}END{for(i in a)print i" "int(a[i]/1024+0.5);}' | grep user'
I need a fresh eye on this. Please help.
In bash, as mentioned [ here ], putting spaces around the equal sign would cause errors, So the right format is
variable_name=value;
Moreover, you may change
while [ true ]
to
while true
Edit
If used has the form impala 600 and you're only interested in the number at the end, then you may do
used="${used##* }"
#Do this just after the your first command.
Finally do
#use -gt for integer comparisons and > for string comparisons
if ! [ -t $used ] && [ $used -gt 1000 ]
then
echo "user memory is $used"
fi
Note: Though the syntax errors in the script is resolved there is no guarantee that the program logic is right

How can I obtain command returning status in linux shell

Say, I call grep "blabla" $file in my shell. How could I know whether grep found "blabla" in $file?
I try ret='grep "blabla" $file', will this work by viewing the value of ret? If yes, is ret integer value or string value or something else?
If you do exactly
ret='grep "blabla" $file'
then ret will contain the string "grep "blabla" $file".
If you do (what you meant)
ret=`grep "blabla" $file`
then ret will contain whatever output grep spit out (the lines that matched "blabla" in $file).
If you just want to know whether grep found any lines that matched "blabla" in $file then you want to check the return code of grep -q blabla "$file" (note that you don't need to quote literal strings when they don't contain special characters and that you should quote variable references).
The variable $? contains the return code of the most recently executed command. So
grep -q blabla "$file"
echo "grep returned: $?"
will echo the return code from grep which will be 0 if any lines were output.
The simplest way to test that and do something about it is, however, not to use $? at all but instead to just embed the grep call in an if statement like this
if grep -q blabla "$file"; then
echo grep found something
else
echo grep found nothing
fi
When you run the command
grep blabla "$file"
Status is saved in the variable $?. 0 is good, greater than 0 is bad. So you
could do
grep -q blabla "$file"
if [ $? = 0 ]
then
echo found
fi
Or save to a variable
grep -q blabla "$file"
ret=$?
if [ $ret = 0 ]
then
echo found
fi
Or just use if with grep directly
if grep -q blabla "$file"
then
echo found
fi

bash: grep wildcard start and end with

i have a bash script like this:
TABLE_TO_IGNORE=$(mysql -u $DBUSER -p$DBPASS -h $DBHOST -N <<< "show tables from $DBNAME" | grep "^$i" | xargs);
currently i only able to grep the text starting with. How to write the code that to determine the text ending with?
let say 1:
my $i is:
test1_*
tb2_*
tb3_*
with the * at the back part, it will grep as text starting with those value
let say 2:
my $i is:
*_sometext1
*sometext2
with the * at the front, it will grep as text ending with those value.
i know this:
grep '^sometext1' files = 'sometext1' at the start of a line
grep 'sometext2$' files = 'sometext2' at the end of a line
question is: how do i write the if else to my bash code identify the * is in front or back?
Note: You can ignore my bash code, i just need the if else condition to determine the "*" is in front or at the back of the string.
Any help would be great.
Thanks
You can try this code.
#!/bin/bash
stringToTest="Hello World!*"
echo $stringToTest | grep "^\*.*" > /dev/null
if [ $? -eq 0 ]; then
echo "Asterisk is at the front"
fi
echo $stringToTest | grep "^.*\*$" > /dev/null
if [ $? -eq 0 ]; then
echo "Asterisk is at the back"
fi
As shown in this code, I made use of exit code ($?) to determine whether the regular expression matches the string. As shown in man grep:
Normally, exit status is 0 if selected lines are found and 1
otherwise.
Hope this helps.

Resources