Start and Control konsole with DBUS

Some time back I wrote about creating a number of konsoles automatically using dcop. Although we were at the time well into the KDE4 era I had not yet upgraded since there were still things that weren't quite working with KDE4, most of these have now been fixed so I've upgraded some of my systems to KDE4, which means it's time to update the original code to now use dbus.

My first attempt at this was using dbus-send but after not making a lot of progress with that I tried using qdbus instead, this proved easier to use. In re-implementing this code for KDE4 I also discovered a few things that aren't quite working yet in Konsole's dbus interface:

  • It's not yet possible to start a new konsole in another konsole window, all new konsoles appear in the current konsole. My original code created a completely new konsole window and filled it with the new konsoles. Since this is not yet implemented that feature is yanked.
  • Starting a console with a particular "Schema" is also not working yet. The code for doing this is still in the sample below but it's commented out. Also note that schemas have been replaced by "profiles" in KDE4.
  • There's no way to activate a specific session yet using dbus.

At the top are the definitions of the konsoles that I want to start. This is an array where each konsole is defined by 3 entries in the array: the first is the name that I want to give to the konsole tab, the second is the profile to use (ignored for now since this is not working), and the third is the initial command to execute within the konsole.

sessions=(
    sh1   $profile   'clear; bash'
    sh1   $profile   'clear; bash'
    su1   $profile   'clear; su'
    ssh1  $profile   'clear; ssh 127.0.0.1'
    )

After that is the start_sessions function which is quite similar to the original one from the KDE3 version of the code, the main difference being that it calls qdbus rather than dcop to interace with konsole. To create a new session it does:

        # Starting with a specific profile appears to be broken.
        #local session_num=$(qdbus org.kde.konsole /Konsole newSession $profile $HOME)
        local session_num=$(qdbus org.kde.konsole /Konsole newSession)
        sleep 0.1

You'll notice above that the call with the profile included is commented out as that call is still not working in KDE4/Konsole.

To set the title of the session it does:

        qdbus org.kde.konsole /Sessions/$session_num setTitle 0 $name
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num setTitle 1 $name
        sleep 0.1

Title "0" appears to be the initial title, title "1" is the title used after commands are executed. So if you don't set title "1" then the tab title changes after each command that you enter.

To set the command to be run by the new konsole you send text to it:

        qdbus org.kde.konsole /Sessions/$session_num sendText "$command"
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num sendText $'\n'
        sleep 0.1

The second send sends a newline so the konsole actually executes the command.

The main part of the script asks if you want to create the konsoles and executes start_sessions if you answer with something that looks like yes. After starting the sessions it activates the first session. As I mentioned above there's no way to activate a specific session so the code activates the first session by activating the "previous" session multiple times.

    # Activate first session.
    while [[ $nsessions -gt 1 ]]
    do
        qdbus org.kde.konsole /Konsole prevSession
        let nsessions--
    done

Run this and you should get a konsole window that looks something like:

konsoles.jpg

The entire code follows:

#!/bin/bash
#
# Create my standard konsole windows.

if [[ ! "$profile" ]]; then
    profile=Shell
fi

sessions=(
    sh1   $profile   'clear; bash'
    sh1   $profile   'clear; bash'
    su1   $profile   'clear; su'
    ssh1  $profile   'clear; ssh 127.0.0.1'
    )

nsessions=0

