【问题标题】:Using Bash environment variables from within a Perl script?在 Perl 脚本中使用 Bash 环境变量?
【发布时间】:2017-10-26 09:48:09
【问题描述】:

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

我怎样才能让它全部作为字符串读取?

这就是我要运行的内容

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

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

有什么想法吗?

【问题讨论】:

  • PWD 被 bash 导出(以及其他 shell,如 zsh);使用/usr/bin/printenv 来验证;这是一个magic环境变量
  • @BasileStarynkevitch,我的立场是正确的。
  • 使用\$转义$
  • @RyanSaffer, ...btw,一般来说,这种代码是非常危险的。使用本机 Perl 操作比使用 system() 或任何等效操作要好得多 - 如果您的路径可以包含 $(rm -rf ~)(是的,可以使用该字符串创建一个实际的文件或目录它的名字),你不希望它在没有被引用或首先被转义的情况下被传递给 shell(如果它是 $(rm -rf ~)'$(rm -rf ~)' 作为名称中的字符串文字,这将有助于转义它的引用并造成严重破坏,即使您试图通过在周围注入文字单引号来使其安全)。
  • 我确定这个问题是重复的,但是选择的重复问题是一个糟糕的选择。

标签: linux bash perl pwd


【解决方案1】:

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

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

perl -wE'say $ENV{PWD}'

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

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

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


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

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

一些例子:

请注意,qx operator(反引号)使用 /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: $!";

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

请注意,symlink 不能传递目录而不是链接名称。见this page

【讨论】:

  • @RyanSaffer 我大幅更新了帖子,并给出了具体答案。
  • 逾期回复,但这对我帮助很大!!谢谢!!
  • @RyanSaffer Great :) 请让我知道是否有更多解释有用。
猜你喜欢
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
相关资源
最近更新 更多