Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用引号转义php exec()命令_Php_Escaping_Exec_Exiv2 - Fatal编程技术网

如何用引号转义php exec()命令

如何用引号转义php exec()命令,php,escaping,exec,exiv2,Php,Escaping,Exec,Exiv2,我在Linux上使用Exiv2命令行工具编辑图像元数据,如下所示: exiv2 -M"set Iptc.Application2.Caption String This is my caption....." modify IMG.jpg 我希望使用用户提供的标题从PHP执行此操作。如果用户未输入特殊字符,则此操作有效: exec('/usr/local/bin/exiv2 -M"set Iptc.Application2.Caption String '.$caption.'" modify

我在Linux上使用Exiv2命令行工具编辑图像元数据,如下所示:

exiv2 -M"set Iptc.Application2.Caption String This is my caption....." modify IMG.jpg
我希望使用用户提供的标题从PHP执行此操作。如果用户未输入特殊字符,则此操作有效:

exec('/usr/local/bin/exiv2 -M"set Iptc.Application2.Caption String '.$caption.'" modify IMG.jpg');

我需要允许用户使用特殊字符,如单引号和双引号。我想使用escapeshellcmd()来防止恶意数据。如何正确地转义命令和参数,使其工作?我已经尝试了很多选项,但都做不好。

是的,这是一个很难解决的问题,因为命令使用了非标准的shell参数(比如它自己的小元语言)。ImageMagick也有同样的问题

如果只在双引号字符串中使用escapeshellarg(),则它将变得无用。escapeshellcmd()不会转义所有特殊字符,并且在双引号字符串中使用是安全的。因此,您需要围绕它硬编码单引号,以使其正常工作

exec('/usr/local/bin/exiv2 -M"set Iptc.Application2.Caption String \'' . escapeshellcmd($caption) . '\'" modify IMG.jpg');

escapeshellarg()在单引号字符串中不起作用的原因是:

# for this input:
The smith's "; rm -rf *; echo "went to town

# after escapeshellarg()
'The smith\'s "; rm -rf *; echo "went to town'

# Works fine if left as a top-level argument
/usr/bin/command 'The smith\'s "; rm -rf *; echo "went to town'

# BUT if put in a double-quoted string:
/usr/bin/command "subcommand1 'The smith\'s "; rm -rf *; echo "went to town'"

# it is broken into 3 shell commands:
/usr/bin/command "something and 'The smith\'s ";
rm -rf *;
echo "went to town'"

# bad day...

使用heredoc怎么样

$str = <<<'EOD'
/usr/local/bin/exiv2 -M "set Iptc.Application2.Caption String $options" modify IMG.jpg
EOD;
exec($str);

$str=由于Exiv2的非标准shell参数,要找到一个简单而健壮的解决方案来正确处理用户提供的报价并不容易。还有另一种解决方案,它可能更可靠,更易于维护,而且性能损失很小

将Exiv2指令写入文件
cmds.txt
,然后调用:

exiv2 -m cmds.txt IMG.jpg
从文件中读取说明


更新:我已经实现了这个方法,它不需要转义用户提供的数据。该数据直接写入Exiv2读入的文本文件。Exiv2命令文件格式非常简单,以换行符结尾,不允许在值内转义,因此我需要做的就是阻止换行符通过,这是我无论如何都不允许的。

谢谢,这对理解问题非常有帮助。看起来exiv2是通过允许exiv2命令(设计为写入文件)也作为shell参数作为快捷方式写入的,从而获得了它的非标准shell参数。哦,我尝试了这个方法,但它没有保留用户输入的双引号。不过单引号值得称赞,在我的输入中更常见!
exiv2 -m cmds.txt IMG.jpg