Start and Control konsole with DCOP

 in

I like to open a lot of tabs in my terminal (konsole) window: a few standard shells, a couple of su shells, and some ssh connections to other systems that I access regularly. KDE can remember some of these settings via its session capability, but it doesn't always remember everything I want, and sometimes it remembers things I wish it would forget. So, to get my standard tabs, I use DCOP to start what I want when I want it.

DCOP (Desktop COmmunication Protocol) is a protocol that allows applications to interoperate. DCOP has a command-line tool for using it, named, of course, dcop. Note, that DCOP has been replaced in KDE4 with D-Bus (Desktop Bus), so if you've moved to KDE4, this won't do you any good.

The idea is to create a script that creates the konsole tabs I want to create. First are the library functions. There are three functions:

  • create_konsole - starts a new copy of konsole and returns the DCOP ID for it.

  • wait_for_session - waits until the session count (that is, the tab count) in the specified konsole reaches a certain value. This is used to make sure a recently created session has actually started before we try to interact with it.

  • start_sessions - uses a global sessions array to start a list of sessions. The array contains three items for each session:

    • The session name
    • The schema for the session
    • The command to run in the session

The library code follows:

#!/bin/bash
#
# Functions from creating konsoles.


#####################################################################
# Create new console.
function create_konsole()
{
    local basename=$(date +"%H%M%N")
    local name=$basename"_konsoleX1_"
    local kstart_options=$1
    local konsole_options=$2
    kstart $kstart_options --window $name konsole $konsole_options --script -T $name >/dev/null 2>&1
    local konsole_id=konsole-$(ps aux | grep konsole | grep -v grep | grep $name | awk '{print $2}')
    echo $konsole_id
}

#####################################################################
# Wait to make sure the session count equals $1.
function wait_for_session()
{
    local konsole_id=$1
    local count=$2
    local session_count=$(dcop $konsole_id konsole sessionCount 2>/dev/null)
    while [[ $session_count -ne $count ]]
    do
        sleep 0.1
        session_count=$(dcop $konsole_id konsole sessionCount)
    done
}

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

    while [[ $i -lt $session_count ]]
    do
        local name=${sessions[$i]}
        let i++
        local schema=${sessions[$i]}
        let i++
        local command=${sessions[$i]}
        let i++
        dcop $konsole_id $session_id renameSession "$name"
        sleep 0.1
        dcop $konsole_id $session_id setSchema "$schema"
        sleep 0.1
        dcop $konsole_id $session_id sendSession "$command"
        sleep 0.1

        if [[ $i -lt $session_count ]]; then
            let nsessions++
            local session_id=$(dcop $konsole_id konsole newSession)
            wait_for_session $konsole_id $nsessions
        fi
    done
}

# vim: tabstop=4: shiftwidth=4: noexpandtab:
# kate: tab-width 4; indent-width 4; replace-tabs false;

In create_konsole we start the new konsole with the command:

    kstart $kstart_options --window $name konsole $konsole_options --script -T $name >/dev/null 2>&1

This uses kstart to start konsole with a known window name, so that we can get its name via some ps/grep shenanigans in the next line.

In start_sessions, we use dcop to rename the session:

        dcop $konsole_id $session_id renameSession "$name"

To set the schema for the session:

        dcop $konsole_id $session_id setSchema "$schema"

And to send the command to the session:

        dcop $konsole_id $session_id sendSession "$command"

At the end of the function, if there are more sessions to create, we also use dcop to start another session:

            local session_id=$(dcop $konsole_id konsole newSession)

In our main script, we need to define the sessions we want. For this sample, we'll start two standard shells, one su shell and one ssh connection:

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

The schema variable here is set to the *.schema file that we want konsole to use for the tab. The entire script is:

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

source ~/bin/konsoles.sh

