当前位置:  开发笔记 > 编程语言 > 正文

我应该在Perl中转义shell参数吗?

如何解决《我应该在Perl中转义shell参数吗?》经验,为你挑选了2个好方法。

在Perl中使用system()调用时,是否必须转义shell args,还是自动完成?

参数将是用户输入,因此我想确保这不可利用.



1> runrig..:

如果您使用system $cmd, @args而不是system "$cmd @args"(数组而不是字符串),那么您不必转义参数,因为没有调用shell(请参阅系统). system {$cmd} $cmd, @args即使$ cmd包含元字符并且@args为空(这也记录为exec的一部分),也不会调用shell .如果args来自用户输入(或其他不受信任的来源),您仍然需要解开它们.见-T在perlrun文档和perlsec文档.

如果需要读取输出或向命令发送输入,qx并且readpipe没有等效项.相反,使用open my $output, "-|", $cmd, @argsopen my $input, "|-", $cmd, @args虽然这是不可移植的,因为它需要一个真正的fork,这意味着只有...我想.也许它可以在Windows上使用它的模拟分支.一个更好的选择就像IPC :: Run,它也可以处理管道命令到其他命令的情况,系统的多arg形式和open的4 arg形式都不会处理.


我从来没有注意到他们添加了那种语法的+1.可爱.

2> j_random_hac..:

在Windows上,情况有点糟糕.基本上,所有的Win32程序收到一个长命令行字符串-壳(通常cmd.exe)可以首先做一些解释,消除<>例如重定向,但它并没有在该程序字边界分裂它.每个程序都必须自己进行解析(如果他们愿意 - 有些程序不会打扰).在C和C++程序中,由编译器工具链提供的运行时库提供的例程通常在main()调用之前执行此解析步骤.

问题是,通常,您不知道给定程序将如何解析其命令行.许多程序都是使用某些版本的MSVC++编译的,其中描述了古怪的解析规则,但许多其他程序使用不同的编译器编译,这些编译器使用不同的约定.

cmd.exe具有其自身古怪的解析规则的事实加剧了这一点.caret(^)被视为引用以下字符的转义字符,如果满足棘手条件列表,则双引号内的文本将被视为引用(cmd /?有关完整的详细信息,请参阅参考资料).如果你的命令包含任何奇怪的字符,那么很容易cmd.exe知道哪些部分的文字被"引用",哪些不会与你的目标程序不同步,而且所有的地狱都会破裂.

因此,在Windows上转义参数的最安全方法是:

    以您正在调用的程序的命令行解析逻辑所期望的方式转义参数.(希望你知道那个逻辑是什么;如果没有,试试几个例子并猜测.)

    使用空格加入转义参数.

    使用生成字符串的每个非字母数字字符前缀^.

    附加任何重定向或其他shell欺骗(例如,加入命令&&).

    使用system()或反引号运行命令.

推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有