2017-05-25 139 views
2

我想从我的Perl程序中运行Bash命令。 然而,Perl似乎将我的Bash $ PWD环境变量作为Perl变量混淆了。在Perl脚本中使用Bash环境变量?

我怎样才能让它只读为一个字符串?

这就是我试图运行

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

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

任何想法?

+2

'PWD' *是由bash(和其他shell如'zsh')导出的*;使用'/ usr/bin/printenv'来验证;这是一个*魔术*环境变量 –

+0

@BasileStarynkevitch,我站在纠正。 –

+2

使用'\ $'来转义'$' – Arkadiy

回答

5

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

有在Perl %ENV hash,环境变量

perl -wE'say $ENV{PWD}' 

但是,你通常能够更好地获取脚本中的等价物,因为事情可能对脚本或变化作为一个微妙的不同含义脚本运行。

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

为清醒,细致,帐户的优点。


在你需要运行外部命令的情况下,最好是通过使用system多参数形式,以避免壳完全,例如。如果你需要命令的输出,Perl中有各种模块可以提供。请参阅以下链接。

如果您还需要使用shell的功能,而不是引用所有内容,以便shell能够更好地使用现成的工具,如String::ShellQuote

一些例子:

注意qx operator(反引号)使用/bin/sh,这可能会或可能不会降级猛砸。所以如果你想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

+0

@RyanSaffer我大大地更新了这篇文章,并给出了具体的答案。 – zdim

+0

逾期的回复,但这帮了我很多!谢谢!! –

+0

@RyanSaffer很棒:)请让我知道如果有更多的解释将是有用的。 – zdim