Bash

將 KDE 活動概念擴展到 shell

  • October 4, 2013

有時,我會使用 KDE,而我最喜歡 KDE 4 中的一件事就是活動概念。在工作中,它非常有用,因為我經常在一天內處理幾個不同的項目。例如,切換到另一個活動使我能夠更改小元件,以便我可以訪問與目前項目相關的文件夾。

我決定在 shell 中使用這個概念,所以我編寫了一個名為“switch”的小 bash 函式,它設置對目前項目有用的別名,例如alias cdwww=~/public_html/current_project/www,等等。

我的問題是:有沒有一種方法可以將 KDE 活動與 shell 活動同步,即通過 KDE 切換到活動“myproj”時在每個打開的終端上呼叫“switch myproj”,反之亦然(獎金問題)?

另一個問題:如何讓我新創建的別名在所有控制台中工作?有沒有辦法可以檢測 konsole 或 gnome-terminal 中每個打開的終端並在其中執行我的功能?

編輯:這是開關功能,位於我的 .bashrc 文件的末尾,請隨意評論:

function switch() {

   if [ ! -d ~/.switch ]
   then
       mkdir ~/.switch
   fi

   if [ ! -f ~/.switch/proj.save ]
   then
       touch ~/.switch/proj.save
   fi

   echo "$1" > ~/.switch/proj.save

   case $1 in
   meddispar )
       echo "Switching to meddispar..."

       echo "setting cdproj alias"
       alias cdproj="cd ~/public_html/onp/"

       echo "setting cdwww alias"
       alias cdwww="cd ~/public_html/onp/www/"

       echo "setting cc alias"
       alias cc="cdwww && php bin/php/ezcache.php --clear-all --purge && cd -"
   ;;
   darjeeling )
       echo "Switching to darjeeling..."

       echo "setting cdproj alias"
       alias cdproj="cd ~/public_html/darjeeling/"

       echo "setting cdwww alias"
       alias cdwww="cd ~/public_html/darjeeling/www/"

       echo "setting cc alias"
       alias cc="rm -rf ~/public_html/darjeeling/www/var/cache/*"
   ;;
   * )
       echo "'$1'? WTF?"
       rm ~/.switch/proj.save
   ;;
   esac
}
if [ -f ~/.switch/proj.save ]
then
    switch `cat ~/.switch/proj.save`
fi

根據 Gilles 的回答,這就是我所得到的:

greg@tiny :) ~ > qdbus |ack ctivity
org.kde.ActivityController-1949
org.kde.ActivityManager
greg@tiny :) ~ > qdbus org.kde.ActivityManager 
/
/ActivityManager
/MainApplication
/StatusNotifierWatcher
/connections
/kbuildsycoca
/kded
/kxkb
/modules
/modules/StatusNotifierWatcher
/modules/activitymanager
/modules/device_automounter
/modules/dnssdwatcher
/modules/favicons
/modules/freespacenotifier
/modules/keyboard
/modules/khotkeys
/modules/kpackagekitd
/modules/kremotecontroldaemon
/modules/ktimezoned
/modules/kwrited
/modules/nepomuksearchmodule
/modules/networkmanagement
/modules/networkstatus
/modules/powerdevil
/modules/randrmonitor
/modules/remotedirnotify
/modules/solidautoeject
/modules/statusnotifierwatcher
/org
/org/freedesktop
/org/freedesktop/PowerManagement
/org/freedesktop/PowerManagement/Inhibit
/org/kde
/org/kde/networkmanagement
/org/kde/networkmanagement/Activatable
/org/kde/networkmanagement/Activatable/10
/org/kde/networkmanagement/Activatable/11
/org/kde/networkmanagement/Activatable/12
/org/kde/networkmanagement/Activatable/13
/org/kde/networkmanagement/Activatable/14
/org/kde/networkmanagement/Activatable/15
/org/kde/networkmanagement/Activatable/16
/org/kde/networkmanagement/Activatable/17
/org/kde/networkmanagement/Activatable/2
/org/kde/networkmanagement/Activatable/3
/org/kde/networkmanagement/Activatable/4
/org/kde/networkmanagement/Activatable/5
/org/kde/networkmanagement/Activatable/6
/org/kde/networkmanagement/Activatable/7
/org/kde/networkmanagement/Activatable/8
greg@tiny :) ~ > qdbus org.kde.ActivityManager /ActivityManager
method QStringList org.kde.ActivityManager.ActivitiesForResource(QString uri)
method QString org.kde.ActivityManager.ActivityIcon(QString id)
method QString org.kde.ActivityManager.ActivityName(QString id)
signal void org.kde.ActivityManager.ActivityNameChanged(QString id, QString name)
method QString org.kde.ActivityManager.AddActivity(QString name)
method QStringList org.kde.ActivityManager.AvailableActivities()
method QString org.kde.ActivityManager.CurrentActivity()
signal void org.kde.ActivityManager.CurrentActivityChanged(QString id)
method bool org.kde.ActivityManager.IsBackstoreAvailable()
method void org.kde.ActivityManager.RegisterActivityController(QString service)
method void org.kde.ActivityManager.RegisterResourceWindow(uint wid, QString uri)
method QStringList org.kde.ActivityManager.RegisteredActivityControllers()
method void org.kde.ActivityManager.RemoveActivity(QString id)
method void org.kde.ActivityManager.SetActivityIcon(QString id, QString name)
method void org.kde.ActivityManager.SetActivityName(QString id, QString name)
method bool org.kde.ActivityManager.SetCurrentActivity(QString id)
method void org.kde.ActivityManager.UnregisterResourceWindow(uint wid, QString uri)
method QString org.kde.ActivityManager._allInfo()
method QString org.kde.ActivityManager._serviceIteration()
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()
greg@tiny :) ~ > qdbus org.kde.ActivityController-1949 /ActivityController 
method void org.kde.ActivityController.ActivityAdded(QString id)
method void org.kde.ActivityController.ActivityRemoved(QString id)
method void org.kde.ActivityController.ResourceWindowRegistered(uint wid, QString uri)
method void org.kde.ActivityController.ResourceWindowUnregistered(uint wid, QString uri)
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()

編輯:我使用 python 完全重寫了我的腳本,現在整個項目都在這裡可用:https ://github.com/greg0ire/switch

通過 dbus 控制 KDE 活動

KDE 可以通過命令行控制qdbus。一般語法是qdbus COMPONENT PATH METHOD ARGUMENT1...whereCOMPONENT通常類似於org.freedesktop.Fooor org.kde.BarPATH表示組件公開的類,METHOD 是該類中特定操作的名稱,並且可能有進一步的參數,具體取決於方法。

以下是 KDE ≥4.7 列出活動、獲取目前活動和設置目前活動的命令。

qdbus org.kde.kactivitymanagerd /ActivityManager org.kde.ActivityManager.ListActivities
qdbus org.kde.kactivitymanagerd /ActivityManager org.kde.ActivityManager.CurrentActivity
qdbus org.kde.kactivitymanagerd /ActivityManager org.kde.ActivityManager.SetCurrentActivity "activity identifier "

找出 dbus 能做什麼

KDE 的 dbus 文件很差。每個類都有最少的文件記錄,例如ActivityDesktopCorona)。但是您可能需要進行試驗,或者閱讀原始碼(API 文件頁面中有連結)以找出可用的內容。

如果您鍵入qdbus最多兩個參數,它將列出下一個參數的可能性。以下 shell 片段列出了所有可用的 Qt-dbus 方法:

for x in $(qdbus | sed '/^:/d'); do
 for y in $(qdbus $x); do
   qdbus $x $y | sed "s~^~$x $y ~"
 done
done 2>/dev/null >qdbus.list

探索 dbus 樹的另一種方法是qdbusviewer使用 Qt 開發工具。作為PyQt的一部分,還有一個 Python qt-dbus 介面。

讓外殼做出反應

為了讓 shell 對外部事件做出反應,你能做的最好的事情就是讓它在顯示提示之前檢查一些東西。Bash$PROMPT_COMMAND在顯示提示之前執行,zsh 執行該precmd功能。因此,您可以查找目前的 KDE 活動,如果它與您上次查看的時間相比發生了變化,您可以執行一些操作。

引用自:https://unix.stackexchange.com/questions/3543