将值传递给xargs中的多个命令

时间:2018-10-17 20:25:40

标签: aws-cli xargs

我试图在xargs中执行多个命令。我在这里看到的问题是管道值'%'仅传递给xargs中的第一个子命令,而不传递给第二个。通过交换命令位置来验证相同,并且始终总是第二个命令从不获取'%'的必需值

Command-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: %

Command-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": []
}

1 个答案:

答案 0 :(得分:4)

在Mac xargs上,

TL; DR 替换完成后,参数不能超过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 man page

 -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-开始时间2018-01-01T00:00:00Z-结束时间2018-02-28T23:59:59Z-期间2592000- -namespace AWS / EC2 --statistics最大-维度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 id开关将describe-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=%; '