Wak*_*nka -1 shell perl system pipe variable-expansion
如果将多个参数传递给perl的系统函数,则shell扩展将不起作用:
# COMMAND
$ perl -e 'my $s="*"; system("echo", "$s" )'
# RESULT
*
Run Code Online (Sandbox Code Playgroud)
如果命令作为一个参数传递,那么扩展将起作用:
# COMMAND
$ perl -e 'my $s="echo *"; system("$s")'
# RESULT
Desktop Documents Downloads
Run Code Online (Sandbox Code Playgroud)
系统功能还允许使用多个命令并使用管道连接它们.这仅在参数作为一个命令传递时有效:
# COMMAND
$ perl -e 'my $s="echo * | cat -n"; system("$s")'
# RESULT
1 Desktop Documents Downloads
Run Code Online (Sandbox Code Playgroud)
如何组合提到的命令并使用两个管道并防止shell扩展?
我试过了:
# COMMAND
$ perl -e 'my $s="echo"; system("$s", "* | cat -n")'
# RESULT
* | cat -n
Run Code Online (Sandbox Code Playgroud)
但由于我上面描述的原因(多个参数未扩展),这不起作用.我想要的结果是:
1 *
Run Code Online (Sandbox Code Playgroud)
编辑:我实际面临的问题是当我使用以下命令时:
system("echo \"$email_message\" | mailx -s \"$email_subject\" $recipient");
Run Code Online (Sandbox Code Playgroud)
然后扩展$ email_message,如果它包含一些由shell进一步扩展的字符,它将破坏mailx.
system 有三个调用约定:
system($SHELL_CMD)
system($PROG, @ARGS) # @ARGS>0
system( { $PROG } $NAME, @ARGS ) # @ARGS>=0
Run Code Online (Sandbox Code Playgroud)
第一个命令传递给shell.它相当于
system('/bin/sh', '-c', $SHELL_CMD)
Run Code Online (Sandbox Code Playgroud)
另外两个执行程序$PROG.system永远不会阻止shell扩展或执行任何转义.根本没有涉及到shell.
所以你的问题是关于构建一个shell命令.如果您在提示符处,可以使用
echo \* | cat -n
Run Code Online (Sandbox Code Playgroud)
要么
echo '*' | cat -n
Run Code Online (Sandbox Code Playgroud)
通过*.*在插值之前,您需要一个执行转义工作的函数.幸运的是,一个已经存在:字符串:: ShellQuote的shell_quote.
$ perl -e'
use String::ShellQuote qw( shell_quote );
my $s = "*";
my $cmd1 = shell_quote("printf", q{%s\n}, $s);
my $cmd2 = "cat -n";
my $cmd = "$cmd1 | $cmd2";
print("Executing <<$cmd>>\n");
system($cmd);
'
Executing <<printf '%s\n' '*' | cat -n>>
1 *
Run Code Online (Sandbox Code Playgroud)
我使用printf而不是echo因为从-in 开始处理参数非常困难echo.大多数程序接受--将选项与非选项分开,但不接受我的选项echo.
所有这些并发症都提出了一个问题:你为什么要发送电子邮件?处理来自外部程序的错误通常比从库中处理错误要困难得多.
| 归档时间: |
|
| 查看次数: |
236 次 |
| 最近记录: |