Передача значения в несколько команд в xargs - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь выполнить несколько команд внутри xargs.Проблема, которую я вижу здесь, заключается в том, что переданное по каналу значение «%» передается только 1-й подкоманде внутри xargs, но не 2-й.Проверяется то же самое путем взаимного изменения положения команд, и всегда 2-я команда никогда не получает требуемого значения для «%»

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

Команда-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 голосов
/ 18 октября 2018

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 :

 -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-время 2018-02-28T23: 59: 59Z --период 2592000 - пространство имен AWS / EC2 --статистика Максимум --размеры Имя = InstanceId, значение =%;экземпляр эха:%; '

равен 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;'

Это правильно передаст слово «бла» каждому эхо-выражению.

бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла

Добавьте еще один 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=%; '
...