Есть ли способ заставить Ubuntu не приостанавливать процесс загрузки?

Там в любом случае?

Как написать в /usr/lib/pm-utils/sleep.d Проверять ${downspeed eth0}, ${upspeed wlan0}, ${upspeed eth0} а также ${downspeed wlan0} и настроить систему не приостанавливать во время загрузки, а только выключать экран?

Моя ОС - Ubuntu 15.04.

3 ответа

Решение

Вдохновленный вторым комментарием @ByteCommanders, приведенный ниже скрипт выполняет то, что вы описываете: предполагая, что папка загрузок - это каталог, в который вы загружаете, он отключает приостановку во время загрузки и затем ждет пять минут (произвольно для установки), прежде чем снова включить приостановку, чтобы убедитесь, что загрузка действительно завершена.
Вы можете установить любой другой каталог для просмотра в качестве папки загрузки.

Как это устроено

В цикле (один раз в 20 секунд) скрипт проверяет размер целевой папки с помощью команды:

du -ks ~/Downloads

Скрипт сравнивает каждую проверку с последней, чтобы проверить активность загрузки (увеличение размера). Если в течение более пяти минут нет активности (но вы можете установить любое другое время ожидания), сценарий предполагает, что загрузка не происходит, и "нормальная" приостановка включена (повторно).

И наоборот: если скрипт видит увеличивающийся размер ~/Downloadsдиректории, она отключает приостановку до тех пор, пока не будет обнаружено никаких действий более пяти минут.

Мало сока

Команды скрипта чрезвычайно ограничены в ресурсах. Поскольку цикл выполняется только один раз в 20 секунд (как есть), загрузка процессора практически отсутствует.

Сценарий

#!/usr/bin/env python3
import subprocess
import time

#--- set suspend time below (seconds)
suspend_wait = 300
#---

#--- you can change values below, but I'd leave them as they are
speed_limit = 0      # set a minimum speed (kb/sec) to be considered a download activity
looptime = 20        # time interval between checks
download_wait = 300  # time (seconds) to wait after the last download activity before suspend is re- activated
#---

t = 0
key = ["gsettings", "get", "org.gnome.settings-daemon.plugins.power", "sleep-inactive-ac-timeout", "set"]

set_suspend = key[0]+" "+key[-1]+" "+(" ").join(key[2:4])
get_suspend = (" ").join(key[0:4])

