0

I am running Kubuntu 20.04. The perl version is shown by perl -v to be

perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux-gnu-thread-multi (with 50 registered patches, see perl -V ...

I have made apt-get update and with Muon package manager I have all installed perl packages upgraded.

But after that, perl is 5 as before, I have not got perl 6.

I need to use the command qx{..}, i.e. backtick command in order to get the result of linux xxd utility.

On that way I use in a konsole terminal the shell bash with following script, with intentionally an error in the variable $WEx:

perl -we '$WEx=q{"date|"<>"}; print "\nWEx: ~", $WEx, "~\n\n"; $WEa=<<"EOT";

echo -n \\\\\\"$WEx\\\\\\";

EOT

print "\nWEa: ~", $WEa, "~\n"; 

print qx! $WEa !, "\n\n";'

The result are these lines: two lines showing WEx and WEa and an error message:

WEx: ~"date|"<>"~

WEa: ~echo -n \\\""date|"<>"\\\";
~

sh: 2: Syntax error: Unterminated quoted string
==

The error message comes from this this code:

qx! $WEa !

That means, in a spawned shell the command line contained in the variable $WEa is to be executed.

i.e. this shell command:

echo -n \\\""date|"<>"\\\";

i.e. the shell should execute the command "echo", and "echo" has to output the text in the argument that follows.

"echo" should output the text literally without regard what it is, if a command or not, if a command with failure.

But instead, the text is executed as if being a command, and because the false double quote, the error message is given.

I have tried many days with various writings and various codes.

The shell allways cannot handle the line given by the backtick command correcly.

What I am making false?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • No, echo is not guaranteed to emit text literally. Read [the POSIX specification for the `echo` command](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html) -- particularly the APPLICATION USAGE and RATIONALE sections -- and [Why is printf better than echo?](https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo) over at [unix.se]. – Charles Duffy Feb 18 '22 at 22:47
  • 1
    Beyond that, when you put two syntactic quotes of the same type next to each other in a shell command, **they cancel each other out**. Try it yourself: `printf '%s\n' ""hello world""` acts just like `printf '%s\n' hello world`, and **not** like `printf '%s\n' "hello world"`. – Charles Duffy Feb 18 '22 at 22:48
  • 4
    Anyhow -- can you build a simplified [mre] that removes as many elements of your question as possible? You'll get better answers if your question is written to require _only_ perl expertise or _only_ shell expertise, not both together. (Also, note that bash and sh are two different shells, and you should ask about one or the other, not both at the same time; even on the subset of Linux distros where `/bin/sh` is a link to `/bin/bash`, it runs in a compatibility mode when started under that name). – Charles Duffy Feb 18 '22 at 22:50
  • 1
    BTW, if you want to distinguish between a perl problem and a shell problem, one good place to start is to use `strace` to watch the exact shell command that the perl interpreter starts (arguments will be passed in an `execve` syscall). If the shell command is what you think it should be, then it's not a perl problem so you can ask only about shell and not perl; if the shell command is different from what you intend, then you can ask only about perl and not shell. – Charles Duffy Feb 18 '22 at 22:53

2 Answers2

1

echo -n \\\""date|"<>"\\\"; is not a valid shell command and the shell is handling it correctly when it announces a syntax error. How to fix the problem depends on what you are trying to do. That is not clear. (Also unclear is what this has to do with getting the result of xxd.)

One possibility is that you are trying to generate a shell command that will print the value of the $WEx Perl variable. If that is the case, the easiest shell code to use is

echo -n '"date|"<>"'

(a semicolon is not needed at the end in shell code). You need to modify your Perl code to put this code in the $WEa variable. Unfortunately, modifying the existing code to add single quotes is a bit fiddly because it's all inside shell single quotes. See How to escape single quotes within single quoted strings for details of how to do it.

Possible code (without the debugging output) is:

perl -we   '$WEx=q{"date|"<>"};
            $WEa=qq{echo -n '\''$WEx'\''};
            print qx{$WEa}, "\n\n";'
pjh
  • 6,388
  • 2
  • 16
  • 17
0

The reason of my trials was on the way to pass a perl variable with an arbitrary text into a backtick command where it is piped to shell utility xxd.

Here is my working version using the given code:

perl -we '$WEx=q{"date|"<>"}; $WEa=qq{echo -n '\''$WEx'\'' | xxd -g1}; print qx{$WEa}, "\n\n";'

This works, gives the correct hex code.

The key of the solution and my rationale is: despite of the fact that the total perl code is delimited by single quotes, inside of the perl code single quotes can be used if in qq{}.

Machavity
  • 30,841
  • 27
  • 92
  • 100