3

我正在尝试从我的 Perl 程序中运行 Bash 命令。然而,Perl 似乎将我的 Bash $PWD 环境变量混淆为 Perl 变量。

我怎样才能让它把它全部读成一个字符串?

这就是我想要运行的

my $path = /first/path;
`ln -s $path $PWD/second/path`

这些反引号在 Bash 中运行第二行。使用 System() 会产生同样的问题。

有任何想法吗?

4

1 回答 1

6

这里有两个查询,关于使用 Bash 变量和关于运行外部命令。

Perl中有%ENV散列,带有环境变量

perl -wE'say $ENV{PWD}'

但是,您通常最好在脚本中获取等效项,因为脚本的含义可能略有不同,或者随着脚本的运行而变化。

更重要的是,使用 shell 命令会使您面临各种与引用、shell 注入和解释有关的潜在问题。例如,您显示的命令很危险,如Charles Duffy评论中所述。原则上最好使用 Perl 的丰富功能。参见例如

对优势进行清醒而详细的说明。


如果您确实需要运行外部命令,最好完全避免使用 shell,例如使用system的多参数形式。如果您还需要命令的输出,那么 Perl 中有各种模块可以提供该输出。请参阅下面的链接。

如果您还需要使用 shell 的功能,而不是引用所有内容以使 shell 更好地接收它需要的内容,请使用像String::ShellQuote这样的现成工具。

一些例子:

请注意,qx 运算符(反引号)使用/bin/sh,它可能会或可能不会降级到 Bash。因此,如果您想要 Bash,您将需要system('/bin/bash', '-c', @cmd). 请参阅示例链接。


这是与问题背后的目标相关的完整示例。

您的程序的工作目录可能与预期不同,具体取决于它的启动方式。一方面,它在 之后发生变化chdir。我不知道你的确切意图PWD,但在 Perl 中有核心 Cwd ::cwdFindBin$RealBin用于当前工作目录和脚本所在的目录(通常不同的东西)。

要创建指向 的符号链接$path,其相对路径位于当前工作目录之后

use warnings;
use strict;
use Cwd qw(cwd);

my $cwd = cwd;

my $path = '/first/path';

symlink($path, "$cwd/second/path") or die "Can't make a symlink: $!";

如果路径是脚本的位置,请使用$RealBinfromFindBin而不是cwd.

请注意,使用符号链接您不能传递目录而不是链接名称。请参阅此页面

于 2017-05-25T16:48:39.883 回答