I am trying to write a script in python which should change my desktop wallpaper on my raspberry pi. I am a beginner in both python and linux, have been stuck on this problem the whole day. Would love to hear from you guys <3
This is the terminal command which changes my desktop wallpaper:
pcmanfm --set-wallpaper /usr/share/rpd-wallpaper/wallpaper.jpg
Concerning only the linux terminal syntax: i would like to open a second terminal and run a command in it, all initiated from the first terminal. If i type into my first terminal:
pi#raspberrypi:~ $ lxterminal &
it opens a new terminal window which stays open, and is not a child process right? In this 2nd terminal my change wallpaper command works. The following command does not work and if i put a "&" next to gnome-terminal it opens a new terminal but does not execute the command that was specified with -e and gives me an error.
gnome-terminal -e 'bash -c \"pcmanfm --set-wallpaper /usr/share/rpd-wallpaper/wallpaper.jpg; exec bash\"'
How do you open a new terminal with a command passed with -e which is also not a child process?
I know you are new so I want to introduce some concepts to you before I can answer your question.
The "&" operator in shell/unix is not meant to open a new terminal. It is an operator that invokes unix's handy little job control protocol, which allows the parallelization of complex programs! It's awesome. It makes that command a background process, which basically means it starts a new shell (or "terminal" in the language of your OP) which runs that process and leaves you in control of your current shell (or terminal). The shell you are still in control of is called the foreground process.
now, what you have going on with gnome-terminal is a little more complicated. gnome-terminal is executing a bash terminal (which has a shell for each process you run inside it) in the GNOME environment. -e is the command you want to send to this terminal. So, you put the ampersand (&) at the end of that command if that is the command you desire to send to the background.
Now, let's look at the command you want to run:
gnome-terminal -e 'bash -c \"pcmanfm --set-wallpaper /usr/share/rpd-wallpaper/wallpaper.jpg; exec bash\"'
-e indicates the command you want to run in the new terminal. bash-c (commmand) is changing your wallpaper. Ok, cool. exec bash is probably any weird error thrown, if I had to guess. But that line should perform nothing at all.
What it sounds like to me is you don't really need to send anything to the background.
gnome-terminal -e 'bash -c \"pcmanfm --set-wallpaper /usr/share/rpd-wallpaper/wallpaper.jpg
should change your wallpaper. But, to answer the question completely, just place the & AFTER whichever command you wish to send in the background.
I am running an Instagram bot using python and selenium. I use a bash script to run a python script with the accounts credentials(Username, password, hashtags, etc...) I run multiple Instagrams so I have made multiple copies of this file. Is there a way to put this in a single file that I can click on and run?
To open multiple terminals running their assigned account?
I've already tried just to add them to one big file but the scripts wont run until the previous one finishes.
Also since I'm using selenium, trying multi threading in python is somewhat difficult but would not mind going that route if someone could point me to where I could start with that.
#!/bin/sh
cd PycharmProjects/InstaBot
python3 W.py
I highly recommend that everyone read about Bash Job Control.
Getting into multithreading is ridiculous overkill if your bottleneck has nothing to do with the CPU.
for script in PycharmProjects/InstaBot/*.py; do
python3 "$script" &
done
jobs
Only one process in shell can run in foreground mode. So the command gets executed only when the previous completes.
Adding "&" symbol at the end of the command line tells shell that the command should be executed in the background. This way the shell will start python and continue without waiting.
This will execute two instances simultaneously, but they will all output to the same terminal:
#!/bin/sh
cd PycharmProjects/InstaBot
python3 W.py first_credentials &
python3 W.py second_credentials &
You can use the same technique to start a new terminal process for each python script:
#!/bin/sh
cd PycharmProjects/InstaBot
gnome-terminal -e "python3 W.py first_credentials" &
gnome-terminal -e "python3 W.py second_credentials" &
I'm trying to make a Python script run as a service.
It need to work and run automatically after a reboot.
I have tried to copy it inside the init.d folder, But without any luck.
Can anyone help?(if it demands a cronjob, i haven't configured one before, so i would be glad if you could write how to do it)
(Running Centos)
run this command
crontab -e
and then add
#reboot /usr/bin/python /path/to/yourpythonscript
save and quit,then your python script will automatically run after you reboot
There is no intrinsic reason why Python should be different from any other scripting language here.
Here is someone else using python in init.d: blog.scphillips.com/posts/2013/07/… In fact, that deals with a lot that I don't deal with here, so I recommend just following that post.
For Ubuntu Variant:-
open the /etc/rc.local file with:
nano /etc/rc.local
add the following line just before the exit 0 line:
start-stop-daemon -b -S -x python /root/python/test.py
or
Give absolute path of your command i.e
nohup /usr/bin/python2 /home/kamran/auto_run_py_script_1.py &
The start-stop-daemon command creates a daemon to handle the execution of our program. The -b switch causes the program to be executed in the background. The -S switch tells the daemon to start our program. And the -x switch tells the daemon that our program is an executable.
To check and Run
sudo sh /etc/rc.local
I am trying to run a python script with chef, and the script will exit when chef exits because of SIGHUP. I am using nohup but it still gets the signal. Any ideas how I can get this script to run in the background?
nohup python simple-setup.py --dbpath /media/ephemeral0/mongo-data/ -n 2 --name dev --arbiters 1 --mongo_path /usr/bin/ > /media/ephemeral0/log/set.log 2>&1 &
I got round a problem like this by putting the command in a shell script, with an & on the end and then nohupping the shell script. If it helps.
I have Python script bgservice.py and I want it to run all the time, because it is part of the web service I build. How can I make it run continuously even after I logout SSH?
Run nohup python bgservice.py & to get the script to ignore the hangup signal and keep running. Output will be put in nohup.out.
Ideally, you'd run your script with something like supervise so that it can be restarted if (when) it dies.
If you've already started the process, and don't want to kill it and restart under nohup, you can send it to the background, then disown it.
Ctrl+Z (suspend the process)
bg (restart the process in the background
disown %1 (assuming this is job #1, use jobs to determine)
Running a Python Script in the Background
First, you need to add a shebang line in the Python script which looks like the following:
#!/usr/bin/env python3
This path is necessary if you have multiple versions of Python installed and /usr/bin/env will ensure that the first Python interpreter in your $$PATH environment variable is taken. You can also hardcode the path of your Python interpreter (e.g. #!/usr/bin/python3), but this is not flexible and not portable on other machines. Next, you’ll need to set the permissions of the file to allow execution:
chmod +x test.py
Now you can run the script with nohup which ignores the hangup signal. This means that you can close the terminal without stopping the execution. Also, don’t forget to add & so the script runs in the background:
nohup /path/to/test.py &
If you did not add a shebang to the file you can instead run the script with this command:
nohup python /path/to/test.py &
The output will be saved in the nohup.out file, unless you specify the output file like here:
nohup /path/to/test.py > output.log &
nohup python /path/to/test.py > output.log &
If you have redirected the output of the command somewhere else - including /dev/null - that's where it goes instead.
# doesn't create nohup.out
nohup command >/dev/null 2>&1
If you're using nohup, that probably means you want to run the command in the background by putting another & on the end of the whole thing:
# runs in background, still doesn't create nohup.out
nohup command >/dev/null 2>&1 &
You can find the process and its process ID with this command:
ps ax | grep test.py
# or
# list of running processes Python
ps -fA | grep python
ps stands for process status
If you want to stop the execution, you can kill it with the kill command:
kill PID
You could also use GNU screen which just about every Linux/Unix system should have.
If you are on Ubuntu/Debian, its enhanced variant byobu is rather nice too.
You might consider turning your python script into a proper python daemon, as described here.
python-daemon is a good tool that can be used to run python scripts as a background daemon process rather than a forever running script. You will need to modify existing code a bit but its plain and simple.
If you are facing problems with python-daemon, there is another utility supervisor that will do the same for you, but in this case you wont have to write any code (or modify existing) as this is a out of the box solution for daemonizing processes.
Alternate answer: tmux
ssh into the remote machine
type tmux into cmd
start the process you want inside the tmux e.g. python3 main.py
leaving the tmux session by Ctrl+b then d
It is now safe to exit the remote machine. When you come back use tmux attach to re-enter tmux session.
If you want to start multiple sessions, name each session using Ctrl+b then $. then type your session name.
to list all session use tmux list-sessions
to attach a running session use tmux attach-session -t <session-name>.
You can nohup it, but I prefer screen.
Here is a simple solution inside python using a decorator:
import os, time
def daemon(func):
def wrapper(*args, **kwargs):
if os.fork(): return
func(*args, **kwargs)
os._exit(os.EX_OK)
return wrapper
#daemon
def my_func(count=10):
for i in range(0,count):
print('parent pid: %d' % os.getppid())
time.sleep(1)
my_func(count=10)
#still in parent thread
time.sleep(2)
#after 2 seconds the function my_func lives on is own
You can of course replace the content of your bgservice.py file in place of my_func.
Try this:
nohup python -u <your file name>.py >> <your log file>.log &
You can run above command in screen and come out of screen.
Now you can tail logs of your python script by: tail -f <your log file>.log
To kill you script, you can use ps -aux and kill commands.
The zsh shell has an option to make all background processes run with nohup.
In ~/.zshrc add the lines:
setopt nocheckjobs #don't warn about bg processes on exit
setopt nohup #don't kill bg processes on exit
Then you just need to run a process like so: python bgservice.py &, and you no longer need to use the nohup command.
I know not many people use zsh, but it's a really cool shell which I would recommend.
If what you need is that the process should run forever no matter whether you are logged in or not, consider running the process as a daemon.
supervisord is a great out of the box solution that can be used to daemonize any process. It has another controlling utility supervisorctl that can be used to monitor processes that are being run by supervisor.
You don't have to write any extra code or modify existing scripts to make this work. Moreover, verbose documentation makes this process much simpler.
After scratching my head for hours around python-daemon, supervisor is the solution that worked for me in minutes.
Hope this helps someone trying to make python-daemon work
You can also use Yapdi:
Basic usage:
import yapdi
daemon = yapdi.Daemon()
retcode = daemon.daemonize()
# This would run in daemon mode; output is not visible
if retcode == yapdi.OPERATION_SUCCESSFUL:
print('Hello Daemon')