[PATCH] Convert open("-|") to qx{} calls

Subsystems: the rest

DORMANTno replies

13 messages, 5 authors, 2016-06-15 · open the first message on its own page

[PATCH] Convert open("-|") to qx{} calls

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:42:20

Signed-off-by: Johannes Schindelin <redacted>

---

	Since of these 4, I only use cvsimport myself, I could only test
	that. Could someone who uses the others give them a hard beating?

 git-cvsimport.perl  |   64 +++++++++++++++++++--------------------------------
 git-rerere.perl     |    9 ++-----
 git-send-email.perl |    9 ++-----
 git-svnimport.perl  |   62 ++++++++++++++-----------------------------------
 4 files changed, 46 insertions(+), 98 deletions(-)

b37d21c223fdc0ef7fc6af889432f6b51ac82992
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index b46469a..da009f2 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -478,9 +478,9 @@ unless(-d $git_dir) {
 		       "Either use the correct '-o branch' option,\n".
 		       "or import to a new repository.\n";
 
-	open(F, "git-symbolic-ref HEAD |") or
-		die "Cannot run git-symbolic-ref: $!\n";
-	chomp ($last_branch = <F>);
+	$last_branch = qx{git-symbolic-ref HEAD};
+	!$? or exit $?;
+	chomp ($last_branch);
 	$last_branch = basename($last_branch);
 	close(F);
 	unless($last_branch) {
@@ -516,13 +516,12 @@ EOM
 			or die "Bad head branch: $head: $!\n";
 		chomp(my $ftag = <F>);
 		close(F);
-		open(F,"git-cat-file commit $ftag |");
-		while(<F>) {
+		foreach (qx{git-cat-file commit $ftag}) {
 			next unless /^author\s.*\s(\d+)\s[-+]\d{4}$/;
 			$branch_date{$head} = $1;
 			last;
 		}
-		close(F);
+		!$? or exit $?;
 	}
 	closedir(D);
 }
@@ -538,24 +537,21 @@ if ($opt_A) {
 	write_author_info("$git_dir/cvs-authors");
 }
 
-my $pid = open(CVS,"-|");
-die "Cannot fork: $!\n" unless defined $pid;
-unless($pid) {
-	my @opt;
-	@opt = split(/,/,$opt_p) if defined $opt_p;
-	unshift @opt, '-z', $opt_z if defined $opt_z;
-	unshift @opt, '-q'         unless defined $opt_v;
-	unless (defined($opt_p) && $opt_p =~ m/--no-cvs-direct/) {
-		push @opt, '--cvs-direct';
-	}
-	if ($opt_P) {
-	    exec("cat", $opt_P);
-	} else {
-	    exec("cvsps","--norc",@opt,"-u","-A",'--root',$opt_d,$cvs_tree);
-	    die "Could not start cvsps: $!\n";
-	}
+my @opt;
+@opt = split(/,/,$opt_p) if defined $opt_p;
+unshift @opt, '-z', $opt_z if defined $opt_z;
+unshift @opt, '-q'         unless defined $opt_v;
+unless (defined($opt_p) && $opt_p =~ m/--no-cvs-direct/) {
+	push @opt, '--cvs-direct';
 }
 
+my @input;
+if ($opt_P) {
+    @input = qx{cat $opt_P};
+} else {
+    @input = qx{cvsps --norc opt -u -A --root $opt_d $cvs_tree};
+    !$? or exit $?;
+}
 
 ## cvsps output:
 #---------------------
@@ -603,17 +599,11 @@ my $commit = sub {
 		die "Cannot add files: $?\n" if $?;
 	}
 
-	$pid = open(C,"-|");
-	die "Cannot fork: $!" unless defined $pid;
-	unless($pid) {
-		exec("git-write-tree");
-		die "Cannot exec git-write-tree: $!\n";
-	}
-	chomp(my $tree = <C>);
+	my $tree = qx{git-write-tree};
+	!$? or exit $?;
+	chomp($tree);
 	length($tree) == 40
 		or die "Cannot get tree id ($tree): $!\n";
-	close(C)
-		or die "Error running git-write-tree: $?\n";
 	print "Tree ID $tree\n" if $opt_v;
 
 	my $parent = "";
@@ -734,7 +724,7 @@ my $commit = sub {
 	}
 };
 
-while(<CVS>) {
+foreach (@input) {
 	chomp;
 	if($state == 0 and /^-+$/) {
 		$state = 1;
@@ -846,15 +836,9 @@ while(<CVS>) {
 			print "Drop $fn\n" if $opt_v;
 		} else {
 			print "".($init ? "New" : "Update")." $fn: $size bytes\n" if $opt_v;
-			my $pid = open(my $F, '-|');
-			die $! unless defined $pid;
-			if (!$pid) {
-			    exec("git-hash-object", "-w", $tmpname)
-				or die "Cannot create object: $!\n";
-			}
-			my $sha = <$F>;
+			my $sha = qx{git-hash-object -w $tmpname};
+			!$? or exit $?;
 			chomp $sha;
-			close $F;
 			my $mode = pmode($cvs->{'mode'});
 			push(@new,[$mode, $sha, $fn]); # may be resurrected!
 		}
diff --git a/git-rerere.perl b/git-rerere.perl
index d3664ff..0dd04c5 100755
--- a/git-rerere.perl
+++ b/git-rerere.perl
@@ -131,20 +131,15 @@ sub record_preimage {
 sub find_conflict {
 	my $in;
 	local $/ = "\0";
-	my $pid = open($in, '-|');
-	die "$!" unless defined $pid;
-	if (!$pid) {
-		exec(qw(git ls-files -z -u)) or die "$!: ls-files";
-	}
 	my %path = ();
 	my @path = ();
-	while (<$in>) {
+	foreach (qx{git-ls-files -z -u}) {
 		chomp;
 		my ($mode, $sha1, $stage, $path) =
 		    /^([0-7]+) ([0-9a-f]{40}) ([123])\t(.*)$/s;
 		$path{$path} |= (1 << $stage);
 	}
-	close $in;
+	!$? or exit $?;
 	while (my ($path, $status) = each %path) {
 		if ($status == 14) { push @path, $path; }
 	}
diff --git a/git-send-email.perl b/git-send-email.perl
index b0d095b..bd8fae6 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -62,13 +62,8 @@ my $rc = GetOptions("from=s" => \$from,
 sub gitvar {
     my ($var) = @_;
     my $fh;
-    my $pid = open($fh, '-|');
-    die "$!" unless defined $pid;
-    if (!$pid) {
-	exec('git-var', $var) or die "$!";
-    }
-    my ($val) = <$fh>;
-    close $fh or die "$!";
+    my ($val) = qx{git-var $var};
+    !$? or exit $?;
     chomp($val);
     return $val;
 }
diff --git a/git-svnimport.perl b/git-svnimport.perl
index ee2940f..6094a11 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -218,11 +218,10 @@ unless(-d $git_dir) {
 	-f "$git_dir/svn2git"
 		or die "'$git_dir/svn2git' does not exist.\n".
 		       "You need that file for incremental imports.\n";
-	open(F, "git-symbolic-ref HEAD |") or
-		die "Cannot run git-symbolic-ref: $!\n";
-	chomp ($last_branch = <F>);
+	$last_brach = qx{git-symbolic-ref HEAD};
+	!$? or exit $?;
+	chomp $last_branch;
 	$last_branch = basename($last_branch);
-	close(F);
 	unless($last_branch) {
 		warn "Cannot read the last branch name: $! -- assuming 'master'\n";
 		$last_branch = "master";
@@ -321,15 +320,9 @@ sub get_file($$$) {
 		return undef unless defined $name;
 	}
 
-	my $pid = open(my $F, '-|');
-	die $! unless defined $pid;
-	if (!$pid) {
-	    exec("git-hash-object", "-w", $name)
-		or die "Cannot create object: $!\n";
-	}
-	my $sha = <$F>;
+	my $sha = qx{git-hash-object -w $name};
+	!$? or exit $?;
 	chomp $sha;
-	close $F;
 	unlink $name;
 	my $mode = "0644"; # SV does not seem to store any file modes
 	return [$mode, $sha, $path];
@@ -401,14 +394,8 @@ sub copy_path($$$$$$$$) {
 			$srcpath =~ s#/*$#/#;
 	}
 	
-	my $pid = open my $f,'-|';
-	die $! unless defined $pid;
-	if (!$pid) {
-		exec("git-ls-tree","-r","-z",$gitrev,$srcpath)
-			or die $!;
-	}
 	local $/ = "\0";
-	while(<$f>) {
+	foreach (qx{git-ls-tree -r -z $gitrev $srcpath}) {
 		chomp;
 		my($m,$p) = split(/\t/,$_,2);
 		my($mode,$type,$sha1) = split(/ /,$m);
@@ -420,8 +407,7 @@ sub copy_path($$$$$$$$) {
 		}
 		push(@$new,[$mode,$sha1,$p]);	
 	}
-	close($f) or
-		print STDERR "$newrev:$newbranch: could not list files in $oldpath \@ $rev\n";
+	!$? or exit $?;
 }
 
 sub commit {
@@ -472,9 +458,8 @@ sub commit {
 
 	my $rev;
 	if($revision > $opt_s and defined $parent) {
-		open(H,"git-rev-parse --verify $parent |");
-		$rev = <H>;
-		close(H) or do {
+		$rev = qx{git-rev-parse --verify $parent};
+		!$? or do {
 			print STDERR "$revision: cannot find commit '$parent'!\n";
 			return;
 		};
@@ -555,25 +540,20 @@ sub commit {
 		}
 
 		while(@old) {
-			my @o1;
+			my @o2;
 			if(@old > 55) {
-				@o1 = splice(@old,0,50);
+				@o2 = splice(@old,0,50);
 			} else {
-				@o1 = @old;
+				@o2 = @old;
 				@old = ();
 			}
-			my $pid = open my $F, "-|";
-			die "$!" unless defined $pid;
-			if (!$pid) {
-				exec("git-ls-files", "-z", @o1) or die $!;
-			}
-			@o1 = ();
+			my @o1 = ();
 			local $/ = "\0";
-			while(<$F>) {
+			foreach (qx{git-ls-files -z @o1}) {
 				chomp;
 				push(@o1,$_);
 			}
-			close($F);
+			!$? or exit $?;
 
 			while(@o1) {
 				my @o2;
@@ -600,17 +580,11 @@ sub commit {
 			die "Cannot add files: $?\n" if $?;
 		}
 
-		my $pid = open(C,"-|");
-		die "Cannot fork: $!" unless defined $pid;
-		unless($pid) {
-			exec("git-write-tree");
-			die "Cannot exec git-write-tree: $!\n";
-		}
-		chomp(my $tree = <C>);
+		my $tree = qx{git-write-tree};
+		!$? or exit $?;
+		chomp($tree);
 		length($tree) == 40
 			or die "Cannot get tree id ($tree): $!\n";
-		close(C)
-			or die "Error running git-write-tree: $?\n";
 		print "Tree ID $tree\n" if $opt_v;
 
 		my $pr = IO::Pipe->new() or die "Cannot open pipe: $!\n";
-- 
1.2.3.gb37d

Re: [PATCH] Convert open("-|") to qx{} calls

From: Alex Riesen <hidden>
Date: 2016-06-15 22:42:20

On 2/23/06, Johannes Schindelin [off-list ref] wrote:
      Since of these 4, I only use cvsimport myself, I could only test
      that. Could someone who uses the others give them a hard beating?
I can't really test them (no svn and cvs, and locked down network), but I took
a look at the patches. Hope it helps.

git-cvsimport:
-               open(F,"git-cat-file commit $ftag |");
-               while(<F>) {
+               foreach (qx{git-cat-file commit $ftag}) {
                        next unless /^author\s.*\s(\d+)\s[-+]\d{4}$/;
Are you sure you don't need quoting/safe pipe here?
Or is it a CVS tag?
+} else {
+    @input = qx{cvsps --norc opt -u -A --root $opt_d $cvs_tree};
+    !$? or exit $?;
Same here. $cvs_tree can contain any filesystem-allowed character.

git-svnimport:
-                       my $sha = <$F>;
+                       my $sha = qx{git-hash-object -w $tmpname};
+                       !$? or exit $?;
Is $tmpname safe?
-       my $sha = <$F>;
+       my $sha = qx{git-hash-object -w $name};
+       !$? or exit $?;
Is $name safe?
-       while(<$f>) {
+       foreach (qx{git-ls-tree -r -z $gitrev $srcpath}) {
                chomp;
Is $srcpath safe?
-                       while(<$F>) {
+                       foreach (qx{git-ls-files -z @o1}) {
@o1 must contain filenames. Can be dangerous

Re: [PATCH] Convert open("-|") to qx{} calls

From: Randal L. Schwartz <hidden>
Date: 2016-06-15 22:42:20

quoted
quoted
quoted
quoted
"Alex" == Alex Riesen [off-list ref] writes:
Alex> Is $tmpname safe?
quoted
-       my $sha = <$F>;
+       my $sha = qx{git-hash-object -w $name};
+       !$? or exit $?;
Alex> Is $name safe?
quoted
-       while(<$f>) {
+       foreach (qx{git-ls-tree -r -z $gitrev $srcpath}) {
chomp;
Alex> Is $srcpath safe?
quoted
-                       while(<$F>) {
+                       foreach (qx{git-ls-files -z @o1}) {
Alex> @o1 must contain filenames. Can be dangerous

Convert all of these to use "safe_qx" (perl 5.6 compatible):

    sub safe_qx {
      defined (my $pid = open my $kid, "-|") or die "Cannot fork: $!";
      unless ($pid) { # child does:
        exec @_;
        die "Cannot exec @_: $!";
      }
      my $result = do { local $/; <$kid> };
      close $kid;                   # sets $?
      return $result;
    }

my $result = safe_qx('some shell command');
my $other_result = safe_qx('git-ls-tree', '-r', '-z', $gitrev, $srcpath);

Args are safe, as if being passed to system/exec, so a single arg
can be a shell command, multiargs are passed arg-by-arg to a single
exec target.  $? is set correctly.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
[off-list ref] <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Re: [PATCH] Convert open("-|") to qx{} calls

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:20

merlyn@stonehenge.com (Randal L. Schwartz) writes:
Convert all of these to use "safe_qx" (perl 5.6 compatible):

    sub safe_qx {
      defined (my $pid = open my $kid, "-|") or die "Cannot fork: $!";
...
IIRC, that is backwards.  The thread's conversion is not about
5.6 vs 5.8.  The conversion like what you suggested above was
done, but the thing is, and Alex's Perl is unhappy about it.

The version of Perl Alex has to use claims to be 5.8, but does
not understand open($kid, '-|'), and he is trying to come up
with a workaround.

I wish Perl had a stricter trademark policy that required
language features to be fully ported for an implementation to
use that name ;-).

Re: [PATCH] Convert open("-|") to qx{} calls

From: Randal L. Schwartz <hidden>
Date: 2016-06-15 22:42:20

quoted
quoted
quoted
quoted
"Junio" == Junio C Hamano [off-list ref] writes:
Junio> The version of Perl Alex has to use claims to be 5.8, but does
Junio> not understand open($kid, '-|'), and he is trying to come up
Junio> with a workaround.

Ahh, the problem is activestate then.  If that's the case, then amend the code
with a check for $^O (operating system) that falls back to a qx if on
activestate, and hope that filenames aren't a problem.  Unfortunately, I don't
know enough about that to fix it.

But whatever you do, *don't* replace safe_qx with qx() for all other systems,
or you'll be opening up a can of worms for those of us on sensible systems.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
[off-list ref] <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Re: [PATCH] Convert open("-|") to qx{} calls

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:42:20

Hi,

On Thu, 23 Feb 2006, Randal L. Schwartz wrote:
quoted
quoted
quoted
quoted
quoted
"Junio" == Junio C Hamano [off-list ref] writes:
Junio> The version of Perl Alex has to use claims to be 5.8, but does
Junio> not understand open($kid, '-|'), and he is trying to come up
Junio> with a workaround.

Ahh, the problem is activestate then.  If that's the case, then amend 
the code with a check for $^O (operating system) that falls back to a qx 
if on activestate, and hope that filenames aren't a problem.  
Unfortunately, I don't know enough about that to fix it.
Now that our local Perl guru joined the discussion, may I ask what is, and 
what is not quoted when put inside qx{}? I had the impression that all 
arguments are quoted, except that variables are resolved first. Was that 
wrong? IOW does

	qx{bash $variable}

quote the value of $variable, or not?

Ciao,
Dscho

Re: [PATCH] Convert open("-|") to qx{} calls

From: Randal L. Schwartz <hidden>
Date: 2016-06-15 22:42:20

quoted
quoted
quoted
quoted
"Johannes" == Johannes Schindelin [off-list ref] writes:
Johannes> Now that our local Perl guru joined the discussion, may I ask what
Johannes> is, and what is not quoted when put inside qx{}?

Nothing is quoted.  Your string acts as if it was XXX in:

        sh -c 'XXX'

so any quoting is entirely on your own.  Thus, without the multi-arg exec in
my proposed replacement, you can get shell-ish interactions that can ruin your
day pretty bad.

Johannes>  I had the
Johannes> impression that all arguments are quoted, except that variables are
Johannes> resolved first. Was that wrong? IOW does

Johannes> 	qx{bash $variable}

Johannes> quote the value of $variable, or not?

The Perl $variable is expanded to its current contents.  But suppose the
contents are `date` (including the backquotes).  That would mean that a shell
would execute a date command, and *its* output would then contribute further
to the command invocation.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
[off-list ref] <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Re: [PATCH] Convert open("-|") to qx{} calls

From: Alex Riesen <hidden>
Date: 2016-06-15 22:42:20

Randal L. Schwartz, Thu, Feb 23, 2006 21:41:44 +0100:
Johannes> Now that our local Perl guru joined the discussion, may I ask what
Johannes> is, and what is not quoted when put inside qx{}?

Nothing is quoted.  Your string acts as if it was XXX in:

        sh -c 'XXX'
Not so for ActiveState. It'll just run the first non-whitespace word
passing the rest of the line in its command-line.
It's not even worse then to pass it all to cmd/command :)

Re: [PATCH] Convert open("-|") to qx{} calls

From: Randal L. Schwartz <hidden>
Date: 2016-06-15 22:42:20

quoted
quoted
quoted
quoted
"Alex" == Alex Riesen [off-list ref] writes:
Alex> Randal L. Schwartz, Thu, Feb 23, 2006 21:41:44 +0100:
Johannes> Now that our local Perl guru joined the discussion, may I ask what
Johannes> is, and what is not quoted when put inside qx{}?
quoted
Nothing is quoted.  Your string acts as if it was XXX in:

sh -c 'XXX'
Alex> Not so for ActiveState. It'll just run the first non-whitespace word
Alex> passing the rest of the line in its command-line.
Alex> It's not even worse then to pass it all to cmd/command :)

Right.  That's why I suggest (in a later message) that safe_qx merely
fall back to qx() on Activestate.  Can't go much more wrong. :)

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
[off-list ref] <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Re: [PATCH] Convert open("-|") to qx{} calls

From: Rogan Dawes <hidden>
Date: 2016-06-15 22:42:20

Alex Riesen wrote:
Randal L. Schwartz, Thu, Feb 23, 2006 21:41:44 +0100:
quoted
Johannes> Now that our local Perl guru joined the discussion, may I ask what
Johannes> is, and what is not quoted when put inside qx{}?

Nothing is quoted.  Your string acts as if it was XXX in:

        sh -c 'XXX'
Not so for ActiveState. It'll just run the first non-whitespace word
passing the rest of the line in its command-line.
It's not even worse then to pass it all to cmd/command :)
Not true.

 > type t
#!perl -w

print qx{echo joe & echo joe}."\n";
 > perl t
joe
joe

 >

If the shell was not interpreting the arguments, you would expect to get 
1 line with:

joe & echo joe

on it.

 > perl -v
This is perl, v5.8.7 built for MSWin32-x86-multi-thread
(with 7 registered patches, see perl -V for more detail)

Copyright 1987-2005, Larry Wall

Binary build 813 [148120] provided by ActiveState http://www.ActiveState.com
ActiveState is a division of Sophos.
Built Jun  6 2005 13:36:37

Perl may be copied only under the terms of either the Artistic License 
or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'.  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

Regards,

Rogan

Re: [PATCH] Convert open("-|") to qx{} calls

From: Alex Riesen <hidden>
Date: 2016-06-15 22:42:20

On 2/24/06, Rogan Dawes [off-list ref] wrote:
Alex Riesen wrote:
quoted
Randal L. Schwartz, Thu, Feb 23, 2006 21:41:44 +0100:
quoted
Johannes> Now that our local Perl guru joined the discussion, may I ask what
Johannes> is, and what is not quoted when put inside qx{}?

Nothing is quoted.  Your string acts as if it was XXX in:

        sh -c 'XXX'
Not so for ActiveState. It'll just run the first non-whitespace word
passing the rest of the line in its command-line.
It's not even worse then to pass it all to cmd/command :)
Not true.

 > type t
#!perl -w

print qx{echo joe & echo joe}."\n";
 > perl t
joe
joe
Does not seem to be the case here (and yes, I check build 815 too):

$ perl -v

This is perl, v5.8.6 built for MSWin32-x86-multi-thread
(with 3 registered patches, see perl -V for more detail)

Copyright 1987-2004, Larry Wall

Binary build 811 provided by ActiveState Corp. http://www.ActiveState.com
ActiveState is a division of Sophos.
Built Dec 13 2004 09:52:01
...

$ perl -e 'print qx{echo joe & echo joe}."\n";'
joe & echo joe

Re: [PATCH] Convert open("-|") to qx{} calls

From: Rogan Dawes <hidden>
Date: 2016-06-15 22:42:20

Alex Riesen wrote:
On 2/24/06, Rogan Dawes [off-list ref] wrote:
quoted
Not true.

 > type t
#!perl -w

print qx{echo joe & echo joe}."\n";
 > perl t
joe
joe
Does not seem to be the case here (and yes, I check build 815 too):

$ perl -v

This is perl, v5.8.6 built for MSWin32-x86-multi-thread
(with 3 registered patches, see perl -V for more detail)

Copyright 1987-2004, Larry Wall

Binary build 811 provided by ActiveState Corp. http://www.ActiveState.com
ActiveState is a division of Sophos.
Built Dec 13 2004 09:52:01
...

$ perl -e 'print qx{echo joe & echo joe}."\n";'
joe & echo joe
Interesting. I tried to do that one-liner at a DOS prompt (not cygwin, 
which I assume you are using), and I was unable to do so. CMD was seeing 
the "&" first, and splitting the command in 2, namely

perl -e 'print qx joe

and

echo joe}."\n";'

which obviously didn't work.

Do you get the same results if you run it from a DOS prompt? and via a file?

Rogan

Re: [PATCH] Convert open("-|") to qx{} calls

From: Alex Riesen <hidden>
Date: 2016-06-15 22:42:20

On 2/24/06, Rogan Dawes [off-list ref] wrote:
Interesting. I tried to do that one-liner at a DOS prompt (not cygwin,
which I assume you are using), and I was unable to do so.
Yes, it was from cygwin's bash.
Do you get the same results if you run it from a DOS prompt? and via a file?
Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

C:\>perl -e 'print qx{echo joe & echo joe}'
Can't find string terminator "'" anywhere before EOF at -e line 1.
joe}'

C:\>perl -e "print qx{echo joe & echo joe}"
joe & echo joe

C:\>perl x.pl
joe & echo joe

C:\>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help