如何将字符串解释为使用perl中的参数执行的命令

时间:2020-12-07 01:50:38

Trying to find an equivalent solution for below in perl. Suppose I have the following POSIX shell script:

试图在perl中找到下面的等效解决方案。假设我有以下POSIX shell脚本:

#!/bin/sh

MY_CMD='WDT=$1; shift ; printf "%-${WDT}.${WDT}s\n" "$@"'
eval $MY_CMD

An suppose that above is being saved as my_script.sh

假设上面的内容被保存为my_script.sh

And if I execute it like: ./my_script.sh 4 Hello to thise nice girls then the output will be like:

如果我执行它像:./ my_script.sh 4你好这个好女孩然后输出将是:

Hell
to
this
nice
girl

How can I do the same using perl. Here the main problems is how do I take perl input parameters and pass them to my command saved in an variable so that those parameters will get evaluated accordingly to the ones from input (in shell eval does this properly).

我怎样才能使用perl做同样的事情。这里的主要问题是如何获取perl输入参数并将它们传递给保存在变量中的命令,以便相应地对这些参数进行评估(在shell eval中这样做是正确的)。

Should it be that I asked horribly stupid questions, please excuse me as I just started learning perl .o)

应该是我问了可怕的愚蠢问题,请原谅我,因为我刚开始学习perl .o)

EDIT: I think I need to clarify myself more with the question... I NEED to have the command in a variable. I have simplified the script example here to understand easily the problem. In all solutions so far you are giving me solution how that same task to be done in perl, but please don't focus on the command itself, that is just an example:

编辑:我想我需要更多地澄清自己的问题......我需要在变量中使用命令。我在这里简化了脚本示例,以便轻松理解问题。到目前为止,在所有解决方案中,你给我解决了如何在perl中完成同样的任务,但请不要专注于命令本身,这只是一个例子:

Other Examples would be: MY_CMD='export AWKNUMF="%.2f"; exe 93 "$1" "$2" "$3" $(shift 3; echo "$@") | sort -k1,1 | exe 93 ":" 1 2'

其他例子是:MY_CMD ='export AWKNUMF =“%。2f”; exe 93“$ 1”“$ 2”“$ 3”$(shift 3; echo“$ @”)| sort -k1,1 | exe 93“:”1 2'

and so on...

等等...

The idea that MY_CMD variable would be populated with some command retrieved from a repository which expects some parameters and I want those parameters to be provided in the input to the perl.

认为MY_CMD变量将填充从存储库中检索到的某些命令,该存储库需要一些参数,并且我希望在perl的输入中提供这些参数。

SYNOPSYS would be ./perl_script.pl my_command_name [param1 [param2 ... [paramN]]]

SYNOPSYS将是./perl_script.pl my_command_name [param1 [param2 ... [paramN]]]

The point here is that you should not focus on the content of the MY_CMD variable. It is just a shell command(s) which gets parameters along.

这里的要点是你不应该关注MY_CMD变量的内容。它只是一个获取参数的shell命令。

the perl equivalent would be something like:

perl等价物将是这样的:

system ($my_cmd, "@ARGV"); but this of course does not work as expected.

system($ my_cmd,“@ ARGV”);但这当然不能按预期工作。

3 个解决方案

#1


