오픈수세 42.1 + KDE 5
프로세스 시작/종료를 알리기 위해 스크립트에서 kdialog를 사용하고 있습니다.
#!/bin/sh
while inotifywait -r -e modify -e create -e delete ~/www/gruz.org.uab/www/; do
kdialog --passivepopup 'Started' --title 'UNISON update';
unison -ui text -auto -batch gruz.org.uab
kdialog --passivepopup 'Finished' --title 'UNISON update';
done
하지만 팝업이 일부 표시 영역을 덮고 있어 파일을 복사할 때와 같이 시스템 트레이의 진행률 표시기로 바꾸고 싶습니다.
http://static.xscreenshot.com/small/2016/08/04/13/screen_c0544580363c95b1458ba32ad0dcb741
나는 다음과 같은 것을 읽었습니다.qdbus org.kde.JobViewServer.requestView, 그러나 지식 부족으로 구현하지 못했습니다.
명령줄 예제(또는 기타 이에 상응하는 항목)를 제공할 수 있습니까?
- 프로세스를 실행하다
- 트레이의 시작 표시기
- 완료되면 정지 표시기
고마워요 사랑하는 여러분
답변1
쉘 스크립트에서 이를 사용할 때의 문제점은 qdbus org.kde.JobViewServer.requestView
요청하는 D-Bus 클라이언트가 종료될 때 알림을 제거하도록 설계되었기 때문에 dbus-send
및 .qdbus
requestView
요청을 생성하는 데 을 사용하는 경우 qdbusviewer
이와 같은 호출을 사용해 볼 수 있으며 작동할 것입니다. 그러나 연결을 열어두기 위해 쉘 스크립트에서 호출할 수 있는 기성품을 찾을 수 있을지 의문입니다.
# Assuming qdbusviewer got /JobViewServer/JobView_15 from the call...
qdbus org.kde.kuiserver /JobViewServer/JobView_15 org.kde.JobViewV2.setInfoMessage 'Frobnicating the foobles...'
qdbus org.kde.kuiserver /JobViewServer/JobView_15 org.kde.JobViewV2.setDescriptionField 1 Cromulence fair
qdbus org.kde.kuiserver /JobViewServer/JobView_15 org.kde.JobViewV2.setPercent 25
qdbus org.kde.kuiserver /JobViewServer/JobView_15 org.kde.JobViewV2.setSpeed 200
qdbus org.kde.kuiserver /JobViewServer/JobView_15 org.kde.JobViewV2.setTotalAmount 100000 bytes
qdbus org.kde.kuiserver /JobViewServer/JobView_15 org.kde.JobViewV2.setProcessedAmount 200 bytes
qdbus org.kde.kuiserver /JobViewServer/JobView_15 org.kde.JobViewV2.terminate 'Received Ctrl+C'
그러나 쉘 스크립트 대신 약간의 Python을 사용하려는 경우 예제를 제공할 수 있습니다.하다동일한 작업에 대해 Python이 쉘 스크립트에 대한 매우 좋은 대안임을 보장할 수 있습니다.
이는 이벤트 루프를 설정하지 않고 가능한 많은 관련 기능을 보여주기 위해 작성되었습니다.
#!/usr/bin/env python
# This line opts into some Python 3.x features if you run Python 2.x
# and must go at the top of the file because it changes how the file is parsed.
# (Specifically, the Python 3.x print() syntax and sane division)
from __future__ import print_function, division
# These lines are analogous to `source` in a shell script
# The `import` statement searches `sys.path` for the requested packages
import fnmatch, os, subprocess, time
# I'm not sure what package you'll need on OpenSUSE, but this comes from
# python-dbus on Debian, *buntu, and Mint.
import dbus
# -- Get a handle for the D-Bus API to create a new Job --
session_bus = dbus.SessionBus()
# A simple little helper function to paper over some complexity
# See Also: https://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html
def get_dbus_interface(name, path, interface):
obj = session_bus.get_object(name, path)
return dbus.Interface(obj, dbus_interface=interface)
create_handle = get_dbus_interface(
'org.kde.kuiserver', '/JobViewServer', 'org.kde.JobViewServer')
# -- Create a Job and get a handle to manipulate it --
# requestView takes (appName, appIconName, capabilities)
# https://lists.freedesktop.org/archives/xdg/2008-April/009410.html
# ...but according to the source code, capabilities never got hooked up, so
# the pause and stop buttons will always be there, whether or not you're
# listening for them. (And stop will always kill the popup.)
request_path = create_handle.requestView('MyTestApp', 'download', 0)
request_handle = get_dbus_interface(
'org.kde.kuiserver', request_path, 'org.kde.JobViewV2')
# -- Set up a fake task for demonstration purposes --
files = os.listdir('/etc') # NOTE: Check out os.walk() for recursive
file_count = len(files)
wait_per_file = 5.0 / file_count # Add 2 seconds to the total runtime
# -- Configure the bits of the popup that won't change in our example --
request_handle.setInfoMessage('Echoing files in /etc')
request_handle.setTotalAmount(file_count, 'files')
request_handle.setSpeed(200 * 1024**4) # 200 TiB/s
# -- Do our fake work --
# NOTE: In Python, indentation outside of () and [] is significant
try:
for position, filename in enumerate(files):
# Visible in the collapsed view
request_handle.setPercent((position / file_count) * 100)
request_handle.setDescriptionField(0, 'Source', filename)
request_handle.setDescriptionField(1, 'Destination', filename)
# These are for the expanded view
request_handle.setProcessedAmount(position, 'files')
# Here's some fake work so you can see how to call subprocesses
subprocess.call(['echo', filename])
time.sleep(wait_per_file)
# Set the final state of the popup that will be left behind
request_handle.setDescriptionField(0, "", "Completed successfully.")
request_handle.clearDescriptionField(1)
request_handle.terminate("All done")
except KeyboardInterrupt:
print("Ctrl+C Pressed")
request_handle.setDescriptionField(0, "Cancelled", "Ctrl+C Pressed")
request_handle.clearDescriptionField(1)
request_handle.terminate("Cancelled from outside")
finally:
# This gets called no matter what
print("Doing fake cleanup")
print("%s of the files were *.conf" % len(fnmatch.filter(files, '*.conf')))
답변2
진행률 표시기와 함께 bash 명령을 실행하도록 Python 스크립트를 수정했습니다. 진행 상황은 볼 수 없지만 뭔가가 아직 실행 중인지는 확인할 수 있습니다.
#!/usr/bin/env python
# This line opts into some Python 3.x features if you run Python 2.x
# and must go at the top of the file because it changes how the file is parsed.
# (Specifically, the Python 3.x print() syntax and sane division)
from __future__ import print_function, division
# These lines are analogous to `source` in a shell script
# The `import` statement searches `sys.path` for the requested packages
import subprocess, time
# I'm not sure what package you'll need on OpenSUSE, but this comes from
# python-dbus on Debian, *buntu, and Mint.
import dbus
# Get command line parameters
import sys
# Run bash script in background
import threading
# -- Get a handle for the D-Bus API to create a new Job --
session_bus = dbus.SessionBus()
# A simple little helper function to paper over some complexity
# See Also: https://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html
def get_dbus_interface(name, path, interface):
obj = session_bus.get_object(name, path)
return dbus.Interface(obj, dbus_interface=interface)
def run_bash_command(command):
try:
subprocess.call(command, shell=False)
except Exception as e:
print("Exception: ")
print(e)
def main():
create_handle = get_dbus_interface(
'org.kde.kuiserver', '/JobViewServer', 'org.kde.JobViewServer')
# -- Create a Job and get a handle to manipulate it --
# requestView takes (appName, appIconName, capabilities)
# https://lists.freedesktop.org/archives/xdg/2008-April/009410.html
# ...but according to the source code, capabilities never got hooked up, so
# the pause and stop buttons will always be there, whether or not you're
# listening for them. (And stop will always kill the popup.)
request_path = create_handle.requestView('bash', 'download', 0)
request_handle = get_dbus_interface(
'org.kde.kuiserver', request_path, 'org.kde.JobViewV2')
# -- Configure the bits of the popup that won't change in our example --
request_handle.setInfoMessage(sys.argv[1])
# NOTE: In Python, indentation outside of () and [] is significant
try:
worker = threading.Thread(target=run_bash_command, args=[sys.argv[1:]])
worker.start()
# for position, filename in enumerate(files):
# # Visible in the collapsed view
request_handle.setPercent(0)
request_handle.setDescriptionField(0, 'Command:', str(sys.argv[1]))
request_handle.setDescriptionField(1, 'Arguments:', str(sys.argv[2:]))
while worker.isAlive():
time.sleep(1)
# Set the final state of the popup that will be left behind
request_handle.setDescriptionField(0, "", "Finished.")
# request_handle.clearDescriptionField(1)
request_handle.terminate("All done")
except KeyboardInterrupt:
request_handle.setDescriptionField(0, "Cancelled", "Ctrl+C Pressed")
request_handle.clearDescriptionField(1)
request_handle.terminate("Cancelled from outside")
finally:
# This gets called no matter what
pass
main()