Pergunta

I have an issue when using this command

system("konsole --new-tab --workdir<dir here> -e perlprogram.pl &");

It opens perlprogram.pl which has:

system("mpg321 song.mp3");

I want to do this because mpg321 stalls the main perl script. so i thought by opening it in another terminal window it would be ok. But when I do run the first script all it does is open a new tab and do nothing.

Am I using konsole correctly?

Foi útil?

Solução

Am I using konsole correctly?

Likely, no. But that depends. This question can be decomposed into two issues:

  1. How do I achieve concurrency, so that my program doesn't halt while I execute an external command
  2. 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 execed 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top