ip command could not get IP address in shell script in crontab - bash

I use Cloudflare API script to update DDNS on my Raspberry PI using crontab. The shell script works fine in Debian but fails in CentOS/Fedora. While run in the terminal, it works.
I checked out the ip addr could not get data, but I could not solve it. And I tried out that I can instead ip addr with hostname -I, then it works well.
But I am wondering why ip could not work in .sh / bash shell script?
Ferora 28 server Raspberry.
I tried many resolvation I can googled, none works.
#!/bin/bash
#this works
ip=$(hostname -I | awk '{print $NF;exit}')
echo $ip>>/usr/local/bin/cloudflare.log
#this fail
ips=$(ip route get 1:: | awk '{print $(NF-4);exit}')
echo $ips>>/usr/local/bin/cloudflare.log
# crontab -l
#automatic update ddns per 1 min
* */1 * * * /usr/local/bin/cf-ddns.sh >/dev/null 2>&1
cat cloudflare.log
xx.xx.xxx.xx
<Blank_None>

crontab dosn't set PATH an cannot find the binarys. Add PATH at the top of your script, or with an export at top of crontab.
# for example
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

Related

Automated Bash Upload Script with Crontab Raspberry Pi Not Running

I'm attempting to have my Raspberry Pi use rysnc to upload files to an SFTP server sporadically throughout the day. To do so, I created a bash script and installed a crontab to run it every couple hours during the day. If I run the bash script, it works perfectly, but it never seems to run using crontab.
I did the following:
"sudo nano upload.sh"
Create the following bash script:
#!/bin/bash
sshpass -p "password" rsync -avh -e ssh /local/directory host.com:/remote/directory
"sudo chmod +x upload.sh"
Test running it with "./upload.sh"
Now, I have tried all the following ways to add it to crontab ("sudo crontab -e")
30 8,10,12,14,16 * * * ./upload.sh
30 8,10,12,14,16 * * * /home/picam/upload.sh
30 8,10,12,14,16 * * * bash /home/picam/upload.sh
None of these work based on the fact that new files are not uploaded. I have another bash script running using method 2 above without issue. I would appreciate any insight into what might be going wrong. I have done this on eight separate Raspberry Pi 3B that are all taking photos throughout the day. The crontab upload works on none of them.
UPDATE:
Upon logging the crontab job, I found the following error:
Host key verification failed.
rsync error: unexplained error (code 255) at rsync.c(703) [sender=3.2.3]
This error also occurred if I tried running my bash script without first connecting to the server via scp and accepting the certificate. How to get around this when calling rsync from crontab?
check if the script is working properly at all ( paste it in shell)
Check if your crond.service working properly - systemctl status crond.service.
Output should be "active (running)"
Then you can try add simply test job to cron: * * * * * echo "test" >> /path/whichyou/want/file.txt
and check if this job work properly
Thanks to logging recommendation from Gordon Davisson in comments, I was able to identify the problem.
A logging error occurred, as mentioned in the original question update above where rsync would choke on a host key verification.
My solution: tell rsync not to check host key certificates. I simply changed the upload.sh bash file the following:
#!/bin/bash
sshpass -p "password" rsync -avh -e "ssh -o StrictHostKeyChecking=no" /local/directory host.com:/remote/directory
Working perfectly now -- hope this helps someone.

Bash script with sendmail delivers email when executed manually but not from crontab

I wrote the following bash script to send me an alert if there is a problem with my website:
#!/bin/bash
# 1. download the page
BASE_URL="https://www.example.com/ja"
JS_URL="https://www.example.com/"
# # 2. search the page for the following URL: /sites/default/files/google_tag/google_tag.script.js?[FIVE-CHARACTER STRING WITH LETTERS AND NUMBERS]
curl -k -L ${BASE_URL} 2>/dev/null | grep -Eo "/sites/default/files/google_tag/google_tag.script.js?[^<]+" | while read line
do
# 3. download the js file
if curl -k -L ${JS_URL}/$line | grep gtm_preview >/dev/null 2>&1; then
# 4. check if this js file has the text "gtm_preview" or not; if it does, send an email
# echo "Error: gtm_preview found"
sendmail error-ec2#example.com < email-gtm-live.txt
else
echo "No gtm_preview tag found."
fi
done
I am running this from an Amazon EC2 Ubuntu instance. When I execute the script manually like ./script.sh, I receive an email in my webmail inbox for example.com.
However, when I configure this script to run via crontab, the mail does not get sent via the Internet; instead, it gets sent to /var/mail on the EC2 instance.
I don't understand why this is happening or what I can do to fix it. Why does sendmail behave different if it is being run from bash vs being run from crontab?
Be aware that the PATH environment variable is different for crontab executions than it is for your typical interactive sessions. Also, not all of the same environment variables are set. Consider specifying the full path for the sendmail executable ( which you can learn by issuing the 'which sendmail' command ).