No eval needed in Perl (I doubt it's needed in the shell, either).

Perl中不需要eval(我怀疑它在shell中是否需要)。

#!/usr/bin/perl
use warnings;
use strict;

my $width = shift;
printf "%-$width.${width}s\n", $_ for @ARGV;

#2


There's two elements to your request.

您的请求有两个要素。

Firstly - perl uses @ARGV to hold command line parameters. You can access individual elements either with shift or $ARGV[1].

首先 - perl使用@ARGV来保存命令行参数。您可以使用shift或$ ARGV [1]访问单个元素。

Secondly - eval works in perl too - but you'll probably find there's a better way of doing what you're trying to do.

其次 - eval也可以在perl中运行 - 但你可能会发现有更好的方法可以做你正在尝试做的事情。

So to take your example:

所以举个例子:

#!/usr/bin/perl
use strict;
use warnings;

my ( $WDT, @words ) = @ARGV; 

foreach my $word ( @words ) {
   printf ( "%-${WDT}.${WDT}s\n", $word );
}

#3


How can I do the same using perl.

我怎样才能使用perl做同样的事情。

Perl too has the eval() function. It can take a string and evaluate it in the context it was called from.

Perl也有eval()函数。它可以采用字符串并在调用它的上下文中对其进行评估。

Here the main problems is how do I take perl input parameters and pass them to my command saved in an variable so that those parameters will get evaluated accordingly to the ones from input (in shell eval does this properly).

这里的主要问题是如何获取perl输入参数并将它们传递给保存在变量中的命令,以便相应地对这些参数进行评估(在shell eval中这样做是正确的)。

You have to create the variables before the eval'ed Perl code can access. That also would, depending on the implementation, bypass or conflict directly with the use strict.

您必须在eval'ed Perl代码可以访问之前创建变量。根据实施情况,这也会直接绕过或严格违反use。

I'm away of two way to create the variables: using eval or by creating them by manipulating the symbol table. Consider:

我没有两种方法来创建变量:使用eval或通过操作符号表创建它们。考虑:

my $value_of_a = 10;
my $value_of_b = 20;

# alt1 : create vars using `eval`
eval '$a = '.$value_of_a;
eval '$b = '.$value_of_b;
eval q{ print "$a + $b = ", $a+$b, "\n"; };

# alt2 : create the vars by manipulating the symbol table directly
$var_name = "aa";
${"::$var_name"} = $value_of_a;
$var_name = "bb";
${"::$var_name"} = $value_of_b;
eval q{ print "$aa + $bb = ", $aa+$bb, "\n"; };

To avoid calling the eval every time to interpret the code, one can also try to wrap the code into a nameless function and eval it once to create the subroutine which can be called at any time. Consider:

为了避免每次调用eval来解释代码,我们也可以尝试将代码包装到无名函数中并将其重复一次以创建可以随时调用的子例程。考虑:

# the input data:
my $var_name_a = 'a';
my $var_name_b = 'b';
my $value_of_a = 10;
my $value_of_b = 20;
my $cmd = 'print "$a + $b = ", $a+$b, "\n";';

# the preparations:
eval '$'.$var_name_a.' = '.$value_of_a;
eval '$'.$var_name_b.' = '.$value_of_b;
my $sub = eval 'sub { '. $cmd .' }';

# the execution:
$sub->();

#1


No eval needed in Perl (I doubt it's needed in the shell, either).

Perl中不需要eval(我怀疑它在shell中是否需要)。

#!/usr/bin/perl
use warnings;
use strict;

my $width = shift;
printf "%-$width.${width}s\n", $_ for @ARGV;

#2


There's two elements to your request.

您的请求有两个要素。

Firstly - perl uses @ARGV to hold command line parameters. You can access individual elements either with shift or $ARGV[1].

首先 - perl使用@ARGV来保存命令行参数。您可以使用shift或$ ARGV [1]访问单个元素。

Secondly - eval works in perl too - but you'll probably find there's a better way of doing what you're trying to do.

其次 - eval也可以在perl中运行 - 但你可能会发现有更好的方法可以做你正在尝试做的事情。

So to take your example:

所以举个例子:

#!/usr/bin/perl
use strict;
use warnings;

my ( $WDT, @words ) = @ARGV; 

foreach my $word ( @words ) {
   printf ( "%-${WDT}.${WDT}s\n", $word );
}

#3


How can I do the same using perl.

我怎样才能使用perl做同样的事情。

Perl too has the eval() function. It can take a string and evaluate it in the context it was called from.

Perl也有eval()函数。它可以采用字符串并在调用它的上下文中对其进行评估。

Here the main problems is how do I take perl input parameters and pass them to my command saved in an variable so that those parameters will get evaluated accordingly to the ones from input (in shell eval does this properly).

这里的主要问题是如何获取perl输入参数并将它们传递给保存在变量中的命令,以便相应地对这些参数进行评估(在shell eval中这样做是正确的)。

You have to create the variables before the eval'ed Perl code can access. That also would, depending on the implementation, bypass or conflict directly with the use strict.

您必须在eval'ed Perl代码可以访问之前创建变量。根据实施情况,这也会直接绕过或严格违反use。

I'm away of two way to create the variables: using eval or by creating them by manipulating the symbol table. Consider:

我没有两种方法来创建变量:使用eval或通过操作符号表创建它们。考虑:

my $value_of_a = 10;
my $value_of_b = 20;

# alt1 : create vars using `eval`
eval '$a = '.$value_of_a;
eval '$b = '.$value_of_b;
eval q{ print "$a + $b = ", $a+$b, "\n"; };

# alt2 : create the vars by manipulating the symbol table directly
$var_name = "aa";
${"::$var_name"} = $value_of_a;
$var_name = "bb";
${"::$var_name"} = $value_of_b;
eval q{ print "$aa + $bb = ", $aa+$bb, "\n"; };

To avoid calling the eval every time to interpret the code, one can also try to wrap the code into a nameless function and eval it once to create the subroutine which can be called at any time. Consider:

为了避免每次调用eval来解释代码,我们也可以尝试将代码包装到无名函数中并将其重复一次以创建可以随时调用的子例程。考虑:

# the input data:
my $var_name_a = 'a';
my $var_name_b = 'b';
my $value_of_a = 10;
my $value_of_b = 20;
my $cmd = 'print "$a + $b = ", $a+$b, "\n";';

# the preparations:
eval '$'.$var_name_a.' = '.$value_of_a;
eval '$'.$var_name_b.' = '.$value_of_b;
my $sub = eval 'sub { '. $cmd .' }';

# the execution:
$sub->();