将脚本的输出作为独立的bash命令运行

时间:2021-11-13 22:11:43

suppose you have a perl script "foobar.pl" that prints the following to stdout

假设你有一个perl脚本“foobar.pl”,它将以下内容输出到stdout

date -R

and you want to run whatever that perl script outputs as a standalone bash command (don't worry about security problems as this is running in a trusted environment).

并且您希望运行perl脚本输出的任何内容作为独立的bash命令(不要担心安全问题,因为它在受信任的环境中运行)。

How do you get bash to recognize this as a standalone command?

你如何让bash认识到这是一个独立的命令?

I've tried using xargs, but that seems to want to pass arguments only to a pre-defined command.

我尝试过使用xargs,但似乎只想将参数传递给预先定义的命令。

I want the perl script to be able to output any arbitrary command.

我希望perl脚本能够输出任意命令。

$command = 'date -R'
system($command); ## in the perl script 

the above does not work because I want it to run in an existing cygwin environment ...

以上不起作用,因为我希望它在现有的cygwin环境中运行...

foobar.pl | xargs bash -i {}

the above does not work because bash seems to be running a new process and thus the initialization and settings from bash_profile don't get instantiated.

上面的方法不起作用,因为bash似乎正在运行一个新进程,因此bash_profile的初始化和设置不会被实例化。

6 个解决方案

#1


Bad:

`perl foo.pl`
$(perl foo.pl)

Why is this bad? Because of so many reasons; most notably:

为什么这么糟糕?由于这么多原因;最为显着地:

  • Wordsplitting: What you're doing here is taking the output of the perl script, splitting it into chunks wherever there are spaces, tabs or newlines, and taking those chunks as arguments to the first chunk which is the command to run. In really extremely simplistic cases like $(echo 'date +%s') it might work; but that's just a really bad representation of what you're REALLY doing here.
  • Wordsplitting:你在这里做的是获取perl脚本的输出,将其分成块,只要有空格,制表符或换行符,并将这些块作为参数传递给第一个块,即运行命令。在非常简单的情况下,例如$(echo'date +%s')它可能会起作用;但这只是你真正在这里做的非常糟糕的表现。

  • You cannot do quoting or use any other bash shell features like parameter expansion, bash keywords, etc.
  • 您不能引用或使用任何其他bash shell功能,如参数扩展,bash关键字等。

Good, but inconvenient:

好,但不方便:

perl foo.pl > mytmpfile; bash mytmpfile

Creating a temporary file to put your perl script's output into and then running that with bash works, but it's inconvenient as you need to create (and clean up!) your temporary file and have it in a portably writable (and secure!) location.

创建一个临时文件来将你的perl脚本的输出放入然后用bash运行,但是这很不方便,因为你需要创建(并清理!)你的临时文件并将它放在一个可移植的可写(和安全!)位置。

Also remember not to use . or source to execute the temporary file unless you really intend to run it all in the active shell. Moreover, when you use . or source, you won't be able to reliably clean up your temporary file afterward.

还记得不要用。或者来源执行临时文件,除非你真的打算在活动shell中运行它。而且,当你使用。或来源,您将无法可靠地清理您的临时文件。

Probably the best solution:

可能是最好的解决方案:

perl foo.pl | bash

This is pretty safe all-round ("safe" in the context of, least bug-prone) assuming your perl script outputs correct bash syntax, of course.

假设你的perl脚本输出正确的bash语法,这是全面安全的(在上下文中“安全”,最不容易出错)。

Alternatives that do pretty much the same thing:

替代品几乎完全相同:

bash < <(perl foo.pl)
bash <(perl foo.pl)

#2


`foobar.pl`

#3


Given the perl file:

鉴于perl文件:

print "date";

the following bash command will do it.

以下bash命令将执行此操作。

> $(perl qq.pl)
Mon Apr  6 11:02:07 WAST 2009

But that is run in a separate shell. If you really want to invoke it in the context of the current shell, do this:

但这是在一个单独的shell中运行的。如果您真的想在当前shell的上下文中调用它,请执行以下操作:

$ perl qq.pl >/tmp/qq.$$ ; . /tmp/qq.$$ ; rm -f /tmp/qq.$$
Mon Apr  6 11:04:59 WAST 2009

#4


Try:

foobar.pl | bash

#5


I don't think this is exactly what you're looking for, but its what I've got :-)

我不认为这正是你正在寻找的,但它是我得到的:-)

