【问题标题】:Passing value passing to multiple commands in xargs将值传递给 xargs 中的多个命令
【发布时间】:2019-03-22 14:47:09
【问题描述】:

我正在尝试在 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": []
}

【问题讨论】:

    标签: aws-cli xargs


    【解决方案1】:

    TL;DR 在 Mac 上 xargs 参数在替换完成后不能超过 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 --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 id 传递给带有--instance-ids 开关的describe-instances 命令,它按预期工作,因为参数扩展低于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=%; '
    

    【讨论】:

    • 太棒了!谢谢@kenlukas 的详细解释。
    猜你喜欢
    • 2016-03-06
    • 2018-02-28
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多