Comparing two date strings in bash - bash

I am having trouble with a script that checks the date of a table to make sure the slave's data is up to date
The problem is that the date equality is coming back incorrect:
NOW=$(date +"%Y-%m-%d")
VALUE=`mysql -uroot -p database -e "select DATE_FORMAT(create_date,'%Y-%m-%d') as '' from actions order by id desc limit 1"`
echo $NOW $VALUE
if [ "$?" -ne 0 ]; then
MSG="MySQL check data date failed"
echo $MSG
echo $MSG > $MESSAGE
/bin/mail -s "$SUBJECT" "$EMAIL" < $MESSAGE
exit 7
fi
if [ "$NOW" != "$VALUE" ]; then
echo "not equal"
fi
The output is that they are not equal:
2011-12-08 2011-12-08
not equal
My guess is that I am comparing two different types, but according the bash documentation that shouldn't be the case.
Can someone explain this to me?
Thanks

If you turn on the shell debugging set -vx, you'll see each line (or block of code like while, for loops) displayed, (verbose mode), then you get the line as it being executed with all variables expanded to their current values. Change the last conditional to
if [ "X${NOW}X" != "X${VALUE}X" ] ; then ....
And you can easily tell if $NOW or $VALUE have any extra while-space characters embedded. Once you can see where the differences are, then you can easily determine how to fix the assignment of those values.
I hope this helps.

Related

bash script to trigger on and off events from journalctl