OS X Bash script doesn't work but individual commands do

I'm trying to turn the instructions on this page about connecting to a Soft Ether VPN on OS X into a bash script, but I'm running into some issues.
When I run each of these commands individually at the command line, I'm able to initiate the connection to the VPN just fine and set up the routing appropriately, but when I put it into a script, it doesn't work.
Here is the script in question:
#!/bin/bash
GATEWAY=`route -n get default | grep gateway | awk '{print $2}'`
VPN_IP=130.158.6.123/32
VPN_GATEWAY=192.168.0.1
vpnclient start
vpncmd localhost /CLIENT /CMD AccountConnect HomeVPN;
ipconfig set tap0 DHCP;
ifconfig tap0 down; ifconfig tap0 up
echo "waiting for dhcp to get us an address..."
sleep 15
route delete default;
route -n add $VPN_IP $GATEWAY;
route add default $VPN_GATEWAY;
Upon testing, I have confirmed that GATEWAY gets the correct value and all the other variables are set correctly. The script seems to do everything correctly up until the part where it starts changing the routes. At first I thought it was because the interface hadn't had enough time to get an IP address, so I put a pretty long wait time in to make sure it had an IP before it started trying to change routes.
Any thoughts as to why this doesn't work when put into script form?
Just a guess: sudo doesn't work well in shell scripts as it's an interactive tool and need to prompt for a password. You might consider removing the sudo commands and running the entire script using sudo.

I'm trying to get the MAC address as a variable in Linux, but it rarely works

I'm using the following code to get the MAC address of eth0 into a variable for use in a filename, but it rarely every works. It isn't that it NEVER works, it is just unpredictable.
ntpdate -b 0.centos.pool.ntp.org
DATE=$(date +%s)
MAC=$(ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}' | sed 's/://g')
cp logfile logfilecp-$MAC-$DATE
Now, it seems to work less-frequently if I use the ntpdate line, but regardless, it is wholly unpredictable. Anyone have any idea what I could do to make this work better? I end up with a filename like
logfile--1375195808.bz2
New info
I've got the script setup to run as a cronjob (crontab -e). I notice that when it runs as a cronjob, it doesn't get the MAC, but when I run it manually ./runscript.bash it does get the MAC. Hopefully someone knows why this might be causing it.
Thanks.
Try an easier method to get you mac address than through ifconfig, i.e.
cat /sys/class/net/eth0/address
I've tested it in shell (not through script) and works like a charm :
TEST=`cat /sys/class/net/eth0/address`
touch /tmp/blabla-$TEST
EDIT for your second problem
in you cron script, add the full path of the binaries you're using (i.e. /sbin/ifconfig), or use my method as above :)
ip addr | grep link/ether | awk '{print $2}'

Creating cron entry on server using ssh login within shell script

I need to upload a file (bash script) to a remote sever. I use the scp command. After the file has been copied to the remote server I want to create a cron entry in the crontab file on the remote server.
However, the file upload and writing the cron entry need to occur within a bash shell script so that I only need to execute the script on my local machine and the script is copied to the remote host and the cron entry is written to the crontab.
Is there a way that I can use an ssh command, within the script, that logs me into the remote server, opens the crontab file and writes the cron entry.
Any help is very welcome
I would:
extract the user's crontab with crontab -l > somefile
modify that file with the desired job
import the new crontab with crontab somefile
I just did something like this where I needed to create a multiline line crontab on a remote machine. By far the simplest solution was to pipe the content to the remote crontab command through ssh like this:
echo "$CRON_CONTENTS" | ssh username#server crontab
mailo seemed almost right, but the command would be the second argument to the ssh command, like this:
ssh username#server 'echo "* * * * * /path/to/script/" >> /etc/crontab'
Or if your system doesn't automatically load /etc/crontab you should be able to pipe to the crontab command like this:
ssh username#server 'echo "* * * * * myscript" | /usr/bin/crontab'
Say you want to copy $local to $remote on $host and add an hourly job there to run at 14 past every hour, using a single SSH session;
ssh "$host" "cat >'$remote' &&
chmod +x '$remote' &&
( crontab -l;
echo '14 * * * * $remote' ) | crontab" <"$local"
This could obviously be much more robust with proper error checking etc, but hopefully it should at least get you started.
The two keys here are that the ssh command accepts an arbitrarily complex shell script as the remote command, and gets its standard input from the local host.
(With double quotes around the script, all variables will be interpolated on the local host; so the command executed on the remote host will be something like cat >'/path/to/remote' && chmod +x '/path/to/remote' && ... With the single quotes, you could have whitespace in the file name, but I didn't put them in the crontab entry because it's so weird. If you need single quotes there as well, I believe it should work.)
You meant something like
ssh username#username.server.org && echo "* * * * * /path/to/script/" >> /etc/crontab
?

Resources