Есть ли способ заставить 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
Как пользоваться
- Скопируйте приведенный ниже скрипт в пустой файл и сохраните его как
no_suspend.py
В разделе заголовка сценария установите желаемое "нормальное" время приостановки (поскольку сценарий повторно включит приостановку):
#--- 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 #---
Протестируйте скрипт с помощью команды:
python3 /path/to/no_suspend.py
Если все работает нормально, добавьте его в свои приложения запуска: Dash > Startup Applications > добавьте команду:
python3 /path/to/no_suspend.py
ОБНОВЛЕНИЕ (2016-06-11): С момента написания первого скрипта он превратился в полноценную программу, которая определяет, когда приостановить, основываясь на
- Сетевой трафик
- Активность пользователей
- Загрузка процессора
Я опубликовал его на 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".
Подарите ему ответ и ответьте, если у вас есть какие-либо вопросы или комментарии!
Примечания к выпуску...
- Проверяет активность пользователя и сетевой трафик на основе порогов
- Если один или оба значения превышают пороговые пределы, настройки приостановки питания ОС отключаются.
- Моя первая модификация кода привела его к Python 2.7.x Мне пришлось перенести его обратно на 3.4.x
- Реализована печать, которая идет как в файл журнала, так и в стандартный вывод с использованием возможностей Python 3.
- Добавлено много распечаток данных для определения состояния. Очень полезно для устранения неполадок.
- В логике If-elif-else я добавил счетчики обратного отсчета.
- Добавлено много комментариев, надеюсь, поможет новичкам во всем этом.
- Скомпоновали конфигурацию logrotate, которую вы можете использовать для управления журналами вывода бесконечно. (См. Комментарии в истории)
- Настоятельно рекомендуется переместить logrotate cron в cron.hourly
- Использует xprintidle
- logrotate config использует xz-utils
- Повторный тест производительности показал, что влияние на процессор практически ничтожно. Только алгоритм сжатия xz, запускаемый logrotate, может воздействовать на одно ядро до 100%. Но это не длится долго на современном процессоре плюс он однопоточный. Так что ваши другие ядра могут выполнять другую работу. Он будет сжимать только журналы, которые имеют пару дней или более 20 МБ.
- Если вы довольны конфигурацией, вы можете настроить ее с помощью встроенного в дистрибутив запуска Startup Applications, который запустит программу при входе в вашу учетную запись. Убедитесь, что у вас есть logrotate, сконфигурированный с настройкой скрипта, для управления файлами журналов. Вы также можете настроить это в свое удовольствие.
- 16.09.2015 - версия 2.1 - Добавлена логика Force Graceful Suspension
- 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)