I am trying to write a bash script to set a variable "status" to either online or offline.
I use logger "trigger offline" and logger "trigger online" for simplicity.
The offline event triggers ok, and I can see the output correct in journalctl, but when the online event is sent by logger, the variable £status is still offline. If its offine, I want it to restart the NetworkManger until the event online is triggered. thanks
!/bin/bash
journalctl -fqn0 | \
while read line
do
#trigger if offline
echo "$line" | grep "trigger offline"
if [ $? = 0 ]
then
status="offline"
fi
#trigger if online
echo "$line" | grep "trigger online"
if [ $? = 0 ]
then
status="online"
fi
sleep 3
logger "Status is $status"
if [[ $status="offline" ]]
then
#restart the network here
logger "do some stuff"
fi
done
if [[ $status="offline" ]]
when $status is online means
if [[ online=offline ]]
online=offline is a single string.
[[ string ]] is true if string is non zero. Which is the case.
You wanted to use the string comparison, to call [[ with 3 arguments (not counting the closing ]]), a string, a = and another string, not just one.
In other words
if [[ $status = "offline" ]]
with the correct spaces.
Another thing unrelated to your error, but related to the next one:
I surmise that all line won't contain either 'online' or 'offline'.
So, $status maybe empty (at least at the beginning. Then, it will be whatever it already was for all lines not related to your status. Which may be a 3rd error, but that an applicative problem I can not judge whether this is a problem or not. I do have the feeling that you don't want to log a status line each time a totally unrelated event is shown by journalctl tho. So you may want to reset status to "" at each loop. Not sure. Your call).
But the important point is, whatever you choose, $status maybe the empty string. In which case, your if will become if [[ =offline ]] which is true, and mine if [[ = offline ]] which is a syntax error.
To avoid that, you want to enclose $status in double quotes
So :
if [[ "$status" = "offline ]]

Is there any way to check if there is any input then contiue?

I am a newbie in bash programming. I need a bash script which can check if there is an input or not.If there is an input then continue to the second question, otherwise it will not continue unless it forces me to write the input (data). I wrote this script but is not working:
echo "Write buss no:"
read bussno
while [ true ] ; do
if [ -z $bussno ] ; then
echo "\Buss No. should be filled"
read bussno
else
echo "Write from date: "
read startdate
if [ -z $startdate ] ; then
echo "\start date should be filled"
read startdate
fi
done
Bash read command support timeout. You can set the timeout to zero:
From man bash:
-t timeout
Cause read to time out and return failure if a complete line of input
is not read within timeout seconds. timeout may be a decimal number
with a fractional portion following the decimal point. This option is
only effective if read is reading input from a terminal, pipe, or
other special file; it has no effect when reading from regular files.
If timeout is 0, read returns success if input is available on the
specified file descriptor, failure otherwise. The exit status is
greater than 128 if the timeout is exceeded.
Basically use bussno= ; read -t0 bussno instead of read bussno
There are ways, but you want to keep it simple, yes?
Maybe the logic you want is something like
while [[ -z "$bussno" ]]; do read -r -p "Please enter a business number: " bussno; done
while [[ -z "$startdate" ]]; do read -r -p "Please enter a start date: " startdate; done
This still leaves a lot to be desired in terms of data confirmation, though.
You can add a regex for that if you want, and some follow up confirmations.
For example, for the date,
valid_date='^[[:digit:]]{8}$'
msg="A valid start date is today or later as YYYYMMDD, e.g.: 20220823"
echo "$msg"
until [[ -n "$startdate" && $startdate =~ $valid_date ]]; do
read -p "Please enter a valid start date: " startdate
if date -d "$startdate" >/dev/null 2>&1 && # fail if invalid date
(( "$(date +'%Y%m%d')" <= "$startdate" )) # fail if in past
then break
else echo "'$startdate' is not a valid date."
echo "$msg"
startdate= # reset
fi
done
These still leave much to be desired, but it's a start.

shell script compare numbers return illegal number

I have a script that simply needs to check a timestamp with another timestamp in an if-statement.
However, it constantly returns an Illegal number
currentTime=$(($(date +%s) -d ))
cutoffTime=$((currentTime - 604800))
cutoffTime is the first variable to compare
time="$(echo $notes | grep -oP '^[0-9]{0,10}')"
time is the second variable to compare and is parsed from a string.
The if-statement looks like this
if [ $(($time)) -lt "$cuttofTime" ];
but even if I try
if [ "$time" -lt "$cuttofTime" ];
or
if [ "$time" < "$cuttofTime" ];
It will still say 'Illegal number'. I have no clue why it says illegal number when converting $time to a number in the first if-statement.
What is the proper way to do this in shell scripts and why does it state it is an illegal number?

While loop in Bash not running

I'm pretty new with Bash scripting and am having trouble getting my 'while' loop to run. When I echo keywords, a whole list of words prints and then when I echo length, it prints 124. I believe I'm using the while loop and condition correctly, so I can't figure out what I'm doing wrong. Any thoughts?
keywords=$1
length=${#keywords}
echo "$keywords"
echo "$length"
if [ -z "$keywords" ]; then
while [ $length -gt 100 ]; do
echo "$keywords"
echo "$length"
keywords="${keywords%,*}"
length=${#keywords}
done
fi
echo $keywords
The problem is here:
[ -z "$keywords" ]
-z is true if its argument is an empty string. Something of length 124 is definitely far from empty. You probably meant -n.
Next time, please also include the input in the question so we can reproduce the problem.

If statement goes else every time - bash

I am very new here, so I apologize for any my mistakes, and I am sorry for my lack of knowledge (I'm just beginner).
So here it is, i am doing little script in bash with li and I have if statement, here it is
#!/bin/bash
something=$(whiptail --inputbox "Enter some text" 10 30 3>&1 1>&2 2>&3)
if [ $something ?? 'you' ];
then
echo "$something"
else
echo "nope"
fi
To be specific what i want from it - I enter some word/sentence/whatever to whiptail, and if it contains some of of you string then prints it, but every times it goes else ;_;.Please help.
EDIT now it works, thanks but I need to check if string contains word.
if [[ $string =~ .*My.* ]]
doesn't seem to work
I don't get it at all, losing hope and searching the web i've encontered on
#!/bin/bash
OPTION=$(whiptail –title “Menu Dialog” –menu “Choose your option” 15 60 4 \ “1” “Grilled ham” \ “2” “Swiss Cheese” \ “3” “Charcoal cooked Chicken thighs” \ “4” “Baked potatos” 3>&1 1>&2 2>&3)
exitstatus=$?
if [ $exitstatus = 0 ];
then echo “Your chosen option:” $OPTION
else echo “You chose Cancel.”
fi
And I've just pasted this script to check how it works and modify it, it isn't mine script and it supposed to work, but it says “You chose Cancel.”
What you may be looking for are the string comparison operators like == or !=. For example,
if [ "$something" == "you" ]; then
echo "$something"
else
echo "nope"
fi
If $something equals you then echo $something; else echo nope.
Or, as David C.Rankin mentioned in his comment you can check the string variable to prove whether a string is empty or not. For example,
if [ -z "$something"] ;then
String is empty
if [ -n "$something" ]; then
String is non-empty
For more information on this check the TEST manual page.

Resources