if [[ ! "$schema" ]]; then
    #schema=XTerm.schema
    #schema=BlackOnLightColor.schema
    #schema=Linux.schema
    #schema=GreenTint.schema
    #schema=syscolor.schema
    #schema=LightPicture.schema
    #schema=DarkPicture.schema
    schema=GreenOnBlack.schema
    #schema=BlackOnLightYellow.schema
    #schema=LightPaper.schema
    #schema=WhiteOnBlack.schema
    #schema=BlackOnWhite.schema
    #schema=Transparent.schema
    #schema=Transparent_MC.schema
    #schema=Transparent_lightbg.schema
    #schema=GreenTint_MC.schema
    #schema=vim.schema
    #schema=Transparent_darkbg.schema
fi

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

konsole_id=$(create_konsole '--iconify')
wait_for_session 1

session_id=$(dcop $konsole_id konsole currentSession)
first_session_id=$session_id

start_sessions $konsole_id

dcop $konsole_id konsole activateSession $first_session_id
sleep 0.1
dcop $konsole_id 'konsole-mainwindow#1' restore
sleep 0.1
dcop $konsole_id 'konsole-mainwindow#1' setGeometry 100 100 600 400

# vim: tabstop=4: shiftwidth=4: noexpandtab:
# kate: tab-width 4; indent-width 4; replace-tabs false;
The steps are:
  • Call create_konsole to create the initial console and wait for it to become ready. The window is created iconified.
  • Use dcop to get the session id of the first session created. We use this after creating all the other sessions to activate the first session.
  • Call start_sessions to create the sessions in our sessions array.
  • Use dcop to activate the first session that was created.
  • Use dcop to restore the main window.
  • Use dcop to size and place the main window.

Run the main script and you should get a konsole window that looks like:

konsoles.jpg

______________________

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.

script

Anonymous's picture

script at:
http://sp0t.net/doku.php/it:scripts:bash:konsole
is similar and is using a better method of getting the PID :-)

Yes and No

Mitch Frazier's picture

It's better if you're starting konsole directly, but I'm not, I'm using kstart to start konsole and that code would return the PID for kstart and not for konsole.

Mitch Frazier is an Associate Editor for Linux Journal.

I thought i was subscribing

Anonymous's picture

I thought i was subscribing to LJ for "cutting-edge", updated stuff. But I guess i'll better stick with KDE3.

KDE4 not quite there yet

Mitch Frazier's picture

Although KDE 4.2 is certainly worlds better than the first couple of releases, it still has some annoyances so I haven't made the move yet. When it gets there, you can be sure I'll be updating this to use D-Bus.

Mitch Frazier is an Associate Editor for Linux Journal.

SOLVED

Anonymous's picture

For gentoo users, be sure to have kde-base/kstart installed :)

this was what I was looking for!!

Anonymous's picture

Hello, this was exactly what I was looking for!

But so far I'm unable to make it work. I only get so many
"call failed" and no konsole started at all.

if I run the second script with bash -x this is what I get:

+ source /home/ll/bin/konsoles.sh
+ [[ ! -n '' ]]
+ schema=GreenOnBlack.schema
... Removed for brevity
++ dcop konsole- konsole currentSession
call failed
... Removed for brevity

do you think that this can be fixed?

Oops

Mitch Frazier's picture

My full script had some extra cruft in it so I used a trimmed down version for the post and I got a bit too exuberant in my trimming. In the second script, look for "wait_for_session" and change it from this:

  wait_for_session 1

to this:

  wait_for_session $konsole_id 1

Mitch Frazier is an Associate Editor for Linux Journal.

Achieving the similar with

Anonymous's picture

Achieving the similar with dbus would make a great article, would it not?

Yes it would

Mitch Frazier's picture

And when KDE4 fixes a few more things I'll be upgrading.

Mitch Frazier is an Associate Editor for Linux Journal.

You can talk via dbus like dcop

Anonymous's picture

You say it won't help, but dbus was sort of designed off the ideas of dcop... so switching to dbus CAN work... and you can send messages to apps in KDE4 just like 3.5 using dbus instead of dcop.

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix