2

A Perl system call must send the following string to the UnixShell:

'"XYZ"'

In my Perl script I have used the following command:

system("cleartool mkattr -replace ATTRIBUTE '"$attribute"' lbtype:$label");

Everything is well passed to the Shell Unix, except both uses of the quote character:

'

Indeed,

cleartool mkattr -replace ATTRIBUTE

The above command is passed as it is exactly what I want. The Perl variables $attribute and $label are well interpreted. But I don't know what to do to obtain exactly:

'"XYZ"'

Here XYZ is the value of the Perl variable $attribute OS is AIX (Unix) and Shell is ksh. cleartool is the command line interface of Clearcase but no Clearcase skill is necessary to fix my problem.

ssr1012
  • 2,573
  • 1
  • 18
  • 30
Martin
  • 77
  • 4
  • 4
    The shown Perl code with `system(…)` shouldn't even compile since the `"` before the `$attribute` variable should terminate the previous string. Are you sure that's the code you are using? – amon Nov 16 '17 at 12:49
  • 1
    How are you not getting a runtime error? Are you sure it's not `system("clear ... BUTE '" . $attribute ...` You can't concatenate strings with no operator like that. – William Pursell Nov 16 '17 at 12:50
  • It's not clear from my question I WANT TO pass '"XYZ"' not "XYZ". – Martin Nov 16 '17 at 15:42
  • I have to wonder if you *do* have to send that exact string. It looks like you are trying to build up a command line, and confusing literal quotes with syntactic quotes. `system("cleartool", "mkattr", "-replace", "ATTRIBUTE", $attribute, "lbtype$label")` is probably what you want. – chepner Nov 16 '17 at 16:05

2 Answers2

7

If you want to execute a system command and don't have to use any shell syntax like redirects, it's usually better and safer to use the list form of system:

system(
    'cleartool',  'mkattr', '-replace', 'ATTRIBUTE',
    qq{"$attribute"}, qq{lbtype:$label}
);
# or, if you really want to pass both types of quotes:
system(
    'cleartool',  'mkattr', '-replace', 'ATTRIBUTE',
    qq{'"$attribute"'}, qq{lbtype:$label}
);

See perldoc -f system

It's not clear from your question if you want to pass '"XYZ"' or "XYZ".

tinita
  • 3,987
  • 1
  • 21
  • 23
  • `qq{"$attribute"}` can be replaced with `$attribute`. – shawnhcorey Nov 16 '17 at 13:05
  • 4
    @shawnhcorey that would be something different. It depends if the OP really wants to pass the quotes to the program or not – tinita Nov 16 '17 at 13:06
  • @shawnhcorey It is pretty clear. The heading says _system call must send exactly both characters '"_ Later in the actual body, he also states _except both uses of the quote character:_ – Gerhard Nov 16 '17 at 13:21
  • 1
    @GerhardBarnard the OP says `'"XYZ"'` should be passed to the *shell*. but it's not clear (at least to me) what `cleartool` should end up with. – tinita Nov 16 '17 at 13:37
  • 1
    @tinita Agreed. When a string of quotes appear in a shell command, I suspect an XY problem. – shawnhcorey Nov 16 '17 at 14:09
  • Both uses of the quote character means exactly that, both single and double quotes, just as mentioned in the heading and twice in the actual answer. – Gerhard Nov 16 '17 at 14:24
  • 1
    @shawncorey: The question may be unclear, but `qq{"$attribute"}` is certainly not equivalent to `$attribute`. Your comment is incorrect. – Borodin Nov 16 '17 at 17:40
1

See "Quote and Quote like Operators" and use qq{...}:

system(qq{cleartool mkattr -replace ATTRIBUTE '"$attribute"' lbtype:$label});

qq{...} is exactly like "..." except you can then use double quotes " in your string without escaping them.

You can use any character directly after the qq and must then use the same character to denote the end-of-string, i.e. qqX...X would work the same way. You would run into problems if your string contains Xes, so don't do that.

You can also use paired characters as delimiter ({}, (), <>) which is what you usually will see.

PerlDuck
  • 5,610
  • 3
  • 20
  • 39
  • I learned a lot from your answer, thanks a lot. But the result is always the same. I lose the character: ' , it is replaced by: " , I tested many other possibilities... escape the quote, the double quote, both... qq keeps everything even back slash but not the single quote. – Martin Nov 16 '17 at 15:34
  • @Martin: That isn't true. `qq//` doesn't retain backslashes and won't remove single quotes. Try printing the values before you pass them to `system`. – Borodin Nov 16 '17 at 17:42