在 Perl 脚本中使用 Bash 环境变量?

Using Bash environment variables from within a Perl script?

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

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

这就是我想要的 运行

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

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

有什么想法吗?

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

Perl中有%ENV hash,有环境变量

perl -wE'say $ENV{PWD}'

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

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

冷静、详细地说明优点。


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

如果您还需要使用 shell 的功能,而不是为了让 shell 收到它需要的东西而引用所有内容,最好使用像 [=27 这样的现成工具=].

一些示例:

  • How to use both pipes and prevent shell expansion in perl system function?

  • Perl is respecting '<' as a regular character rather an output redirection

请注意 qx operator(反引号)使用 /bin/sh,它可能会也可能不会降级为 Bash。因此,如果您想要 Bash,则需要 system('/bin/bash', '-c', @cmd)。请参阅 link 示例。


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

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

创建符号 link 到 $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: $!";

如果路径是脚本的位置,请使用 FindBin 中的 $RealBin 而不是 cwd

请注意 symlink you cannot pass a directory instead of a link name. See this page.