I have a script that checks something on my PC every 5 minutes and I don’t want Python to show on my task tray. I use Windows as my operating system.
Is there any way to make Python run in the background and force it to not show in my task tray?
Xetnus
3532 gold badges4 silver badges13 bronze badges
asked Apr 23, 2009 at 21:07
If you run a console script using pythonw.exe
, it will neither display a window nor appear in the task bar. For example, I use the following command to launch ntlmaps on startup:
C:BenBlankPython2.6pythonw.exe scripts/ntlmaps
Be aware, however, that there is no way to interact with the script, nor to terminate it save via the Task Manager.
answered Apr 23, 2009 at 21:15
Ben BlankBen Blank
53.9k27 gold badges132 silver badges153 bronze badges
3
Just another option you have:
You can create a shortcut to your Python script, then right-click the shortcut --> Properties --> Shortcut tab
There is a drop-down box under the Run option which lets you run the command minimized.
answered Apr 23, 2009 at 21:17
Jason CoonJason Coon
17.3k10 gold badges41 silver badges50 bronze badges
1
You could run it as a service. See here
answered May 1, 2009 at 8:07
dugresdugres
12.4k8 gold badges45 silver badges50 bronze badges
0
cron it on linux; schedule it on windows [control panel > scheduled tasks > Add scheduled task]
S.Lott
380k79 gold badges505 silver badges775 bronze badges
answered Apr 23, 2009 at 21:10
MahdeToMahdeTo
10.9k2 gold badges26 silver badges27 bronze badges
1
To Run python file from any where :
Step 1:
Create Shortcut of Python File.
Step 2:
Place Shortcut in this location C:ProgramDataMicrosoftWindowsStart MenuPrograms
Step 3:
Now Right Click --> Go to Properties --> Shortcut --> Press any key on keyboard it will take one shortcut key
Step 4:
Now , Type the Shortcut key which you entered in previous step.
Step 5:
Check out Output! :)
answered Jun 29, 2020 at 5:05
Be ChampzzBe Champzz
3012 silver badges4 bronze badges
Look for Schedule Tasks in the control panel.
answered Apr 23, 2009 at 21:11
David BergerDavid Berger
12.1k6 gold badges38 silver badges51 bronze badges
3
I have a script that checks something on my PC every 5 minutes and I don’t want Python to show on my task tray. I use Windows as my operating system.
Is there any way to make Python run in the background and force it to not show in my task tray?
Xetnus
3532 gold badges4 silver badges13 bronze badges
asked Apr 23, 2009 at 21:07
If you run a console script using pythonw.exe
, it will neither display a window nor appear in the task bar. For example, I use the following command to launch ntlmaps on startup:
C:BenBlankPython2.6pythonw.exe scripts/ntlmaps
Be aware, however, that there is no way to interact with the script, nor to terminate it save via the Task Manager.
answered Apr 23, 2009 at 21:15
Ben BlankBen Blank
53.9k27 gold badges132 silver badges153 bronze badges
3
Just another option you have:
You can create a shortcut to your Python script, then right-click the shortcut --> Properties --> Shortcut tab
There is a drop-down box under the Run option which lets you run the command minimized.
answered Apr 23, 2009 at 21:17
Jason CoonJason Coon
17.3k10 gold badges41 silver badges50 bronze badges
1
You could run it as a service. See here
answered May 1, 2009 at 8:07
dugresdugres
12.4k8 gold badges45 silver badges50 bronze badges
0
cron it on linux; schedule it on windows [control panel > scheduled tasks > Add scheduled task]
S.Lott
380k79 gold badges505 silver badges775 bronze badges
answered Apr 23, 2009 at 21:10
MahdeToMahdeTo
10.9k2 gold badges26 silver badges27 bronze badges
1
To Run python file from any where :
Step 1:
Create Shortcut of Python File.
Step 2:
Place Shortcut in this location C:ProgramDataMicrosoftWindowsStart MenuPrograms
Step 3:
Now Right Click --> Go to Properties --> Shortcut --> Press any key on keyboard it will take one shortcut key
Step 4:
Now , Type the Shortcut key which you entered in previous step.
Step 5:
Check out Output! :)
answered Jun 29, 2020 at 5:05
Be ChampzzBe Champzz
3012 silver badges4 bronze badges
Look for Schedule Tasks in the control panel.
answered Apr 23, 2009 at 21:11
David BergerDavid Berger
12.1k6 gold badges38 silver badges51 bronze badges
3
On Windows, you can use pythonw.exe
in order to run a python script as a background process:
Python scripts (files with the extension
.py
) will be executed by
python.exe
by default. This executable opens a terminal, which stays
open even if the program uses a GUI. If you do not want this to
happen, use the extension.pyw
which will cause the script to be
executed bypythonw.exe
by default (both executables are located in
the top-level of your Python installation directory). This suppresses
the terminal window on startup.
For example,
C:ThanosDoddPython3.6pythonw.exe C:\PythonScriptsmoveDLs.py
In order to make your script run continuously, you can use sched
for event scheduling:
The sched module defines a class which implements a general purpose
event scheduler
import sched
import time
event_schedule = sched.scheduler(time.time, time.sleep)
def do_something():
print("Hello, World!")
event_schedule.enter(30, 1, do_something, (sc,))
event_schedule.enter(30, 1, do_something, (s,))
event_schedule.run()
Now in order to kill a background process on Windows, you simply need to run:
taskkill /pid processId /f
Where processId
is the ID of the process you want to kill.
I have a python script that’s run in the systray (WINDOWS), but when I use the pyinstaller2.0, it opens in systray, but also opens my console.
This script doesn’t involve graphics, but I need it to run in background and preferably not open the console.
thanks in advance!
- python
- windows
- python-2.7
- console
A.Wan
1,7283 gold badges19 silver badges33 bronze badges
asked Jul 23, 2013 at 15:25
Marcos BergamoMarcos Bergamo
1,0332 gold badges11 silver badges19 bronze badges
3
-
You can run it as a windows service. You would need to read the docs on how to do that though.
Jul 23, 2013 at 15:35
-
@GamesBrainiac I read the documentation about this, but don’t understand the implementation. but I trying again!
Jul 23, 2013 at 15:37
I have a python script that’s run in the systray (WINDOWS), but when I use the pyinstaller2.0, it opens in systray, but also opens my console.
This script doesn’t involve graphics, but I need it to run in background and preferably not open the console.
thanks in advance!
- python
- windows
- python-2.7
- console
A.Wan
1,7283 gold badges19 silver badges33 bronze badges
asked Jul 23, 2013 at 15:25
Marcos BergamoMarcos Bergamo
1,0332 gold badges11 silver badges19 bronze badges
3
-
You can run it as a windows service. You would need to read the docs on how to do that though.
Jul 23, 2013 at 15:35
-
@GamesBrainiac I read the documentation about this, but don’t understand the implementation. but I trying again!
Jul 23, 2013 at 15:37
Сценарий мониторинга test1.py, написанный на python, работает в режиме True. Когда ssh удален (с помощью терминала замазки), запустите сценарий с помощью следующей команды:
python test1.py &
Теперь сценарий работает нормально, вы можете увидеть номер процесса через ps, в это время непосредственно закройте терминал ssh (не используя команду выхода, но непосредственно через кнопку закрытия putty), после входа в систему снова и найденный Процесс уже завершен.
Проблема была решена путем запуска в фоновом режиме, и ее можно суммировать здесь, чтобы я мог обратиться к ней позже.
бегать в фоновом режиме под окнами
Под окнами нет глубоких исследований. Метод, который я часто использую, заключается в изменении расширения скрипта Python «.pyw». Двойной щелчок запускается в фоновом режиме без изменения кода.
Запустите в фоновом режиме под Linux
Через вилку
В среде Linux процесс демона в c реализован с помощью fork, и python также может быть реализован таким образом. Пример кода следующий:
#!/usr/bin/env python
import time,platform
import os
def funzioneDemo():
# Это пример конкретной бизнес-функции
fout = open('/tmp/demone.log', 'w')
while True:
fout.write(time.ctime()+'n')
fout.flush()
time.sleep(2)
fout.close()
def createDaemon():
# форк процесс
try:
if os.fork() > 0: os._exit(0)
except OSError, error:
print 'fork #1 failed: %d (%s)' % (error.errno, error.strerror)
os._exit(1)
os.chdir('/')
os.setsid()
os.umask(0)
try:
pid = os.fork()
if pid > 0:
print 'Daemon PID %d' % pid
os._exit(0)
except OSError, error:
print 'fork #2 failed: %d (%s)' % (error.errno, error.strerror)
os._exit(1)
# Перенаправить стандартный IO
sys.stdout.flush()
sys.stderr.flush()
si = file("/dev/null", 'r')
so = file("/dev/null", 'a+')
se = file("/dev/null", 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# Выполнить код в дочернем процессе
funzioneDemo() # function demo
if __name__ == '__main__':
if platform.system() == "Linux":
createDaemon()
else:
os._exit(0)
Через выскочку
Приложение может быть упаковано как системная служба через upstart, и полный пример прямо записан здесь.
1. Напишите скрипт на Python
[[email protected] t27]# cat test123.py
#!/usr/bin/env python
import os,time
while True :
print time.time()
time.sleep(1)
2. Напишите файл конфигурации upstat
[[email protected] t27]# cat /etc/init/mikeTest.conf
description "My test"
author "[email protected]"
start on runlevel [234]
stop on runlevel [0156]
chdir /test/t27
exec /test/t27/test123.py
respawn
- 3. Перезагрузить северную часть штата
initctl reload-configuration
- 4. Запустите сервис
[[email protected] t27]# start mikeTest
mikeTest start/running, process 6635
[[email protected] t27]# ps aux | grep test123.py
root 6635 0.0 0.0 22448 3716 ? Ss 09:55 0:00 python /test/t27/test123.py
root 6677 0.0 0.0 103212 752 pts/1 S+ 09:56 0:00 grep test123.py
- 5. Стоп сервис
[[email protected] t27]# stop mikeTest
mikeTest stop/waiting
[[email protected] t27]# ps aux | grep test123.py
root 6696 0.0 0.0 103212 752 pts/1 S+ 09:56 0:00 grep test123.py
[[email protected] t27]#
Скрипт bash
1. код Python
[[email protected] test]# cat test123.py
#!/usr/bin/env python
import os,time
while True :
print time.time()
time.sleep(1)
- 2. Написать скрипт запуска
[[email protected] test]# cat start.sh
#! /bin/sh
python test123.py &
- 3. Запустите процесс
[[email protected] test]#./start.sh
Если вы используете & для запуска процесса напрямую:
python test123.py &
Непосредственное закрытие терминала ssh приведет к завершению процесса.
Через экран, tmux и т. Д.
Если вы временно запустите программу, вы можете запустить программу через screen, tmux, здесь описывается, как запускается tmux.
1. Запустите tmux
Введите tmux в терминал, чтобы начать
2. Запустите программу в tmux
Просто выполните следующую команду напрямую (ссылка на скрипт выше): python test123.py
3. Закройте терминал ssh напрямую (например, кнопку закрытия на замазке);
4. После перезапуска ssh выполните следующую команду:
tmux attach
- Теперь вы можете видеть, что программа на python все еще работает нормально.
Содержание:
- Асинхронное выполнение с помощью инкрементной итерации;
- Запуск команды в фоновом процессе;
- Использование обратных вызовов с фоновым процессом;
- Интерактивные обратные вызовы;
- Обратный вызов при завершении команды.
Асинхронное выполнение с помощью инкрементной итерации.
from sh import tail # цикл будет работать вечно (если не поставить # таймаут или убить процесс сигналом) for line in tail("-f", "/var/log/some_log_file.log", _iter=True): print(line)
По умолчанию ключевой аргумент _iter
повторяет STDOUT, но можно изменить этот параметр, передав либо 'err'
, либо 'out'
(вместо True
). Кроме того, по умолчанию, выходные данные буферизуются строками, поэтому тело цикла будет выполняться только тогда, когда процесс создает новую строку. Вы можете изменить это, изменив размер буфера вывода команды с помощью _out_bufsize
.
Примечание. Если нужен полностью неблокирующий итератор, то используйте специальный ключевой аргумент _iter_noblock
. Если текущая итерация будет заблокирована, то будет возвращен errno.EWOULDBLOCK
, в противном случае получите кусок вывода.
Запуск команды в фоновом процессе.
По умолчанию каждая запущенная команда терминала через модуль sh
блокируется до завершения. Если какая-то команда выполняется длительное время, то можно запустить ее в фоновом режиме с помощью специального ключевого аргумента _bg=True
:
import sh # блокирующий вызов sh.sleep(3) print("...3 секунды спустя") # НЕ блокирующий вызов p = sh.sleep(3, _bg=True) print("печать сразу после запуска!") # ждем завершения `sh.sleep` p.wait() print("...и 3 секунды спустя")
Наверное заметили, чтобы возвратить результат после выхода из команды нужно вызвать метод RunningCommand.wait()
.
Команды, запущенные в фоновом режиме, игнорируют SIGHUP
, это означает, что когда их контролирующий процесс (лидер сеанса, если есть управляющий терминал) завершается, то ядро не сигнализирует о их завершении. Но поскольку команды модуля sh
по умолчанию запускают свои процессы в своих собственных сеансах, то есть они сами являются лидерами сеансов, игнорирование SIGHUP
обычно не оказывает никакого влияния. Таким образом, единственный случай, когда игнорирование SIGHUP
будет делать что-либо, — это использование ключевого аргумента _new_session=False
, и в этом случае контролирующим процессом, вероятно, будет оболочка, из которой запустили python, и выход из этой оболочки обычно отправляет SIGHUP
всем дочерним процессам.
Использование обратных вызовов с фоновым процессом.
В сочетании с _bg=True
, модуль sh
может использовать обратные вызовы для постепенной обработки выходных данных, передавая вызываемую функцию в ключевые аргументы _out
и/или _err
. Этот вызываемый объект будет вызываться для каждой строки (или фрагмента) данных, которые выводит команда терминала:
from sh import tail # обратный вызов def process_output(line): print(line) p = tail("-f", "/var/log/some_log_file.log", _out=process_output, _bg=True) p.wait()
Чтобы указать, получает ли обратный вызов строку или фрагмент, используйте ключевой аргумент _out_bufsize
. Чтобы «выйти» из обратного вызова, необходимо, что бы функция обратного вызова возвратила True
. Это говорит команде больше не вызывать функцию обратного вызова.
Примечание. Возврат True
не убивает процесс, он только предотвращает повторный вызов обратного вызова. Смотрите «Интерактивные обратные вызовы», чтобы узнать, как убить процесс из обратного вызова.
Интерактивные обратные вызовы.
Команды, вызываемые при помощи модуля sh
могут взаимодействовать с базовым процессом в интерактивном режиме через определенную сигнатуру обратного вызова. Каждая команда, запущенная через sh
, имеет внутреннюю очередь STDIN
, которую можно использовать из обратных вызовов:
import sh def interact(line, stdin): if line == "Какова... скорость ласточки?": stdin.put("Африканская или европейская ласточка?") elif line == "Хм? Я ... этого не знаю": cross_bridge() return True else: stdin.put("Я не знаю.... AAGGHHHHH") return True p = sh.bridgekeeper(_out=interact, _bg=True) p.wait()
Примечание. Если используете очередь, то можно сигнализировать об окончании ввода (EOF) с помощью значения очереди None
.
Можно также убить или завершить процесс или отправить любой сигнал, из обратного вызова, добавив третий аргумент в callback функцию для получения объекта процесса:
import sh def process_output(line, stdin, process): print(line) if "ERROR" in line: process.kill() return True p = sh.tail("-f", "/var/log/some_log_file.log", _out=process_output, _bg=True)
Приведенный выше код будет выполняться, печатая строки из some_log_file.log
до тех пор, пока в строке не появится слово 'ERROR'
, после чего процесс команды tail
будет убит и сценарий завершится.
Примечание. Можно также использовать RunningCommand.terminate()
для отправки SIGTERM
или RunningCommand.signal()
для отправки другого сигнала.
Обратный вызов при завершении команды.
Функция обратного вызова, переданная ключевому аргументу с именем _done
вызывается, когда процесс завершается, либо обычно (через успешный или ошибочный код выхода), либо через сигнал.
Вот пример использования ключевого аргумента _done
для создания многопроцессорного пула, где sh.your_parallel_command
выполняется одновременно не более 10 раз:
import sh from threading import Semaphore pool = Semaphore(10) def done(cmd, success, exit_code): pool.release() def do_thing(arg): pool.acquire() return sh.your_parallel_command(arg, _bg=True, _done=done) procs = [] for arg in range(100): procs.append(do_thing(arg)) [p.wait() for p in procs]
Я создал скрипт, который перемещает файлы из одной папки в другую. Но поскольку исходная папка является папкой «Загрузки», мне нужно, чтобы она всегда работала в фоновом режиме.
У меня также есть стандартный пакетный файл, который выглядит примерно так:
@py C:\PythonScriptsmoveDLs.py %*
Я использую Windows 10 . Я нашел информацию для Linux и OS о том, как использовать nohup
в командном файле. Есть ли версия для Windows?
Если есть, нужно ли выполнять скрипт каждый раз при перезагрузке или включении ПК?
Кроме того, как вы прекращаете процесс, когда вам удается сделать его постоянным?
Огромное спасибо
3 ответа
Лучший ответ
В Windows вы можете использовать pythonw.exe
по порядку для запуска скрипта Python в качестве фонового процесса:
Скрипты Python (файлы с расширением
.py
) будут выполнятьсяpython.exe
по умолчанию. Этот исполняемый файл открывает терминал, который остается открывать, даже если программа использует графический интерфейс. Если вы не хотите случится, используйте расширение.pyw
, которое заставит скрипт быть выполняетсяpythonw.exe
по умолчанию (оба исполняемых файла находятся в верхний уровень каталога установки Python). Это подавляет окно терминала при запуске.
Например,
C:ThanosDoddPython3.6pythonw.exe C:\PythonScriptsmoveDLs.py
Чтобы ваш скрипт работал непрерывно, вы можете использовать sched
для планирования мероприятий:
Модуль sched определяет класс, который реализует планировщик событий общего назначения.
import sched
import time
event_schedule = sched.scheduler(time.time, time.sleep)
def do_something():
print("Hello, World!")
event_schedule.enter(30, 1, do_something, (sc,))
event_schedule.enter(30, 1, do_something, (s,))
event_schedule.run()
Теперь, чтобы убить фоновый процесс в Windows, вам нужно просто запустить:
taskkill /pid processId /f
Где processId
— это идентификатор процесса, который вы хотите убить.
12
Giorgos Myrianthous
19 Сен 2020 в 00:05
Я нашел решение, которое работает:
import shutil, os, time
while True:
for filename in os.listdir('folderToMoveFrom'):
if filename.endswith((desired file extensions)):
shutil.move( (folderToMoveFrom + filename), folderToMoveTo)
time.sleep(6)
Если вы выполнили приведенный выше код без функции time.sleep (), программа вылетает после того, как новый файл входит в папку из-за ошибки «файл не найден», вложенной в другую ошибку «файл не найден». Не уверен, о чем идет речь, но я доволен тем, что у меня есть до сих пор. Единственное, что вам нужно сделать сейчас, это добавить скрипт в планировщик задач для запуска под Pythonw, чтобы он работал как фоновый процесс. Или вместо запуска сценария вы можете запустить командный файл, если не забываете добавить соответствующую инструкцию для pythonw. Вы должны начать процесс только один раз, конечно.
1
Thanos Dodd
4 Дек 2019 в 16:36
Одним из вариантов является изменение вашего сценария, чтобы он работал непрерывно, а не многократно. Просто оберните все это во время цикла и добавьте сон.
import time
while True:
your_script_here
time.sleep(300)
Чтобы убедиться, что это запускается на машине, и для обеспечения автоматического перезапуска в случае возникновения исключительной ситуации, я бы рекомендовал сделать это службой Windows с помощью диспетчера службы не-сосания (www.nssm.cc). Для этого есть несколько шагов (см. Документацию), но после этого ваш скрипт станет просто еще одной службой Windows, которую вы можете запускать и останавливать с помощью стандартной утилиты services.msc.
1
SimonN
1 Дек 2019 в 14:01
Оба захватывают вывод и запускаются в фоновом режиме с threading
Как упоминалось на этот ответ, если вы захватите вывод с помощью stdout=
а затем попробуйте read()
, то процесс блокируется.
Однако есть случаи, когда вам это нужно. Например, я хотел запустить два процесса, которые обмениваются данными через порт между собой, и сохраните их стандартный вывод в файл журнала и стандартный вывод.
Компания threading
модуль позволяет нам это делать.
Во-первых, посмотрите, как выполнить только часть перенаправления вывода в этом вопросе: Python Popen: запись в стандартный вывод и файл журнала одновременно
Тогда:
main.py
#!/usr/bin/env python3
import os
import subprocess
import sys
import threading
def output_reader(proc, file):
while True:
byte = proc.stdout.read(1)
if byte:
sys.stdout.buffer.write(byte)
sys.stdout.flush()
file.buffer.write(byte)
else:
break
with subprocess.Popen(['./sleep.py', '0'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc1,
subprocess.Popen(['./sleep.py', '10'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc2,
open('log1.log', 'w') as file1,
open('log2.log', 'w') as file2:
t1 = threading.Thread(target=output_reader, args=(proc1, file1))
t2 = threading.Thread(target=output_reader, args=(proc2, file2))
t1.start()
t2.start()
t1.join()
t2.join()
сон.ру
#!/usr/bin/env python3
import sys
import time
for i in range(4):
print(i + int(sys.argv[1]))
sys.stdout.flush()
time.sleep(0.5)
После запуска:
./main.py
stdout обновляется каждые 0.5 секунды для каждых двух строк, содержащих:
0
10
1
11
2
12
3
13
и каждый файл журнала содержит соответствующий журнал для данного процесса.
Вдохновленный: https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/
Проверено на Ubuntu 18.04, Python 3.6.7.