结果

结果

我正在编写一个 perl 脚本,它接受一个字符串并将其传递到 .csh 脚本中。

PerlScript.pl:

$CMDLineArgs = "-stuff -more_stuff \'-even_more \"*stuff\" -last_stuff\'";
system(Script.csh $CMDLineArgs);

脚本.csh:

set flags="$argv[*]"

由于某种原因,单引号没有进入我的 .csh 脚本,并且如果 * 位于字符串中的任何位置,则整个事情将无法工作。关于如何将 Perl 脚本中出现的字符串准确地放入 csh 脚本中,有什么建议吗?

答案1

Perlquote为您似乎遇到的这种情况提供了各种-ing 运算符。特别是qw//qq//、 和q//运算符,分别代表quote worddouble quote string、 和single quote string运算符。您会注意到,它们完全消除了引用数据的苦差事。

正如已经指出的那样,出于安全原因,使用通过 a而不是 insystem()提供的参数可以更好地提供该命令。listscalars

最后,在cshell代码内部,您需要使用:q修饰符来引用变量。

%  cat PerlScript.pl

my @Args = (
   qw/     -stuff  /,                    # whitespace ignored
   qw/ -more_stuff /,                    # whitespace ignored
   q['-even more "*stuff" -last_stuff'], # whitespace IMPORTANT
);

my $csh_script = q[Script.csh];

system($csh_script, @Args) and
   die qq[Error: The script $csh_script has failed with exit code:], $? >> 8;

% cat Script.csh

foreach arg ( $argv[*]:q )
   echo "<$arg>"
end

结果

<-stuff>
<-more_stuff>
<'-even more "*stuff" -last_stuff'>

笔记

  • 如果您认为输出不符合您的喜好,请不要更改 csh 脚本中的任何内容。而是@Args在 PerlScript.pl 文件中进行操作。
  • 例如,如果您要填充@Args如下所示的内容:

my @Args = (
   qw/     -stuff  /,
   qw/ -more_stuff /,
   q['-even more],
   q["*stuff"],
   q[-last_stuff'],
   #q['-even more "*stuff" -last_stuff'],
);

然后你会看到以下结果:

<-stuff>
<-more_stuff>
<'-even more>
<"*stuff">
<-last_stuff'>

答案2

可能还有其他方法可以做到这一点(我不是 csh/tcsh 方面的专家 - 当我在 90 年代初不得不使用 csh 时,我不喜欢 csh,并且从那时起就尽可能避免使用它),但我唯一的方法发现在 tcsh 中做你想做的事情是用set nonomatchor set noglob。例如:

perlscript.pl:

#!/usr/bin/perl

@CMDLineArgs = ('-stuff', '-more_stuff', '-even_more', '*stuff', '-last_stuff');
system('./script.tcsh', @CMDLineArgs);

或者,如果您不想键入所有单引号和逗号,请使用qw()

@CMDLineArgs = qw(-stuff -more_stuff -even_more *stuff -last_stuff);

脚本.tcsh:

#!/bin/tcsh

set nonomatch
set flags=($argv[*])

foreach f ($flags)
  echo $f
end

输出是:

$ ./perlscript.pl
-stuff
-more_stuff
-even_more
*stuff
-last_stuff

请注意,这如何将每个参数保留为 中的单独元素$flags,而不是将它们全部连接到单个字符串中。

相关内容