Shell operator "||" did not work as expected? - shell

I am trying to get the file time from the HTTP Header with the following command.
curl -sLI http://sgp-ping.vultr.com/vultr.com.100MB.bin | grep -i '^Last-Modified' | cut -c16- | date -f- '+%F %T'
Under normal circumstances, it can return query results.
If the query fails due to network problems, it will return null.
I want to return the current system time when the query fails. So I use the shell operator "||", which is used as follows.
curl -sLI http://sgp-ping.vultr.com/xxx.bin | grep -i '^Last-Modified' | cut -c16- | date -f- '+%F %T' || date '+%F %T'
But it doesn't work as expected, what's wrong with it?
Any help, thanks in advance!

If you are writing a script you can deal with it via $? just need to allow for it.
e.g.
#!/bin/bash
doTheCurl() {
curl -v -sLI -o /dev/null "$1" 2>&1 | grep -i '< Last-Modified:'
[ $? -ne 0 ] && date '+%F %T'
}
doTheCurl "http://sgp-ping.vultr.com/vultr.com.100MB.bin"
doTheCurl "http://non-sgp-ping.vultra.com/xxx.bin"
Gives this [I ignored extracting / formatting - but you can see the results are different because they came from different paths.].
< Last-Modified: Wed, 28 Oct 2020 18:06:00 GMT
2021-03-12 16:24:19
The first one fails because the grep doesn't match anything - so it then gives the date.
You can do whatever you like - pipe thru sed or whatever after.

Related

Bash script, domain expiration date with email sending

I am trying to implement a solution for automatic mail sending once it finds a domain that expiration date has been exceeded. I am really new to this, therefore I managed to get as far as code below, that shows expiration dates and sends an email containg the output.
The kind of help I am looking for is at least a clue how to compare expiration date with the current date and get a result as number of days. I will really appreciate any kind of help.
#!/bin/bash
DOM="onet.pl wp.pl"
for d in $DOM
do
echo -n "$d - "
whois $d | egrep -i 'Expiration|Expires on' | head -1
whois $d | egrep -i 'Expiration|Expires on' | head -1 >> /tmp/domain.date
echo ""
done
#[ -f /tmp/domain.date ] && mail -s 'Domain renew / expiration date' myemail#gmail.com < /tmp/domain.date || :
Look no further than the date command, it has everything you need !
Here is a straightforward solution using date -d to parse the date :
# Get the expiration date
expdate="$(whois $d | egrep -i 'Expiration|Expires on' | head -1)"
# Turn it into seconds (easier to compute with)
expdate="$(date -d"$expdate" +%s)"
# Get the current date in seconds
curdate="$(date +%s)"
# Print the difference in days
printf "Number of days to expiration : %s\n" "$(((expdate-curdate)/86400))"
Good luck !

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

For loop and confition including Curl command

I am trying to write a script where I enumerate users by checking the HTTP reponse length. I want to get output "good" when response is not equal 23, however I get these errors now:
for ((i=113;i<=115;i++)); do
if [[curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" |
grep Content-Length | cut -d' ' -f2 != 23]]
then
echo "good"
fi
done
Output:
bash: [[curl: command not found
cut: !=: No such file or directory
cut: 23]]: No such file or directory
cut: !=: No such file or directory
cut: 23]]: No such file or directory
bash: [[curl: command not found
cut: !=: No such file or directory
cut: 23]]: No such file or directory
bash: [[curl: command not found
If I simply make a script without if condition, then it works well:
for ((i=113;i<=115;i++)); do
curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" |
grep Content-Length
done
I checked many examples but can't seem to figure out where I am doing wrong.
After updating your initial error, you may have a syntax like (suggestion: put some effort on format, so that it is more clear what you have and what may be wrong):
for ((i=113;i<=115;i++))
do
if [[ curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2 != 23 ]]
then
echo "good"
fi
done
This is returning you the error:
bash: conditional binary operator expected bash: syntax error near
-i'`
Which is normal, because you are basically saying:
if [[ command ]]; then ...
Where command is a set of multiple piped commands. However, in [[ you just can add expressions on the form "$var" -eq 23 or "$(command)" -ne 23.
So use $( ) to execute the command: if [[ "$(command)" -ne 23 ]]:
if [[ "$(curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2)" -ne 23 ]]
Note I am using -ne to perform an integer comparison that means "not equal to".
Finally, notice that awk alone can do what grep and cut do in two steps:
... | grep "Content-Length" | cut -d' ' -f2
This means: check the line containing "Content-Length" and print its second field. awk makes it simple by saying:
... | awk '/Content-Length/ {print $2}'
And last, but not least, your expression for ((i=113;i<=115;i++)) can be also written as for i in {113..115} using brace expansion.
If you want to test a result of the command execution you should put it into $() . So the resulting script should look as follows:
for i in {113..115}; do if [[ $(curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2) != 23 ]]; then echo "good" ; fi; done
Also I've changed a way you iterate the values. {a..b} in bash provides a sequence from 'a' to 'b'.

How can I find time difference between two server timestamps?

This outputs the closest Google server's time:
// Closest Google Server:
date +"%s" -d "$(curl -s --head http://google.com | grep ^Date: | sed 's/Date: //g')"
// Result: 1234
This outputs my local server time:
// Server
date +"%s"
// Result: 1235
How can I fetch the seconds between each result? (in the example above: 1)
Strictly answering your question, how about:
echo $(( $(date +"%s") - $(date +"%s" -d "`curl -s --head http://google.com | grep ^Date: | sed 's/Date: //g'`") ))

Parsing timestamp using sed and embedded command

There's a file with some lines containing some text and either date or time stamp:
...
string1-20141001
string2-1414368000000
string3-1414454400000
...
I want to quickly convert time stamps to dates, like this:
$ date -d #1414368000 +"%Y%m%d"
20141027
and I want to do this dynamically with sed or some similar command line tool. For testing I unsuccessfully use this:
$ echo "something-1414454400000" | sed "s/-\(..........\)...$/-$(date -d #\\1 +'%Y%m%d')/"
date: invalid date '#\\1'
something-
but echoing seems to be working:
$ echo "something-1414454400000" | sed "s/-\(..........\)...$/-$(echo \\1)/"
something-1414454400
so what could be done?
It's interesting what's happening here. Some pointers:
Always single-quote your regex for sed, if possible, when using BASH (etc), especially if using special characters like$. This is why date is being run (with -d #\\1) before sed even gets involved.
Your "working" echo example isn't, actually (I believe): echo \\1 produces \1 (and as above, will do so before sed even gets invoked). This then happens to valid sed replacement syntax, so will substitute your group on the LHS, which is why the output looks about right.
Note that by using -r, you can use easier / more advanced regex syntax.
Hard to say exactly what to do without a bit more context, but to fix the immediate problems, try something like:
echo "something-1414454400000" | sed -re 's/-([0-9]{10,}).+/-$(date -d #\1 +"%Y%m%d")/'
which produces: $(date -d #1414454400) (which you can then pipe to sh)
Or for a more complete solution, you can change the regex to produce a shell command directly, and pipe it:
echo "something-1414454400000" | sed -re 's/(.*-)([0-9]{10,10}).+/echo \1$(date -d #\2 \"+%Y%M%d\")/' | sh
..producing something-20140028
You can do this in BASH:
while read -r p; do
if [[ "$p" =~ ^(.+-)([0-9]{10}).{3}$ ]]; then
echo -n "${BASH_REMATCH[1]}"
date -d "#${BASH_REMATCH[2]}" +"%Y%m%d"
else
echo "$p"
fi
done < file
OUTPUT:
string1-20141001
string2-20141026
string3-20141027
awk -F- 'BEGIN { OFS=FS }
$2 ~ /^[0-9]{13}$/ {
"date -d#" $2/1000 " +%Y%m%d " | getline t; $2=t }1'
Just try this command. I have checked it. It is working on your inputs.
cat file | sed -E "s,(.*)-(.*),\1-`date -d #1414368000 +'%Y%m%d'`,g"

Resources