use warnings; use strict; use Data::Dump; my $perl = "$^X -wMstrict -MData::Dump -e 'dd\\\@ARGV' -- "; dd qq{'"normal \r"'}; # prints "'\"normal \r\"'" print `$perl '"normal \r"'`; # => @ARGV is ("\"normal \r\"") my $value = '"normal \r"'; dd qq{$value}; # prints "\"normal \\r\"" print `$perl $value`; # => @ARGV is ("normal \\r") # "strace -s256 -fe trace=execve" (abbreviated by me) shows: # execve("/bin/sh", ["sh", "-c", "perl ... -- '\"normal \r\"'"], ... # execve("/bin/sh", ["sh", "-c", "perl ... -- \"normal \\r\""], ...