def get_size():
    return int(subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8").split()[0])

def get(cmd):
    return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")

check_1 = int(get("du -ks ~/Downloads").split()[0])

while True:
    time.sleep(looptime)
    try:
        check_2 = int(get("du -ks ~/Downloads").split()[0])
    except subprocess.CalledProcessError:
        pass
    speed = int((check_2 - check_1)/looptime)
    # check current suspend setting
    suspend = get(get_suspend).strip()
    if speed > speed_limit:
        # check/set disable suspend if necessary
        if suspend != "0":
            subprocess.Popen(["/bin/bash", "-c", set_suspend+" 0"])
        t = 0
    else:
        if all([t > download_wait/looptime, suspend != str(download_wait)]):
            # check/enable suspend if necessary
            subprocess.Popen(["/bin/bash", "-c", set_suspend+" "+str(suspend_wait)])
    check_1 = check_2
    t = t+1

Как пользоваться

  1. Скопируйте приведенный ниже скрипт в пустой файл и сохраните его как no_suspend.py
  2. В разделе заголовка сценария установите желаемое "нормальное" время приостановки (поскольку сценарий повторно включит приостановку):

    #--- set suspend time below (seconds)
    suspend_wait = 300
    #---
    
  3. Если вы хотите, вы можете установить другие значения:

    #--- you can change values below, but I'd leave them as they are
    speed_limit = 0      # set a minimum speed (kb/sec) to be considered a download activity
    looptime = 20        # time interval between checks
    download_wait = 300  # time (seconds) to wait after the last download activity before suspend is re- activated
    #---
    
  4. Протестируйте скрипт с помощью команды:

    python3 /path/to/no_suspend.py
    
  5. Если все работает нормально, добавьте его в свои приложения запуска: Dash > Startup Applications > добавьте команду:

    python3 /path/to/no_suspend.py
    

ОБНОВЛЕНИЕ (2016-06-11): С момента написания первого скрипта он превратился в полноценную программу, которая определяет, когда приостановить, основываясь на

  1. Сетевой трафик
  2. Активность пользователей
  3. Загрузка процессора

Я опубликовал его на Launchpad здесь https://launchpad.net/keep.awake под лицензией GPL.

Там нет ни одного пакета оснастки или деба, но я в конце концов доберусь до него. В то же время вы можете скачать и распаковать его для использования.

Это работает как правильная команда.
Введите --help, чтобы увидеть полный список того, что можно сделать. Ниже приведены лишь несколько примеров:
./keepawake.py --help

Для интерактивного запуска:
./keepawake.py

Для запуска в качестве фоновой службы:
nohup ./keepawake.py -r > /dev/null 2>&1 &

Чтобы запустить в качестве фоновой службы и установить 15 минут (900 секунд) как время активности пользователя, прежде чем он определит, что пользователь находится в режиме ожидания:
nohup ./keepawake.py -u 900 -r > /dev/null 2>&1 &

Чтобы запустить в качестве фоновой службы и установить минимальную нагрузку на процессор как 13%:
nohup ./keepawake.py -c 13 -r > /dev/null 2>&1 &

Чтобы запустить в качестве фоновой службы и установить минимальный сетевой трафик 5 КБ (5120 байт):
nohup ./keepawake.py -s 5120 -r > /dev/null 2>&1 &

Чтобы запустить все три настройки выше (сеть, ЦП, режим ожидания пользователя) за один раз:

nohup ./keepawake.py -s 5120 -c 13 -u 900 -r > /dev/null 2>&1 &


[ОРИГИНАЛЬНАЯ ПОЧТА]:

Основываясь на ответе Дхии, я сильно изменил сценарий. Он обрабатывает как сетевой трафик, так и активность пользователей!

Я должен был назвать это как-то, поэтому я назвал это "Keep Awake".

Подарите ему ответ и ответьте, если у вас есть какие-либо вопросы или комментарии!

Примечания к выпуску...

  1. Проверяет активность пользователя и сетевой трафик на основе порогов
  2. Если один или оба значения превышают пороговые пределы, настройки приостановки питания ОС отключаются.
  3. Моя первая модификация кода привела его к Python 2.7.x Мне пришлось перенести его обратно на 3.4.x
  4. Реализована печать, которая идет как в файл журнала, так и в стандартный вывод с использованием возможностей Python 3.
  5. Добавлено много распечаток данных для определения состояния. Очень полезно для устранения неполадок.
  6. В логике If-elif-else я добавил счетчики обратного отсчета.
  7. Добавлено много комментариев, надеюсь, поможет новичкам во всем этом.
  8. Скомпоновали конфигурацию logrotate, которую вы можете использовать для управления журналами вывода бесконечно. (См. Комментарии в истории)
  9. Настоятельно рекомендуется переместить logrotate cron в cron.hourly
  10. Использует xprintidle
  11. logrotate config использует xz-utils
  12. Повторный тест производительности показал, что влияние на процессор практически ничтожно. Только алгоритм сжатия xz, запускаемый logrotate, может воздействовать на одно ядро ​​до 100%. Но это не длится долго на современном процессоре плюс он однопоточный. Так что ваши другие ядра могут выполнять другую работу. Он будет сжимать только журналы, которые имеют пару дней или более 20 МБ.
  13. Если вы довольны конфигурацией, вы можете настроить ее с помощью встроенного в дистрибутив запуска Startup Applications, который запустит программу при входе в вашу учетную запись. Убедитесь, что у вас есть logrotate, сконфигурированный с настройкой скрипта, для управления файлами журналов. Вы также можете настроить это в свое удовольствие.
  14. 16.09.2015 - версия 2.1 - Добавлена ​​логика Force Graceful Suspension
  15. 16/09/2015 - версия 2.1 - Программа теперь предназначена для запуска с привилегией sudo и войдите в /var/log/Keep.Awake/ . logrotate config теперь по умолчанию будет использовать многоядерную обработку для сжатия и будет вращаться только если больше 1M. Это требует xz-utils >= v5.2.0

Пример команды для запуска в фоновом режиме

    $ sudo nohup python3 Keep\ Awake.v2.py > /dev/null 2>&1 &

FILENAME: "Keep \ Awake.v2.py"

    #!/usr/bin/env python3

    import subprocess
    import time
    import logging
    import datetime
    import sys


    #--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    # Keep Awake
    # version: 2.1
    #
    # PURPOSE:
    # This program will check 'network traffic' AND 'user activity' and decide whether to enable the timer to suspend or cancel it.
    #
    # METHOD:
    # The program checks the network traffic if it is greater than a certain treshold; if so it keeps the system awake; if not it checks for user activity.
    # If the user activity is idle for a time greater than a treshold then it sets the timer to suspend.
    # 
    # SAMPLE RUN COMMAND:
    # sudo nohup python3 Keep\ Awake.v2.py > /dev/null 2>&1 &
    #
    # History:
    # 2015-08-22    DanglingPointer - Modified from https://Ask-ubuntu.ru/questions/576525/can-i-prevent-ubuntu-being-suspended-while-a-download-is-in-progress/661085#661085
    # 2015-09-12    DanglingPointer - Modified to version 2 and renamed "Keep Awake".  
    #                               - Version two now prints to standard output as well as a log file information useful for troubleshooting.
    #                               - Comes with a "Kee,Awake.v2.logrotate.config" file which can be used with linux logrotate.d.  It is recommended that logrotate be moved to cron.hourly.
    #                               - Upgraded coded from Python 2 to 3 using 2to3 command.
    #                               - Requires xprintidle linux package.
    # 2015-09-16    DanglingPointer - Modified to version 2.1.  Added logic to "gracefully force suspension" if automatic suspension fails to happen. This has been observed to happen when 
    #                               - the setting to require a password after suspension is enabled locking the desktop.  Keep.Awake.v2.1 will now send a dbus message to force graceful suspension.
    #                               - **NOTE 1** "Force Graceful suspension" will ONLY work in this version if the program is run as root (sudo privilege) after logging into a user account.
    #                               - **NOTE 2** "Force Graceful suspension" will NOT work if the program is sudo-run from command prompt without logging into a user desktop. (i.e. Fails when: run from CTL+ALT+F2 before login OR run from prompt after "switch user" is selected after locking desktop -> in that order)
    #--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


    # CONFIG
    suspend_wait    = 3600                              # set suspend time (seconds); In Ubuntu 14.04 it needs to be the equivalent of one of the options from the Power Settings or else it may not work.
    speed_limit     = 1024                              # set a minimum speed (bytes/second) to be considered a download activity
    looptime        = 20                                # time interval between checks (seconds)
    download_wait   = 300                               # time (seconds) to wait after the last download activity before suspend is re-activated.
    userIdle        = download_wait*1000                # user activity idle time in miliseconds before suspend is re-activated, requires xprintidle linux package
    forceGraceTime  = download_wait                     # time (seconds); in the event that the automatic suspend fails (like locked screen/user is at login screen) The system is given additional grace-time before a suspension is forced.
    logFileLocation = "/var/log/Keep.Awake/"            # Logfile location
    logFileName     = "Keep.Awake.log"                  # Logfile name

    # RATIOS
    download_waitTOlooptimeRatio    = download_wait/looptime
    suspend_waitTOlooptimeRatio     = suspend_wait/looptime
    forceGraceTimeTOlooptimeRatio   = forceGraceTime/looptime

    # STRING CONSTANTS
    key = ["gsettings", "get", "org.gnome.settings-daemon.plugins.power", "sleep-inactive-ac-timeout", "set"]
    dbusForceSuspend = ["dbus-send", "--print-reply", "--system", "--dest=org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower.Suspend"]

    # WHERE TO OUTPUT
    logging.basicConfig(level=logging.INFO, format='%(message)s')
    logger = logging.getLogger()
    logger.addHandler(logging.FileHandler(logFileLocation + logFileName, 'a'))
    print = logger.info

    # VARIALBES
    rx_speed=0                  # receive speed
    tx_speed=0                  # transmit speed
    t = 0                       # time interval interation count
    countDown = 0               # count down integer
    downLoadWaitCountDown = 0   # count down for download_wait
    graceCountDown = 0          # count down for forced grace time. See comments above for forceGraceTime CONFIG
    graceFlag = False           # flag to provide grace period
    set_suspend = key[0]+" "+key[-1]+" "+(" ").join(key[2:4])
    get_suspend = (" ").join(key[0:4])
    force_suspend = (" ").join(dbusForceSuspend)

    print ("")
    print (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    print ("KEEP AWAKE v2.1")
    print ("Python version: " + (sys.version))
    print ("")
    print ("Program Date-Time Start: " + datetime.datetime.now().isoformat())
    print ("Configuration Loaded...")
    print ("suspend_wait: "     + str(suspend_wait)     + " - Time in seconds for setting 'Suspend when inactive for' for the OS.")
    print ("speed_limit: "      + str(speed_limit)      + " - Minimum amount of data in bytes to qualify as activity.")
    print ("looptime: "         + str(looptime)         + " - Time interval in seconds between checks for network activity.")
    print ("download_wait: "    + str(download_wait)    + " - Time in seconds to wait after last download activity before 'suspend_wait' is applied to the OS.")
    print ("userIdle: "         + str(userIdle)         + " - Idle time in miliseconds to wait before 'suspend_wait' is applied to the OS.")
    print ("forceGraceTime: "   + str(forceGraceTime)   + " - Time in seconds; in the event that the automatic suspend fails (like locked screen/user is at login screen), the system is given additional grace-time before a suspension is forced.")
    print ("logFileLocation: "  + logFileLocation       + " - Logfile location")
    print ("logFileName: "      + logFileName           + " - Logfile name")
    print ("")
    print ("Variables Loaded...")
    print ("rx_speed: "         + str(rx_speed)         + " - Received bytes in last interval")
    print ("tx_speed: "         + str(tx_speed)         + " - Transmited bytes in last interval")
    print ("set_suspend: "      + set_suspend           + " - String used to construct Shell command to set the 'Suspend when inactive for' for the OS.")
    print ("get_suspend: "      + get_suspend           + " - String used to construct Shell command to get the 'Suspend when inactive for' setting from the OS.")
    print ("force_suspend: "    + force_suspend         + " - String used to construct Shell command to force the 'Suspend.")
    print ("\n\n")


    def get(cmd):
        return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")

    def get_bytes(t, iface='eth0'):
        with open('/sys/class/net/' + iface + '/statistics/' + t + '_bytes', 'r') as f:
            data = f.read();
        return int(data)

    if __name__ == '__main__':
        (tx_prev, rx_prev) = (0, 0)

        while(True):
            print ("Interval Loop Started:\t" + datetime.datetime.now().isoformat())

            tx = get_bytes('tx')
            rx = get_bytes('rx')

            if tx_prev > 0:
                tx_speed = tx - tx_prev


            if rx_prev > 0:
                rx_speed = rx - rx_prev

            print (str(tx_speed) + " bytes TRANSMITTED in since last interval.")
            print (str(rx_speed) + " bytes RECEIVED in since last interval.")
            print ("Starting nap for " + str(looptime) + " seconds...")

            time.sleep(looptime)

            print ("Awaking from nap:\t" + datetime.datetime.now().isoformat())

            tx_prev = tx
            rx_prev = rx

            speedrx =rx_speed/looptime

            print ("RECEIVE speed: " + str(speedrx) + " bytes/second")

            speedtx = tx_speed/looptime

            print ("TRANSMIT speed: " + str(speedtx) + " bytes/second")

            if speedtx > speedrx:
                speed = speedtx
            else:
                speed = speedrx

            print ("Highest speed selected: " + str(speed) + " bytes/second")

            suspend = get(get_suspend).strip()

            print ("Speed Limit configured: " + str(speed_limit) + " bytes/second"   )
            print ("'t'-value loop counter: " + str(t))
            print ("'download_wait'/'looptime': " + str(download_waitTOlooptimeRatio))
            print ("'suspend' value == " + suspend)

            idleTime = int(get("xprintidle"))

            print ("User activity idle time: " + str(idleTime/1000) + " seconds")
            print ("User activity idle threshold limit: " + str(userIdle/1000) + " seconds")

            if speed > speed_limit or userIdle >= idleTime:
                # check/set disable suspend if necessary
                if suspend != "0":
                    subprocess.Popen(["/bin/bash", "-c", set_suspend+" 0"])
                t = 0
                graceFlag = False
                print ("Threshold limits breached... keeping system awake...")

            elif t > download_waitTOlooptimeRatio:
                # check/enable suspend if necessary
                subprocess.Popen(["/bin/bash", "-c", set_suspend+" "+str(suspend_wait)])
                countDown = suspend_waitTOlooptimeRatio - (t - download_waitTOlooptimeRatio)

                # hack logic - if countDown goes below zero, and automatic sleep fails --> force suspend provide grace period.
                if countDown < 0 and not graceFlag:
                    graceCountDown = -(countDown - forceGraceTimeTOlooptimeRatio)
                    graceFlag = True

                    print ("FORCE SUSPEND: Expected automatic sleep did not happen. User desktop session likely locked to login screen.")
                    print ("FORCE SUSPEND: Providing grace time before forcing suspension.")
                    print ("FORCE SUSPEND: Counting-down to FORCED suspend..." + str(graceCountDown))

                    graceCountDown = graceCountDown - 1

                elif countDown < 0 and graceFlag:
                    print ("FORCE SUSPEND: Counting-down to FORCED suspend..." + str(graceCountDown))
                    graceCountDown = graceCountDown - 1

                    if graceCountDown < 0:
                        print ("FORCE SUSPEND: Force Suspending...")

                        # prime graceFlag to False in case it comes back up to the same conditions allowing a new grace time
                        graceFlag = False

                        # execute suspend command
                        subprocess.call(force_suspend, shell=True)
                else:
                    print ("Cumulative activity below threshold limits... Counting-down to suspend..." + str(countDown))

            else:
                downLoadWaitCountDown = download_waitTOlooptimeRatio - t
                print ("Zero activity... Waiting before setting suspension count down..." + str(downLoadWaitCountDown))

            t = t+1
            print ("Interval Loop End:\t" + datetime.datetime.now().isoformat())
            print ("---------------------------------------------------------")

logrotate пользовательский конфиг. Используйте "$man logrotate" для деталей его использования. Это очень удобно!... FILENAME: "Keep.Awake.v2.logrotate.config"

    /var/log/Keep.Awake/Keep.Awake.log
    {
            copytruncate
            size 1M
            rotate 30
            compress
            delaycompress
            compresscmd /usr/bin/xz
            compressext .xz
            compressoptions -9e --threads=0
            missingok
            notifempty
            extension .log
            create 664 root danglingpointer
            su root root
    }

Основываясь на ответе, предоставленном здесь, я изменил скрипт @Jacob Vlijm следующим образом, чтобы предотвратить приостановку Ubuntu во время любой загрузки или загрузки. Сначала вы должны установить xprintidle.

#!/usr/bin/env python3
#install xprintidle first, it is a binary written in C; see  https://packages.debian.org/sid/xprintidle 
#This script is for prevent/supersede suspend while a download/upload in progress.
#Change wlan0 (wifi) to eth0 (ethernet) or use both if its applies. 
#add it to your startup applications: Dash > Startup Applications > add the command: python3 /path/to/delay_suspend.py
import subprocess
import time
time.sleep(15)
subprocess.Popen(['notify-send', "Ubuntu will supersede suspend while a download/upload in progress"])    

#--- set suspend time below (seconds)
suspend_wait = 300
#---

#--- you can change values below, but I'd leave them as they are
speed_limit = 1000      # set a minimum speed (bytes/looptime) to be considered a download activity
looptime = 20       # time interval between checks
download_wait = 300  # time (seconds) to wait after the last download activity before suspend is re- activated
#---

rx_speed=0
tx_speed=0
speed=0
idletime = 2

t = 0
key = ["gsettings", "get", "org.gnome.settings-daemon.plugins.power", "sleep-inactive-ac-timeout", "set"]

set_suspend = key[0]+" "+key[-1]+" "+(" ").join(key[2:4])
get_suspend = (" ").join(key[0:4])

def get_size():
    return int(subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8").split()[0])

def get(cmd):
    return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")



def get_bytes(t, iface='wlan0'):
    with open('/sys/class/net/' + iface + '/statistics/' + t + '_bytes', 'r') as f:
        data = f.read();
    return int(data)

if __name__ == '__main__':
    (tx_prev, rx_prev) = (0, 0)
#Rx stand for received (download) and Tx for tranferred (upload).
    while(True):
        tx = get_bytes('tx')
        rx = get_bytes('rx')

        if tx_prev > 0:
            tx_speed = tx - tx_prev


        if rx_prev > 0:
            rx_speed = rx - rx_prev


        time.sleep(looptime)

        tx_prev = tx
        rx_prev = rx

        speedrx =rx_speed/looptime
        #print('RX: ', rx_speed, 'xxxxx')
        speedtx = tx_speed/looptime
        if speedtx > speedrx:
            speed = speedtx
        else:
            speed = speedrx


    # check current suspend setting
        suspend = get(get_suspend).strip()
        idletime = float(subprocess.check_output('xprintidle').strip())
        idletime=idletime/1000
        if speed > speed_limit:
            # check/set disable suspend if necessary
            if suspend != "0":
                subprocess.Popen(["/bin/bash", "-c", set_suspend+" 0"])

            if idletime >  download_wait-2*looptime:
                subprocess.Popen(['notify-send', "Postponed suspend due to active net traffic"]) 
                    #subprocess.Popen(['notify-send', str(speed) +"Postponed suspend for completion of active upload/download"+ str(speed_limit)])  
            t = 0
        else:
            if all([t > download_wait/looptime, suspend != str(download_wait)]):
                # check/enable suspend if necessary
                subprocess.Popen(["/bin/bash", "-c", set_suspend+" "+str(suspend_wait)])

        t = t+1
        #print(idletime)
        #print(speed)
        #print(speed_limit)        
        #subprocess.Popen(['notify-send', str(idletime)])
        #print('speed:', speed)
        #print('speed limit:', speed_limit)
Другие вопросы по тегам