我正在尝试从我的 Perl 程序中运行 Bash 命令。 然而,Perl 似乎将我的 Bash $PWD 环境变量混淆为 Perl 变量。
我怎样才能让它只作为一个字符串读取呢?
这就是我想要运行的
my $path = /first/path;
`ln -s $path $PWD/second/path`
那些反引号在 Bash 中位于第二行。使用 System() 会产生同样的问题。
有什么想法吗?
最佳答案
这里有两个查询,关于 Bash 变量的使用和运行外部命令。
有 %ENV
hash在 Perl 中,带有环境变量
perl -wE'say $ENV{PWD}'
但是,您通常最好在脚本中获得等效项,因为脚本的含义可能略有不同,或者随着脚本的运行而发生变化。
更重要的是,使用 shell 命令会使您面临各种潜在的引用、shell 注入(inject)和解释问题。例如,您显示的命令是危险的,如 Charles Duffy 中所述。评论。原则上最好使用 Perl 的丰富功能。参见示例
清醒而详细地说明优势。
如果您确实需要运行外部命令,最好完全避免使用 shell,例如使用 system 的多参数形式.如果您还需要命令的输出,Perl 中有各种模块可以提供。请参阅下面的链接。
如果您还需要使用 shell 的功能,而不是正确地引用所有内容以便 shell 接收它需要的东西,最好使用像 String::ShellQuote 这样的现成工具。 .
一些例子:
How to use both pipes and prevent shell expansion in perl system function?
Perl is respecting '<' as a regular character rather an output redirection
How to pipe the content of a variable as STDIN in a qx{} statement in Perl?
Perl system command with multiple parameters output to file .
请注意 qx operator (反引号)使用 /bin/sh
,它可能会也可能不会降级为 Bash。因此,如果你想要 Bash,你需要 system('/bin/bash', '-c', $cmd)
,其中 $cmd
需要小心构建以避免出现问题。请参阅带有示例的链接。
这是与问题背后的目标相关的完整示例。
您的程序的工作目录可能与预期不同,具体取决于它的启动方式。一方面,它在 chdir
之后发生变化。我不知道你使用 PWD
的确切意图,但在 Perl 中有核心 Cwd::cwd
和 FindBin使用 $RealBin
,用于当前工作目录和脚本所在的目录(通常不同)。
创建指向$path
的符号链接(symbolic link),相对路径位于当前工作目录之后
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
。
关于linux - 在 Perl 脚本中使用 Bash 环境变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44185663/