Am I using
konsole
correctly?
Likely, no. But that depends. This question can be decomposed into two issues:
- How do I achieve concurrency, so that my program doesn't halt while I execute an external command
- How do I use
konsole
.
1. Concurrency
There are multiple ways to do that. Starting with the fork||exec('new-program')
, to system 'new-program &'
, or even open
.
system
will invoke the standard shell of your OS, and execute the command you provided. If you provide multiple arguments, no shell escaping is done, and the specified program exec
ed directly. (The exec
function has the same interface so far). system
returns a number that specifies if the command ran correctly:
system("my-command", "arg1") == 0
or die "failed my-command: $?";
See perlfunc -f system
for the full info on what this return value signifies…
The exec
never returns if successfull, but morphs your process into executing the new program.
fork
splits your process in two, and executes the child and the process as equal copies. They only differ in the return value of fork
: The parent gets the PID of the child; the child gets zero. So the following executes a command asynchronously, and lets your main script execute without further delay.
my @command = ("mpg321", "song.mp3");
fork or do {
# here we are in the child
local $SIG{CHLD} = 'IGNORE'; # don't pester us with zombies
# set up environment, especially: silence the child. Skip if program is well-behaved.
open STDIN, "<", "/dev/null" or die "Can't redirect STDIN";
open STDOUT, ">", "/dev/null" or die "Can't redirect STDOUT";
exec {$command[0]} @command;
# won't ever be executed on success
die qq[Couldn't execute "@command"];
};
The above process effectively daemonizes the child (runs without a tty).
2. konsole
The command line interface of that program is awful, and it produces errors half the time when I run it with any parameters.
However, your command (plus a working directory) should actually work. The trailing ampersand isn't neccessary, as the konsole
command returns immediately. Something like
# because I `say` hello, I can be certain that this actually does something.
konsole --workdir ~/wherever/ --new-tab -e perl -E 'say "hello"; <>'
works fine for me (opens a new tab, displays "hello", and closes when I hit enter). The final readline there keeps the tab open until I close it. You can keep the tab open until after the execution of the -e
command via --hold
. This allows you to see any error messages that would vanish otherwise.