user3555181
user3555181

Reputation: 117

System call with nested calls and arguments

I am attempting to use the system command to launch an exe that takes several arguments, including launching of more exes that also take arguments.

It is set up as follows.

Apple.exe takes everything as an argument.

Box.exe is an argument that also takes arguments. So right now we are 2 layers in.

This is pseudocode, where the number of quotes equal the layer of arguments

system(Apple.exe 'Box.exe' "/candy" "/dawn" 'elf.exe' "/fence")

Breaking it out where everything below Apple.exe is passed into Apple.exe, there are arguments that are calls themselves. We end up with Apple.exe taking 5 arguments, where 2 of those arguments are calls and 3 of them are arguments for the 2 calls.

Apple.exe

   Box.exe /candy /dawn

   elf.exe /fence

Upvotes: 0

Views: 324

Answers (2)

ikegami
ikegami

Reputation: 386331

If this was a unix-based system, I'd say pass the information as a series of shell commands. apple would be called as follows:

use String::ShellQuote qw( shell_quote );

system(shell_quote('apple', 
   shell_quote('box', '--candy', '--dawn'),
   shell_quote('elf', '--fence'),
));

That generates something equivalent to

apple 'box --candy --dawn' 'elf --fence'

apple would look like:

for my $cmd (@ARGV) {
   system($cmd);   # aka system('sh', '-c', $cmd);
}

But you appear to be using Windows, and command line processing is a bit fragile in Windows. You could try

use Win32::ShellQuote qw( quote_cmd );

system(quote_cmd('apple', 
   quote_cmd('box', '/candy', '/dawn'),
   quote_cmd('elf', '/fence'),
));

which produces an ugly mess that should be equivalent to

apple "box /candy /dawn" "elf /fence"

apple would still look like:

for my $cmd (@ARGV) {
   system($cmd);   # aka system('cmd', '/x', '/c', $cmd);
}

Upvotes: 0

tobyink
tobyink

Reputation: 13664

That's not the way system calls work. When you call an executable, it gets passed a list of arguments. This is an array of strings - there is no concept of nesting other arrays in there. This is not a Perl-specific limitation; it's just how system calls work in mainstream operating systems.

One suggestion might be to call Apple.exe with two arguments:

system(
   "Apple.exe",
   "Box.exe /candy /dawn",
   "elf.exe /fence",
);

When Apple.exe receives the two arguments, it can split them on whitespace to build whatever structure it needs. If the arguments themselves may contain whitespace, choose another character to split on:

system(
   "Apple.exe",
   "Box.exe~/candy~/dawn",
   "elf.exe~/fence",
);

Alternatively, you could write out your arguments as JSON to a file:

[
  [ "Box.exe", "/candy", "/dawn" ],
  [ "elf.exe", "/fence" ]
]

And then call Apple.exe giving it the path to the JSON file:

system("Apple.exe", "argument-list.json");

Of course, whatever choice you make, you'll need to make sure that Apple.exe is programmed to receive its arguments in whatever manner that you chose to pass them.

Upvotes: 1

Related Questions