#####################################################################
# Start sessions in konsole.
function start_sessions()
{
    local session_count=${#sessions[*]}
    local i=0

    while [[ $i -lt $session_count ]]
    do
        local name=${sessions[$i]}
        let i++
        local profile=${sessions[$i]}
        let i++
        local command=${sessions[$i]}
        let i++

        echo "Creating $name: $command"
        # Starting with a specific profile appears to be broken.
        #local session_num=$(qdbus org.kde.konsole /Konsole newSession $profile $HOME)
        local session_num=$(qdbus org.kde.konsole /Konsole newSession)
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num setTitle 0 $name
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num setTitle 1 $name
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num sendText "$command"
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num sendText $'\n'
        sleep 0.1

        let nsessions++
    done
}

read -p "Create konsoles? " ans
if [[ "${ans:0:1}" == 'y' ]]; then
    start_sessions

    # Activate first session.
    while [[ $nsessions -gt 1 ]]
    do
        qdbus org.kde.konsole /Konsole prevSession
        let nsessions--
    done
fi


# vim: tabstop=4: shiftwidth=4: noexpandtab:
# kate: tab-width 4; indent-width 4; replace-tabs false;
AttachmentSize
konsoles.jpg23.54 KB
______________________

Mitch Frazier is an Associate Editor for Linux Journal.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

A workaround to the single-window problem.

Alex Bokov's picture

(originally posted to production-engineer.com which apparently republished this article; reposting it here so more people can find this workaround)

What a wonderful script! This is going to really streamline my work. And guess what? I found a fix for the single-window problem.

1. Change line #37 in your script to say...
local session_num=$(qdbus $KONSOLE_DBUS_SERVICE /Konsole newSession)
instead of...
local session_num=$(qdbus org.kde.konsole /Konsole newSession)

2. Create a new profile for Konsole. I named mine "PreLauncher". In the profile editor (or in the line beginning with "Command=" in .kde/share/apps/konsole/PreLauncher.profile) put the following command:
/bin/bash /usr/local/bin/prelauncher.sh

3. Create a prelauncher.sh, which consists of...
#!/bin/bash
session_num=$(qdbus org.kde.konsole /Konsole newSession)
qdbus org.kde.konsole /Sessions/$session_num sendText "konsole --profile Launcher"
qdbus org.kde.konsole /Sessions/$session_num sendText $'\n'
exit 0

4. Create another new profile for Konsole. I named mine "Launcher". In the profile editor (or in the line beginning with "Command=" in .kde/share/apps/konsole/Launcher.profile) put the following command:
/bin/bash /usr/local/bin/multisession.sh
...where multisession.sh is the script you wrote.

So now when you run "konsole --profile PreLauncher" you will get a new, multi-tabbed konsole instance each time. If you run it from another konsole, you will end up with one extra tab in that konsole when it's done. If you run it from krunner or a desktop shortcut, you won't get the extraneous tab. Enjoy! And, once again, thanks for sharing the original script.

Thanks for the Update

Mitch Frazier's picture

I haven't had a chance to test this out but thanks. Since KDE4 and Konsole are changing all the time it would be useful for you to post here what version of Konsole you're using. And it would be useful for me to do the same:

$ konsole --version
Qt: 4.5.3
KDE: 4.3.5 (KDE 4.3.5) "release 0"
Konsole: 2.3.3

Mitch Frazier is an Associate Editor for Linux Journal.

Konsole version

Alex Bokov's picture

konsole --version
Qt: 4.6.2
KDE Development Platform: 4.4.2 (KDE 4.4.2)
Konsole: 2.4.2

Tested my workaround and it still works.

Please reply

Anonymous's picture

This fix is not working (I tested it on the latest konsole).

Mine does, please take a look at my solution and reply to my message (Jun 03, 2010). Or is there any reason I may want/need to know why you left my message unanswered?

Too Busy

Mitch Frazier's picture

Just haven't had time to look at it.

Mitch Frazier is an Associate Editor for Linux Journal.

It's not yet possible to

Anonymous's picture

It's not yet possible to start a new konsole in another konsole window, all new konsoles appear in the current konsole. My original code created a completely new konsole window and filled it with the new konsoles. Since this is not yet implemented that feature is yanked.

What do you mean? New konsole *windows* (not instances) are treated simply as extra (sets of) "tabs" (to be managed as/within the original "org.kde.konsole"). This is fine, as you can still use qdbus to refer to each tab individually, no matter which window it is on.

The problem, indeed, is that, while a dbus-based script can create new windows containing the one initial qdbus-manageable tab (and one only), it can "physically" add *extra* tabs only to the "original" konsole window.

But there's a simple solution to this. You can use new konsole instances. Each newly started konsole gets its own unique entry in $(qdbus | grep konsole) (e.g. org.kde.konsole-6384), so you can keep track of any newly created org.kde.konsole-PID entry in $(qdbus) and send "/Konsole newSession" to the desired org.kde.konsole-PID instead of org.kde.konsole.

(My method to make sure that my scripted execution of /usr/bin/konsole always created a new konsole instance and not a new konsole window was using "ln -s /usr/bin/konsole <symlink>" and running <symlink> instead. (Do you have a better method?) I only needed one symlink execution, because from that point on the system somehow became "multisession_konsole-aware": the "konsole" command never created new windows anymore, but only new instances, as confirmed by $(qdbus). So I didn't anymore need to add to my version of your script the creation of a temporary symlink for each needed instance, as I'd planned.)

I didn't read (or pay attention to the aims of) your post carefully, as I was only interested in getting my stuff done, so I'm not sure about this: with my feedback in mind, do you still find it expensive to port all of your dcop-based script's features to this one? (And, if not, will you do it?)

Dolphin ou Konqueror x Konsole

MMedinabr's picture

Greetings,
Here was where I found a part of the solution I need, so if you can help me, thank you.
I made a connection to a server by ssh from the dolphin or konqueror. So I have the user name and password in the KWalletManager.
I access multiple servers, so I want to know if I can open a konsole session remotely using this "user/password" informations.
Currently if I press F4, open a session in my home folder location.
Sorry my poor English.

Konsole and KWallet

Mitch Frazier's picture

There isn't any integration of kwallet with konsole that I'm aware of and it seems unlikely that there ever will be since this problem is essentially already solved by using ssh keys and ssh-agent.

Mitch Frazier is an Associate Editor for Linux Journal.

profiles?

toes's picture

When you spoke about profiles not yet working in KDE4/Konsole, were you referring to the profiles that in KDE3/Konsole could used like this:

   konsole    --profile    my_profile

Profiles

Mitch Frazier's picture

I believe profiles in KDE3 referred to a particular set of sessions (ie a particular set of tabs). The look and feel of a tab was determined by a schema in KDE3. In KDE4 there are no schemas and most of what was in a schema is now in a profile and it appears that KDE4 does not have a profile in the sense that KDE3 did. I don't have two systems side by side to compare them, and I'm using KDE4 right this second so I'm working from memory as to what KDE3 did/does so there may be other differences/similarities that I'm overlooking/forgetting.

And I didn't say that profiles aren't working, what I said was that starting a tab using a particular profile via dbus is not yet working. Profiles work, you just can't get dbus to use them yet.

Mitch Frazier is an Associate Editor for Linux Journal.

Glad to see this

eager's picture

This was one of the features I really missed when I moved from KDE 3 to KDE 4.

I had several scripts, one for each project, which would set up a work environment for that project. The script would open konsole, create and label multiple tabs, and then in each tab, cd to the correct directory for the tab, and run a command to set the path and any other environment variables I needed. Bingo, I was ready to roll.

Moving to KDE 4 meant making a number of changes in how I worked; not a pleasant choice. I've gotten used to manually setting up konsole windows, gotten used to tabs which don't tell me what is in the tab, searching for the tab which I know has vi open, and so forth.

I'll give your script a try and see if I can ressurect my old tricks.

Michael Eager, Consultant, Embedded Systems, Compilers, Debuggers

new konsole sessions via dbus

George Morrison's picture

I am interested in knowing how to create a new konsole session in a specific konsole window. I normally have one konsole window in each of 5 or 6 desktops. Everything I have tried (usually, but not always) starts new sessions in the konsole window that was launched last. I may want to start a session in the konsole window that was launched first, or third, or whatever. Any clues?

Bullets

Mitch Frazier's picture

Check the first bullet item near the top of the article. That feature is not (yet) available in KDE4/Konsole.

Mitch Frazier is an Associate Editor for Linux Journal.

issue

hemanth.hm's picture

Could not connect to D-Bus server: org.freedesktop.DBus.Error.Spawn.ExecFailed: /bin/dbus-launch terminated abnormally with the following error: Autolaunch error: X11 initialization failed.

X11

Mitch Frazier's picture

Check the April 17th, 2008 entry here.

Mitch Frazier is an Associate Editor for Linux Journal.

Thank you!

JaapvB's picture

That blog-entry exactly does what I've been trying to do some time ago. I couldn't get it working. Now I can open my devices in Konqueror from any desktop without starting a new Konqueror.

actually a qdbus error

Aaron Seigo's picture

"You'll notice above that the call with the profile included is commented out as that call is still not working in KDE4/Konsole."

actually, this is a bug in qdbus where it doesn't handle multiple methods with the same name but different parameter lists properly. just took a look and whipped up a patch, will submit it upstream.

iff I want to do in Gnome ...

unixbhaskar's picture

Hi Mitch,

Iff I want do it in gnome session how do I go about it? Can you please paas me the code to open a gnome-teminal and within that I need to open a 1 screen seseeion with 5 screen window and in those screen session all have to be chrooted to different slice/parttion OS along with gnome-teminal title of that particular OS.

Am I clear?

A bit explation:

I have 5 or more slices...and GNU/Linux OS in every slices. Now I may boot up one OS at a time and once I get into a desktop of gnome and fire gnome-terminal it will open an teminal(fire "screen") and create a screen within that with 5 ot more window of screen and Chrooted to five different OS on other slices(i.e chroot /Arch /bin/bash). So the screen title would change to that perticular OS,instead of doing it manually like CTRL-A a...

PS: I have script to mount all the other slices of partition after boot.So chroot to those OS will be easy.But I want to automate that once I clicked into gnome-terminal icon and its open up.

I think almost an idea you posted here with few tweak.But need to get the exact code to work.

/dev/sda1-----> Gentoo

/dev/sda2----->openSUSE

/dev/sda3---->Arch

/dev/sda4---->Slackware

/dev/sda5---->CentOS

/dev/sda6---->Ferdora

/dev/sda7---->Ubuntu

Thanks in advance Mitch.

Thanks
Bhaskar

Bhaskar Chowdhury

Gnome Terminal

Mitch Frazier's picture

I'm not a gnome or gnome-terminal user so I don't have any code for doing that. As far as I can tell gnome-terminal does not have a dbus interface so this route won't work.

Check here and here for some ideas on controlling gnome-terminal with xdotool. The second link contains a modified version of the code at the first link.

Mitch Frazier is an Associate Editor for Linux Journal.

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState