StevieD
StevieD

Reputation: 7443

Quoting bash command for perl to execute

I've spent like an hour on this without success. Got this perl script which I want to call a wrapper bash function:

my $command = qq(source ~/.bashrc; do_osascript -e 'tell application "Safari" to return URL of current tab of window 1');

my $url = `/usr/local/bin/bash -c '$command'`;
logd $url;

And here is the wrapper bash function:

function do_osascript() {
    if [ -e "/Library/QuickTime/EyeTV MPEG Support.component" ]; then
        mv "/Library/QuickTime/EyeTV MPEG Support.component" ~
    fi
    command osascript "$@"
    if [ -e "${HOME}/EyeTV MPEG Support.component" ]; then
        mv "${HOME}/EyeTV MPEG Support.component" "/Library/QuickTime/"
    fi
}

UPDATE: Had some old code for bash. Updated.

I've tried many different methods of escaping quotes but none of them work. I have confirmed that the command works fine when run from the command line.

Upvotes: 0

Views: 88

Answers (2)

Grinnz
Grinnz

Reputation: 9231

Use String::ShellQuote to programmatically quote an argument or list of arguments so a bourne-compatible shell will treat each as a single argument, regardless of what it contains:

use strict;
use warnings;
use String::ShellQuote;

my $command = shell_quote '/usr/local/bin/bash', '-c', qq(source ~/.bashrc; do_osascript -e 'tell application "Safari" to return URL of current tab of window 1');

my $url = `$command`;

Or invoke the program directly without having the shell parse it. There are many options for this, but the direct analogue of backticks would be using IPC::ReadpipeX:

use strict;
use warnings;
use IPC::ReadpipeX;

my $command = qq(source ~/.bashrc; do_osascript -e 'tell application "Safari" to return URL of current tab of window 1');

my $url = readpipex '/usr/local/bin/bash', '-c', $command;

Other good options for this are listed in that module's docs under SEE ALSO.

Upvotes: 1

tripleee
tripleee

Reputation: 189407

You can't nest stingle quotes like that. For debugging, try

my $url = `printf '>>%s<<\n' /usr/local/bin/bash -c '$command'`,
print "$url";
exit;

to see how the command is tokenized by the shell.

The simplest fix I can think of is

my $command = qq(source ~/.bashrc; do_osascript -e 'tell application \\"Safari\\" to return URL of current tab of window 1');
my $url = `printf '>>%s<<\n' /usr/local/bin/bash -c "$command"`;

where I added backslash escapes before the double quotes in $command, and switched from single to double quotes in $url. But seriously, having that function in your .bashrc is just weird. Put it in a script file instead and do away with the requirement to bash -c "source ~/.bashrc;" before the actual command.

Upvotes: 1

Related Questions