首页 > 解决方案 > 将值传递给 xargs 中的多个命令

问题描述

我正在尝试在 xargs 中执行多个命令。我在这里看到的问题是管道值 '%' 仅传递给 xargs 内的第一个子命令,而不是第二个子命令。通过交换命令位置来验证相同,并且仍然总是第二个命令永远不会获得 '%' 所需的值

命令-1

aws ec2 describe-instances --query 'Reservations[].Instances[?(LaunchTime>=`2015-01-01` && LaunchTime<=`2015-02-28`)][].{id: InstanceId, launched: LaunchTime}' | jq --raw-output '.[] | .id' | xargs -n 1 -I % sh -c 'aws cloudwatch get-metric-statistics --metric-name NetworkPacketsIn --start-time 2018-01-01T00:00:00Z --end-time 2018-02-28T23:59:59Z --period 2592000 --namespace AWS/EC2 --statistics Maximum --dimensions Name=InstanceId,Value=%; echo instance: %;'

输出:

{
    "Label": "NetworkPacketsIn",
    "Datapoints": []
}
instance: %
{
    "Label": "NetworkPacketsIn",
    "Datapoints": []
}
instance: %

命令 2

aws ec2 describe-instances --query 'Reservations[].Instances[?(LaunchTime>=`2015-01-01` && LaunchTime<=`2015-02-28`)][].{id: InstanceId, launched: LaunchTime}' | jq --raw-output '.[] | .id' | xargs -n 1 -I % sh -c 'echo instance: %; aws cloudwatch get-metric-statistics --metric-name NetworkPacketsIn --start-time 2018-01-01T00:00:00Z --end-time 2018-02-28T23:59:59Z --period 86400 --namespace AWS/EC2 --statistics Maximum --dimensions Name=InstanceId,Value=%;'

输出

instance: i-3e4fab33
{
    "Label": "NetworkPacketsIn",
    "Datapoints": []
}
instance: i-c2abbac8
{
    "Label": "NetworkPacketsIn",
    "Datapoints": []
}

标签: aws-clixargs

解决方案


TL; Mac 上的DRxargs参数在替换完成后不能超过 255 个字节。

缩短您的参数并将分号从最后一个命令中删除修复了错误:

aws ec2 describe-instances --query 'Reservations[].Instances[?(LaunchTime>=`2015-01-01` && LaunchTime<=`2015-02-28`)][].{id: InstanceId, launched: LaunchTime}' | jq --raw-output '.[] | .id' | xargs -I % sh -c 'aws cloudwatch get-metric-statistics --metric-name NetworkPacketsIn --start-time 2018-01-01T00:00:00Z --end-time 2018-02-28T23:59:59Z --period 86400 --namespace AWS/EC2 --statistics Maximum --dimensions Name=InstanceId,Value=%;echo id=%'

这是更长的答案以及一些证明它的测试。

xargs 手册页

 -I replstr
         Execute utility for each input line, replacing one or more occurrences of replstr in up to replacements (or
         5 if no -R flag is specified) arguments to utility with the entire line of input.  The resulting arguments,
         after replacement is done, will not be allowed to grow beyond 255 bytes; this is implemented by concatenat-
         ing as much of the argument containing replstr as possible, to the constructed arguments to utility, up to
         255 bytes.  The 255 byte limit does not apply to arguments to utility which do not contain replstr, and fur-
         thermore, no replacement will be done on utility itself.  Implies -x.

OP 传递给的参数xargs

'aws cloudwatch get-metric-statistics --metric-name NetworkPacketsIn --start-time 2018-01-01T00:00:00Z --end-time 2018-02-28T23:59:59Z --period 2592000 --namespace AWS /EC2 --statistics 最大值 --dimensions Name=InstanceId,Value=%; 回声实例:%;'

是 250 字节。当%被 替换时,AMI ID它会超过 255 字节限制并爆炸。

如果您想自己测试,请尝试以下操作,参数有 254 个字节:

echo blah |xargs -I % sh -c 'export blah=%; echo $blah; echo $blah; echo $blah;\
echo $blah; echo $blah; echo $blah;echo $blah; echo $blah; echo $blah;echo $blah;\
echo $blah; echo $blah;echo $blah; echo $blah; echo $blah;echo $blah; echo $blah;\
echo $blah;echo $blah;echo $blah;'

这将正确地将单词 blah 传递给每个 echo 语句。

哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈

在末尾再添加一个echo $blah;,使字节总数达到 265 个字节,然后它就爆炸了:

% % % % % % % % % % % % % % % % % % %

为了使长篇文章更长,我将 传递instance iddescribe-instances带有--instance-ids开关的命令,它按预期工作,因为参数扩展低于 255 限制。

aws ec2 describe-instances --query 'Reservations[].Instances[?(LaunchTime>=`2015-01-01` && LaunchTime<=`2015-02-28`)][].{id: InstanceId, launched: LaunchTime}' | jq --raw-output '.[] | .id' | xargs  -I % sh -c 'echo instance: %; aws ec2 describe-instances --instance-ids=%; '

推荐阅读