perl foo.pl > /tmp/$$.script; bash /tmp/$$.script; rm /tmp/$$.script

Good luck!

#6


Try with open($fh,"-|",$arg1,$arg2)

尝试打开($ fh,“ - |”,$ arg1,$ arg2)

#1


Bad:

`perl foo.pl`
$(perl foo.pl)

Why is this bad? Because of so many reasons; most notably:

为什么这么糟糕?由于这么多原因;最为显着地:

  • Wordsplitting: What you're doing here is taking the output of the perl script, splitting it into chunks wherever there are spaces, tabs or newlines, and taking those chunks as arguments to the first chunk which is the command to run. In really extremely simplistic cases like $(echo 'date +%s') it might work; but that's just a really bad representation of what you're REALLY doing here.
  • Wordsplitting:你在这里做的是获取perl脚本的输出,将其分成块,只要有空格,制表符或换行符,并将这些块作为参数传递给第一个块,即运行命令。在非常简单的情况下,例如$(echo'date +%s')它可能会起作用;但这只是你真正在这里做的非常糟糕的表现。

  • You cannot do quoting or use any other bash shell features like parameter expansion, bash keywords, etc.
  • 您不能引用或使用任何其他bash shell功能,如参数扩展,bash关键字等。

Good, but inconvenient:

好,但不方便:

perl foo.pl > mytmpfile; bash mytmpfile

Creating a temporary file to put your perl script's output into and then running that with bash works, but it's inconvenient as you need to create (and clean up!) your temporary file and have it in a portably writable (and secure!) location.

创建一个临时文件来将你的perl脚本的输出放入然后用bash运行,但是这很不方便,因为你需要创建(并清理!)你的临时文件并将它放在一个可移植的可写(和安全!)位置。

Also remember not to use . or source to execute the temporary file unless you really intend to run it all in the active shell. Moreover, when you use . or source, you won't be able to reliably clean up your temporary file afterward.

还记得不要用。或者来源执行临时文件,除非你真的打算在活动shell中运行它。而且,当你使用。或来源,您将无法可靠地清理您的临时文件。

Probably the best solution:

可能是最好的解决方案:

perl foo.pl | bash

This is pretty safe all-round ("safe" in the context of, least bug-prone) assuming your perl script outputs correct bash syntax, of course.

假设你的perl脚本输出正确的bash语法,这是全面安全的(在上下文中“安全”,最不容易出错)。

Alternatives that do pretty much the same thing:

替代品几乎完全相同:

bash < <(perl foo.pl)
bash <(perl foo.pl)

#2


`foobar.pl`

#3


Given the perl file:

鉴于perl文件:

print "date";

the following bash command will do it.

以下bash命令将执行此操作。

> $(perl qq.pl)
Mon Apr  6 11:02:07 WAST 2009

But that is run in a separate shell. If you really want to invoke it in the context of the current shell, do this:

但这是在一个单独的shell中运行的。如果您真的想在当前shell的上下文中调用它,请执行以下操作:

$ perl qq.pl >/tmp/qq.$$ ; . /tmp/qq.$$ ; rm -f /tmp/qq.$$
Mon Apr  6 11:04:59 WAST 2009

#4


Try:

foobar.pl | bash

#5


I don't think this is exactly what you're looking for, but its what I've got :-)

我不认为这正是你正在寻找的,但它是我得到的:-)

perl foo.pl > /tmp/$$.script; bash /tmp/$$.script; rm /tmp/$$.script

Good luck!

#6


Try with open($fh,"-|",$arg1,$arg2)

尝试打开($ fh,“ - |”,$ arg1,$ arg2)