My script -
#!/bin/sh
# export DBUS_SESSION_BUS_ADDRESS environment variable
PID=$(pgrep gnome-session)
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-)
DIR="/home/umang/Downloads/Wallpapers"
PIC=$(ls $DIR/*.jpg | shuf -n1)
/usr/bin/gsettings set org.gnome.desktop.background picture-uri file://$PIC
cronjob file -
* * * * * /path/to/script/Wallpaper_Changer.sh
* * * * * date >> /path/to/logfile/CronTest.log
Wallpaper changes correctly via terminal and the dates are logged via cron.
I am running ubuntu 14.04, GNOME Shell 3.12.1.
Help me change wallpaper on gnome as well as unity.
There are quite a few questions that are similar to this on SO, a simple Google search yielded quite a few. There is this one:
Run cronjob as user to change desktop background in Ubuntu
This one:
https://askubuntu.com/questions/25489/wallpaper-change-crontab-jobs-not-working-after-upgrade-from-8-04-to-10-04
This one:
https://askubuntu.com/questions/403918/setting-cron-to-run-a-shell-script-random-wallpaper-from-a-webpage
And probably more. Hope one of these or others online help you out.
I tried all the solutions but none helped. The problem was, I was still unable to access the environment variables(DBUS_SESSION_BUS_ADDRESS). So one could check if those are available first.
What worked for me is simply running the script in current shell environment. This can be done by running the script with a . as in cronjob file -
* * * * * . /path/to/script/Wallpaper_Changer.sh
More information : Global environment variables in a shell script Understanding Unix shells and environment variables
Related
I have this in my crontab:
* * * * * cd /etc && . ./cron.sh>>cron.log
In my cron.sh (which is executable) I have:
#!/bin/sh
echo "hello world"
export MyVar="abcd"
It runs both with cron and manually, however the environment variable is only set when I run it manually with the command:
. ./cron.sh
Can anyone please help. I know its something to do with source but I cant figure it out.
This does not work either:
* * * * * cd /etc && sh ./cron.sh>>cron.log
. will export variables in the current shell, which is the one spawned by the cron, not yours.
If you want to add an extra variable to your shells, use the ~/.profile et al (specifically the /etc/profile that is shared by all users).
I'm trying to set a variable for all users
You cannot do that via a cron job.
In fact, in general, you can't do it at all. The environment variables of a shell cannot be set from outside the shell. The UNIX / Linux operating system architecture doesn't allow it.
You could could set an environment variable for all users via /etc/profile except ...
the /etc/profile file is only executed when a user logs in, and
the user can override any environment variables set there.
I am facing an issue of crontab does not run the python script in Raspbian GNU/Linux 9.4 (stretch) installed on a Raspberry Pi3. I have done lots of research on this topic e.g. by following the troubleshooting guide in https://askubuntu.com/questions/23009/why-crontab-scripts-are-not-working/24527#24527 , but none of them solved my issue.
The python script that I want to run is located in
/home/pi/Documents/Fork_BookManager.py
I have made sure that anyone can execute, read and change content to the above file.
I can run this file through terminal by writing
usr/bin/python3 /home/pi/Documents/Fork_BookManager.py
I know the file is running, because the Fork_BookManager.py is using selenium to open a web browser, and I see this web browser being opened. There is no error observed when running the Fork_BookManager.py file from terminal.
In terminal executed
crontab -e
Using nano as editor, I first verified that crontab acutally worked by
* * * * * env > /home/pi/Documents/env.output
After a minute there is a env.output file in Documents folder with below parameters.
LANGUAGE=da_DK.UTF-8
HOME=/home/pi
LOGNAME=pi
PATH=/usr/bin:/bin
LANG=da_DK.UTF-8
SHELL=/bin/sh
LC_ALL=da_DK.UTF-8
PWD=/home/pi
I noticed that the path from crontab is different from the path when env is called from terminal as I will have the below path if I call env from terminal
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
So I know that crontab -e was working since I otherwise would not have got the env.output file created in Documents folder. I proceed by calling crontab -e from terminal and copied the path from env into the crontab like below
PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
* * * * * /usr/bin/python3 /home/pi/Documents/Fork_BookManager.py
Saved the script and waited. Nothing happend.
To summerize I have:
Made sure that the Fork_BookManager.py is executable
Verified that crontab is working
Updated path from env into the crontab script
which are three largest cause of experiencing difficulties in making crontab to work according to this guide
https://askubuntu.com/questions/23009/why-crontab-scripts-are-not-working/24527#24527
Still it is not working. What have I missed? Is there a better practice to achieve what I want, namely to execute the python script once a minute without doing it directly from the python script itself such as a while loop with a time.sleep(60)
ADDITIONAL INFORMATION
I even tried to expand the path in crontab script by
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/usr/bin:/home/pi/Documents
in an attempt to specify in which folder the python3 and Fork_BookManager.py is located. Still no luck.
I have a strange problem of being to able to run a bash script from commandline but not from the crontab entry for root. I am running Ubuntu 12.04.
* * * * 1-5 root /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log
If I run the script from the cmd line using bash, it works fine but sh fails with following error:
> jmeter-cron-randomise.sh: 7: jmeter-cron-randomise.sh: arithmetic
> expression: expecting primary: " % 1 "
Having googled the problem, it seems like standard shell doesn't have the same math operators, like % (modulus), as bash. I'm Not sure why the cron job is failing in the script? I am assuming it is because it's not using the bash shell? It's definitely being fired by the cron daemon (can see it in /var/log/syslog). Any help much appreciated.
You likely need to tell cron that the shell to use is the bash shell as it defaults to sh. You can do that for all crontab entries by putting this line in your crontab:
SHELL=/bin/bash
Note that this will cause all scripts in the crontab to be run under bash which may not be what you want. If you want to change the crontab line itself to just run bash, change it to this:
* * * * 1-5 root /bin/bash /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log 2>&1
Note that I have also caused stderr to be written to the cron.log file (2>&1) which may not be what you want but is pretty common practice. This may help you further diagnose errors from the script.
In case this helps anyone: for me this appeared to be because I had ended up with "DOS" line endings (CR-LF) instead of "unix" line endings (LF). This can be checked using od or your favourite hex dump tool, e.g.:
od -c <script_file>
... and look for \r\n instead of just \n.
It seems (and this article supports it) that the CR character stops the "shebang" from working because it's interpreted as part of the shell executable's filename.
(The line endings themselves appeared because the file came from a git repository and was transferred via a Windows machine).
I also encountered this problem trying to schedule a database backup as root and it made me pull my hair out! I was working on a CentOS 7 box.
Whenever I would check /var/spool/mail/root I would see a log:
sh: root: command not found, yet the command would run perfectly in the terminal.
This is what worked for me:
I created the crontab entry using crontab -e while logged in as root.
Using the command above as an example:
* * * * 1-5 root /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log
I deleted the root user entry like:
* * * * 1-5 /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log
That solved my problem.
how to use crontab to run a Graphical program such as "gedit"
57 12 * * * gedit --display=localhost:0
Can not successfully open the program and display it.
--display=localhost:0 can be causing error ,
Following code will also do the trick
57 12 * * * export DISPLAY=:0 && /usr/bin/gedit
There is a reason why i added entire path of gedit ,
Utilities in /bin and /usr/bin can be opened using cron just by specifying its name so
/usr/bin/gedit or just gedit will work.
May a time command you use to start certain utility on terminal doesn't work using cron ,this is because cron passes a minimal set of environment variables to your jobs.May be required env PATH variable is not available with Cron hence it is not able to locate that utility.
you can find a detailed explanation in first reply here.
I'm using Linux (Ubuntu). I use wmctrl to make the firefox window always on top. And it worked FINE when I run the shell on a terminal.
Here is my shell code (say that it was /usr/app/keepfront.sh):
#!/bin/bash
WINTITLE="Mozilla Firefox" # Main Firefox window has this in titlebar
PROGNAME="firefox mywebsite --sync" #run the firefox program
#Use wmctrl to list all windows, count how many contain WINTITLE
WINCOUNT=wmctrl -l | grep -c "$WINTITLE"
if [ $WINCOUNT != 0 ]
then
wmctrl -a "$WINTITLE" # If it exists, bring window to front
else
$PROGNAME & # Otherwise, just launch ff
fi
exit 0
I would like to use crontab to run the shell every 1 minute. Crontab DID run the shell (I wrote some echos), but nothing happened.
Here is my crontab code:
*/1 * * * * /usr/app/keepfront.sh
Anyone know WHY? How to solve this?
cron jobs do not have access to your environment variables, although they are owned by the user they do not run in that user's full desktop environment. In this case your script does not know about your DISPLAY environment variable. To retrieve information and to make changes wmctrl needs to know which DISPLAY to use.
To do what you want to do, all you need is to set the DISPLAY environment variable in your script before any calls to wmctrl. Assuming you only have 1 monitor the line below should fix your problem (my test worked fine). If you have more than 1 monitor then just use echo $DISPLAY on the command line to help you configure the command for your various monitors.
# Add to your script before any calls to wmctrl.
export DISPLAY=:0
Some other things to note:
If you have more than one 'Mozilla Firefox' window open then your code will only bring the first one encountered by wmctrl to the top, this will be the one that was opened first because wmctrl looks through windows from oldest to newest.
I have not tested the launching of Firefox aspect of your script, genarally speaking I would have thought doing this is a bad idea because Firefox will also use environment variables which won't be set when running the script from crontab. You could find a list of all the environment variables that Firefox uses and then manually set them in the script...
You do not need the */1 bit in your crontab line, just use: * * * * * /usr/app/keepfront.sh to run something every minute.
You may wish to add some environment variables to the top of your crontab file - many people do for a variety of reasons. For instance the PATH in your crontab file probably won't be the same as your user PATH and your LANG variable won't be set either, this can stop regular expressions used in scripts called by cron from working. I have the following set at the top of my crontab file, like this:
# These are the basic paths, mine also includes my own scripts path.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Note: LANG allows grep regexes to work properly in called scripts.
LANG=en_GB.UTF-8
Hint: type echo $PATH and echo $LANG to get your current settings.
Typing env on your command line will show you all your environment variables, to see how limited those available to cron are, add this line to your crontab, don't forget to change the path I've used and to remove the line after it has run.
* * * * * env > /home/user/EnvOutputFromCrontab
Hope this helps.
One part of your problem is that this line doesn't do what you think it does:
WINCOUNT=wmctrl -l | grep -c "$WINTITLE"
It runs the command -l (which probably doesn't exist) with WINCOUNT=wmctrl as one of its environment variables.
You probably intended to write:
WINCOUNT=$(wmctrl -l | grep -c "$WINTITLE")
The other part of your problem may be that wmctrl and firefox don't work correctly when run without a terminal, as crontab runs its jobs without a terminal. I've not tried running firefox from crontab, and I can't think of anything much more annoying than having Firefox jump to the foreground every minute (OK; I can think of some things about equally annoying, but the concept doesn't bear thinking about).