0

I thought this must be simple, but I haven't found a viable solution.

The problem is as simple as this: I want to execute a system command and capture the output in Perl variable. The command is specified in Perl array (containing command and parameters, e.g. @cmd = ('mycmd', '-opt1', 'arg1', 'val1')).

I don't want to use forking, i.e. open(FROM_KID, '-|') is not an option. I know that if I had the command in a string I can achieve this with backticks. So perhaps this problem reduces to converting @cmd array into a string. In my case, the command arguments can contain spaces.

Is there a simple way to convert @cmd array into string that can be used with backticks, but such that all arguments are properly quoted? Also ideally without using any external libraries.

Thanks!!

6
  • 1
    First, using system or backtics will fork a child process - there's no way around that. You could do something like $cmd = join(' ', map { s/'/\\'/g; "'$_'" } @cmd); but open would probably be safer.. Commented Sep 16, 2015 at 17:42
  • 4
    Re "I don't want to use forking", It's impossible not to fork. That's how all processes are created in unix, including when using system. Commented Sep 16, 2015 at 17:46
  • By forking, I meant implicit forking the Perl process itself that opening a pipe does, as I understood. Commented Sep 16, 2015 at 18:04
  • 5
    That's the same as the implicit forking done by system and backticks. Commented Sep 16, 2015 at 18:20
  • 1
    You should explain why you think you don't want to fork a subprocess, and why you don't want to use a Perl module Commented Sep 16, 2015 at 21:39

1 Answer 1

3

You may be looking for String::ShellQuote. Note that only Bourne shell quoting is supported.

But backticks also perform an implicit fork, and if they in any way differ from the implicit fork of pipe open, I for one never noticed. :-\

Sign up to request clarification or add additional context in comments.

3 Comments

The String::ShellQuote is third-party package, which I would like to avoid. We have an existing script that uses only core packages and supports Perl back to version 5.8. I just need to make it work under Windows with possibly not affecting the minimum requirements or adding dependency on packages not in core.
String::ShellQuote is pure Perl – you could copy the code from it. But it will only work with Bourne shell, not with Windows' command.exe/cmd.exe. On Windows, you'd need Win32::ShellQuote – or a recent enough version of perl that pipe open works. ;-)
The Win32::ShellQuote seems to be a place to borrow the code from. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.