I have a script that updates a server with some stats once per day. The script works as intended when running from command line, but when running from cron some of the variables are not passed to curl.
Here is an example of the code:
#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
/bin/sh /etc/profile
MACADDR=$(ifconfig en0 | grep ether | awk '{print $2}')
DISKUSED=$(df / | awk '{print $3}' | tail -n1)
DISKSIZE=$(df / | awk '{print $2}' | tail -n1)
# HTTP GET PARAMS
GET_DELIM="&"
GET_MAC="macaddr"
GET_DS="disk_size"
GET_DU="disk_used"
# Put together the query
QUERY1=$GET_MAC=$MACADDR$GET_DELIM$GET_DS=$DISKSIZE$GET_DELIM$GET_DU=$DISK_USED
curl http://192.168.100.150/status.php?$QUERY1
The result in the cron job is http://192.168.100.150/status.php?macaddr=&disk_size=&disk_used=
I am not sure if it is some problem with the variables, or possibly with awk trying to parse data with no terminal size specified, etc.
Any help is appreciated.
When you're running into problems like this it's almost always an environment issue.
Dump the results of "env" to a file and inspect that. You can also run your script with top line of
#!/bin/sh -x
to see what's happening to all the variables. You might want to use a wrapper script so you can redirect the output this provides for analysis.
Very first command in your script ifconfig is found in /sbin/ifconfig on Mac. And the default PATH variable for cron jobs is set to: /usr/bin:/bin That's the reason probably rest of your commands are also failing.
It is better to set the PATH manually at the top of your script. Something like:
export PATH=$PATH:/sbin
One problem I've run into with crons is that variables you take for granted do not exist. The main one you take for granted is the path variable.
Echo what you have set as your path when being run from the command line and put that in the top of your script (or in the top of the crontab).
Alternatively, specify the full path to each command - ifconfig, awk, grep, etc.
I would guess that will fix the problem.
Related
Writing a script to retrieve various environment parameters back from a list of servers. My script returns no value when ran but the same command returns the desired value outside of a script.
I have tried using a couple of variations to retrieve the same data. One of the commands fails because of restrictions placed on the accounts I have access to. The second command works but only if executed in an elevated mode.
This fails with access denied (pwdx is restricted)
dzdo pgrep -f /some/path | xargs pwdx
This works outside of a script but returns no value within a script
dzdo /bin/readlink -e /proc/"$(pgrep -f /some/path)"/cwd
When using "bash -x" to execute my scriipt, I see the "readlink" code is blank.
Ideally, I would like to return the PID and path of the process running as the "pgrep" command does. I can work with the path alone as returned by the "readlink" version returns. The end goal is to gather the information from several servers for audit purposes. (version, etc.)
Am I using the wrong syntax for the "readlink" command? I'm fairly new to coding bash scripts so I appreciate any guidance to help understand when to to what if I'm using a command in a script vs command line.
If pwdx is the restricted program, you need to run that with dzdo, not pgrep.
pgrep -f /some/path | dzdo xargs pwdx
I get this error while running thru crontab
/aws-cron-job/Ap_Hourly_xxxDelete.sh: 1: ./aws-cron-job/Ap_Hourly_xxxDelete.sh: ec2-describe-snapshots: not found
./aws-cron-job/Ap_Hourly_xxxDelete.sh: 1: ./aws-cron-job/Ap_Hourly_xxxDelete.sh: ec2-delete-snapshot: not found
This is my script: filename = xxx.sh
ec2-delete-snapshot --region ap-southeast-1 $(ec2-describe-snapshots --region ap-southeast-1 | sort -r -k 5 | grep "Ap_Hourly" | sed 1,4d | awk '{print $2};' | tr '\n' ' ')
This is my cronjob:
30 05-15 * * 1-6 ./aws-cron-job/Ap_Hourly_xxxDelete.sh > ./aws-cron-job/Ap_Hourly_xxxDelete.txt 2>&1
I can run this script manually but not through Cronjob. Where is the problem in this. Thanks in advance.
I believe that you should place only absolute paths in your cronjobs. As seen in your question, you wrote:
./aws-cron-job/Ap_Hourly_xxxDelete.sh
and I think you should write:
/<rootpath>/aws-cron-job/Ap_Hourly_xxxDelete.sh
The environment that commands run with as cron jobs is very limited, things like $PATH and $HOME are not what you'd expect.
To analyze this, use crontab -e to add the job * * * * * /bin/bash -c env >/tmp/cron.env, then look inside that file to see what bash knows about when started as a cron job on your machine. The job will run every minute, so when you're done debugging, remove it, also with crontab -e.
The error ec2-describe-snapshots: not found suggests that ec2-describe-snapshots might not be found in $PATH when the script runs as a cron job. To fix this, first find its normal location from the a shell with which ec2-describe-snapshots. Then, either use full path in script (/some/path/ec2-describe-snapshots ...), or adjust $PATH in script (PATH=/some/path:$PATH) before calling ec2-describe-snapshots.
Also, it's a good habit to use full paths in crontab entries, both for executables and for log files. However, the error in OP would not come from this.
this is my first question on SO, otherwise I generally find what I need.
So here we go, here is my script :
#!/bin/bash
cd /home/laxa/Teeworlds_servers/scripts
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
kill `ps aux | grep -v "grep" | grep "/home/laxa/Teeworlds_servers/" | awk ' { print $2 } '`
and here is my crontab test :
48 23 * * * /home/laxa/Teeworlds_servers/scripts/restart_server.sh > /home/laxa/log.txt 2>&1
So, when I use the script in a bash shell with putty, the script gets executed fine and does it's job.
But when it's executed by the crontab, after some debug, it fails on the kill command.
I tried to set manually the PATH cause it was a big wrong.
Another friend told me to try to debug it, but apparently the script dies directly.
So I am quite blocked now, if someone has an idea or a solution, I would really welcome it.
Thanks.
Ok so, finally I founded that my line was working, but she was returning more processes than intended. And then I discovered that the script was killing himself, so thanks guys !
I've written a shell script in CentOS. It basically connects to a database and displays certain information.
i have put at the beginning the following instructions:
#!/bin/bash
echo "Content-type: text/plain"
echo ""
If I run it in the Linux Command line I get the results and the output as desired, but If I run it using the web browser, it displays nothing. I have put the script in the cgi-bin directory. As additional information I have some other scripts using nmap and curl working without problem.
Basically I want to display the status of some extensions in Asterisk IP-PBX
for i in `asterisk -rx 'sip show peers'|grep -ai Uns |sort -n |grep ^2| awk '{print $1}' | grep [a-z]`; do
Thanks for your time.
You have put full path to asterisk.
Also you have test script under same user as your webserver. Very likly you have change in /etc/asterisk/asterisk.conf permissions for asterisk ctl file.
I have a strange issue, relating to running a BASH script via cron (invoked via crontab -e).
Here is the script:
#!/bin/bash
SIG1="$(iwconfig wlan0 | awk '/Quality=/ { print $2} ' | cut -c 9-10)"
SIG2="$(iwconfig wlan0 | awk '/Quality=/ { print $2} ' | cut -c 12-13)"
echo "$SIG1:$SIG2" >> test.txt
exit
When run from the commandline, I get the expected output of 45:70 echoed to the end of the text file. However, when I run the script via cron (using crontab -e) and the following entry:
* * * * * bash /home/rupert/test.sh
I just get the colon (:) echoed to the text file, the values SIG1 and SIG2 aren't created and I have no idea why. Why would running via cron mess up the script?
FWIW, here is the output of iwconfig wlan0 with no additional processing:
wlan0 IEEE 802.11abgn ESSID:"plumternet"
Mode:Managed Frequency:2.452 GHz Access Point: 00:18:84:2A:68:AD
Bit Rate=54 Mb/s Tx-Power=15 dBm
Retry long limit:7 RTS thr:off Fragment thr:off
Power Management:off
Link Quality=46/70 Signal level=-64 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
I am doing all this because I want to display the WiFi Link Quality value "46/70" on an LCD screen and the program I use does this by reading a text file. However, when run via cron, the values get lost...???
I am using cut -c 9-10 and cut -c 12-13 because I was thinking the "/" might be causing an issue in the script, I'd be happy to just use cut -c 9-13, but I thought it might fix the issue, but it didn't.
Help!!
Cool, thanks to you guys, I realised it was a PATH problem, simply giving the full path to iwconfig (/sbin/iwconfig) fixed it. Here is a pic of the LCD screen now showing all the correct info:
http://img835.imageshack.us/img835/4175/20100825122413.jpg
you need to give the full path to any commands executed via cron. cron runs commands detached from any terminal which means you need to set the environment correctly. cut is probably available but give the absolute path to iwconfig and awk
Change the permission of this file to 777
chmod 777 /home/rupert/test.sh
Maybe this will help.
I don't know the exact steps to prevent this (in a clean manner) from happening (I'm not all that of a linux-expert), however, this looks like a permissions problem to me. The user as which cron jobs run isn't allowed to execute one of the commands you are letting execute.
If you fix the permissions, I think it may run just fine!