AWS CLI命令在Bash上有效,但不适用于PHP shell_exec()

问题描述:

我想触发以下命令:

aws route53 change-resource-record-sets --hosted-zone-id XXX
 --change-batch '{ "Comment": "2018-06-19-11:31", "Changes":
[ { "Action": "CREATE", "ResourceRecordSet": { "Name": "example.com",
"Type": "TXT", "TTL": 60, "ResourceRecords":
[ { "Value": "\"something\"" } ] } } ] }'

当我在bash上触发它时,它起作用,但是当我在PHP中运行它时,它不起作用:

It works when I trigger it on bash, but not when I run it in PHP:

$json = trim(shell_exec($cmd_aws_submit));
// or:
$json = trim(shell_exec("{$cmd_aws_submit}"));

AWS希望对TXT记录的值("\"something\"")进行引用.我试图这样引用它:

AWS expects, that the value ("\"something\"") for the TXT record is quoted. I tried to quote it like this:

$value = "\\\"" . $textvalue . "\\\"";
$value = "\"" . $textvalue . "\"";
$value = "\\'" . $textvalue . "\\'";
$value = "'" . $textvalue . "'";

所有方法均无效,我总是收到以下错误消息:

None of it works, I always get the following error:

解析参数'--change-batch'时出错:无效的JSON: 无效的\ escape:第12行第23列(字符246)收到了JSON: {"Comment":"2018-06-19-11:54","Changes":[{"Action": "CREATE","ResourceRecordSet":{"Name":"example.com", 类型":"TXT","TTL":60,"ResourceRecords": [{"Value":"\" something \"}]}}]}

Error parsing parameter '--change-batch': Invalid JSON: Invalid \escape: line 12 column 23 (char 246) JSON received: { "Comment": "2018-06-19-11:54", "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "example.com", "Type": "TXT", "TTL": 60, "ResourceRecords": [ { "Value": "\"something\"" } ] } } ] }

与其他aws UNQUOTED dns记录值一样,PHP shell_exec()完美运行.

With other aws UNQUOTED dns record values, PHP shell_exec() works perfectly.

如果我在Bash上触发它,则可以使用"\"something\""完美地工作-为什么它不能与PHP shell_exec()一起使用?

If I trigger it on Bash, it works perfectly using "\"something\"" - why is it not working with PHP shell_exec()?

您应该使用本机escapeshellarg方法来转义传递给命令行的参数.如果您决定在某个阶段在JSON字符串中包含潜在的不安全数据,这也将保护您免受参数注入攻击.

You should use the native escapeshellarg method to escape arguments you pass through to the command line. This will also protect you against argument injection attacks if you decide to include potentially unsafe data in your JSON string at some stage.

$json = '{ "Comment": "2018-06-19-11:31", "Changes":
[ { "Action": "CREATE", "ResourceRecordSet": { "Name": "example.com",
"Type": "TXT", "TTL": 60, "ResourceRecords":
[ { "Value": "\"something\"" } ] } } ] }';

$command = "aws route53 change-resource-record-sets --hosted-zone-id XXX
 --change-batch " . escapeshellarg($json);

$result = trim(shell_exec($command));

您还可以选择将JSON字符串构建为数组,然后使用json_encode()为您构建字符串.

You could also choose to build up the JSON string as an array then use json_encode() to construct your string for you.