如何在启动时自动运行脚本?

Posted

技术标签:

【中文标题】如何在启动时自动运行脚本?【英文标题】:How to run script automatically on boot? 【发布时间】:2017-03-18 20:48:40 【问题描述】:

我有一个监控 USB 端口的 Python 脚本(检查连接了哪些设备)。该脚本执行一些抓取并显示桌面通知。我希望它在每次启动时自动运行。这是代码:

#! /usr/bin/python

import glib
import re
import subprocess
import requests
import bs4
import datetime
import sys
import os
import time
from selenium import webdriver
from pyudev import Context, Monitor
from selenium.common.exceptions import NoSuchElementException

def demote():
    def result():
        os.setgid(100)
        os.setuid(1000)
    return result

def inotify(title, message):
    subprocess.call(['notify-send', '\n'.format(title), '0\n'.format(message)], preexec_fn=demote())
    #os.system('notify-send ' + title + ' ' + message)

def get_network_data(tout):
    """Scrapes balance data from ISP website."""

    if tout is not None:
        try:
        # Do some scraping
            if data_found:
                full_msg = '0\n1'.format(my_balance.capitalize(), airtime_balance.capitalize())
                inotify('My Balance', full_msg)
                #subprocess.call(['notify-send', 'My Balance', '\n0\n1'.format(my_balance.capitalize(), airtime_balance.capitalize())], preexec_fn=demote())

            else:
                print('Could not retrieve data from page...')
                full_msg = '0'.format('Error: Could not retrieve data from page.')
                inotify('My Balance', full_msg)
                #subprocess.call(['notify-send', 'My Balance', '\n0'.format('Error: Could not retrieve data from page.')], preexec_fn=demote())

        except NoSuchElementException:
            print('Could not locate element...')
            full_msg = '0'.format('Error: Could not locate element - acc.')
            inotify('My Balance', full_msg)
            #subprocess.call(['notify-send', 'iMonitor:get_network_data', '\n0'.format('Error: Could not locate element - acc.')], preexec_fn=demote())

    else:
        print('Could not find USB device...')
        full_msg = '\n0'.format('Error: Could not find USB device.')
        inotify('My Balance', full_msg)
        #subprocess.call(['notify-send', 'iMonitor', '\n0'.format('Error: Could not find USB device.')], preexec_fn=demote())

def identify_phone(observer, device):
    """Identifies if specific USB device (phone) is connected (tethered)."""

    global last_updated, initial_search, msg_count

    current_time = datetime.datetime.now()
    time_diff = current_time - last_updated

    if (time_diff.seconds > 300) or initial_search:
        try:
            time.sleep(0.25)
            tout = subprocess.check_output("lsusb | grep 1234:5678", shell=True)
        except subprocess.CalledProcessError:
            tout = None

        last_updated = datetime.datetime.now()
        initial_search = False

        get_network_data(tout)

    if time_diff.seconds > 10:
        msg_count = 1

    if not initial_search and msg_count == 1:
        wait_time = datetime.datetime.fromtimestamp(600 - time_diff.seconds)
        message = wait_time.strftime('You may have to wait %-M minute(s), %-S second(s) before another check is done.')
        print('Could not retrieve data from page...')
        full_msg = '\n0'.format(message)
        inotify('My Balance', full_msg)
        #subprocess.call(['notify-send', 'iMonitor:Identify Phone', '\n0'.format(message)], preexec_fn=demote())
        msg_count += 1

try:
    initial_search = True
    last_updated = datetime.datetime.now()
    msg_count = 1
    try:
        from pyudev.glib import MonitorObserver

    except ImportError:
        from pyudev.glib import GUDevMonitorObserver as MonitorObserver

    context = Context()
    monitor = Monitor.from_netlink(context)

    monitor.filter_by(subsystem='usb')
    observer = MonitorObserver(monitor)

    observer.connect('device-added', identify_phone)
    monitor.start()

    glib.MainLoop().run()

except KeyboardInterrupt:
    print('\nShutdown requested.\nExiting gracefully...')
    sys.exit(0)

但是,脚本以 root 身份运行,并且在尝试更改 uid 和 guid 后,我没有设法让它向登录的(普通)用户显示桌面通知。任何帮助将不胜感激。

PS: 操作系统 - OpenSUSE 42.1 KDE 版本 - KDE Plasma 5.5.5

【问题讨论】:

这个问题最好在Linux site上回答。 我已经编辑了问题 【参考方案1】:

我假设您需要脚本在 KDE 中运行,在这种情况下,您可以简单地将脚本复制或链接到 KDE 4 中的 ~/.kde/Autostart/ 目录。在 KDE 5 中,该目录已移至 ~/.config/autostart

【讨论】:

那个文件夹不存在 根据KDE documentation在KDE5中目录已经移动到~/.config/autostart【参考方案2】:

我猜你可以使用带有@reboot修饰符的cron作业。它会在您的系统每次启动时运行。

【讨论】:

cron 作业以 root 身份运行

以上是关于如何在启动时自动运行脚本?的主要内容,如果未能解决你的问题,请参考以下文章

如何让一个脚本在开机后自动运行

如何避免Docker容器启动脚本运行后自动退出

如何避免Docker容器启动脚本运行后自动退出

Docker容器启动后如何自动运行脚本

Linux系统如何设置开机自动运行脚本?

Linux下开机启动脚本程序