Запросы к выходным данным команд Azure CLIQuery Azure CLI command output

Интерфейс Azure CLI использует аргумент --query для выполнения запроса JMESPath к результатам выполнения команд.The Azure CLI uses the --query argument to execute a JMESPath query on the results of commands. JMESPath — это язык запросов для JSON, который позволяет выбирать и изменять выходные данные команд CLI.JMESPath is a query language for JSON, giving you the ability to select and modify data from CLI output. Запросы выполняются к выходным данным в формате JSON до их форматирования для отображения.Queries are executed on the JSON output before any display formatting.

Аргумент --query поддерживается всеми командами в Azure CLI.The --query argument is supported by all commands in the Azure CLI. В этой статье описано использование возможностей JMESPath на основе ряда небольших простых примеров.This article covers how to use the features of JMESPath with a series of small, simple examples.

Результаты команд CLI в виде словарей и списковDictionary and list CLI results

Даже если используется формат выходных данных, отличный от JSON, при выполнении запросов результаты выполнения команд сначала обрабатываются как объекты JSON.Even when using an output format other than JSON, CLI command results are first treated as JSON for queries. Результаты выполнения команд CLI представляют собой массив или словарь JSON.CLI results are either a JSON array or dictionary. Массивы — это последовательности объектов, доступ к которым может осуществляться по индексу, а словари — это неупорядоченные объекты, доступ к которым осуществляется с помощью ключей.Arrays are sequences of objects that can be indexed, and dictionaries are unordered objects accessed with keys. Команды, которые могут возвращать несколько объектов, возвращают массив, а команды, которые всегда возвращают только один объект, возвращают его в виде словаря.Commands that could return more than one object return an array, and commands that always return only a single object return a dictionary.

Получение свойств из словаряGet properties in a dictionary

При работе с результатами в виде словаря вы всегда можете получить свойства верхнего уровня с помощью ключа.Working with dictionary results, you can access properties from the top level with just the key. Для доступа к свойствам вложенных словарей используется символ . (часть выражения).The . (subexpression) character is used to access properties of nested dictionaries. Прежде чем перейти к запросам, рассмотрим неизмененные выходные данные команды az vm show:Before introducing queries, take a look at the unmodified output of the az vm show command:

az vm show -g QueryDemo -n TestVM -o json

Результаты этой команда выводятся в виде словаря.The command will output a dictionary. Часть содержимого опущена.Some content has been omitted.

{
  "additionalCapabilities": null,
  "availabilitySet": null,
  "diagnosticsProfile": {
    "bootDiagnostics": {
      "enabled": true,
      "storageUri": "https://xxxxxx.blob.core.windows.net/"
    }
  },
  ...
  "osProfile": {
    "adminPassword": null,
    "adminUsername": "azureuser",
    "allowExtensionOperations": true,
    "computerName": "TestVM",
    "customData": null,
    "linuxConfiguration": {
      "disablePasswordAuthentication": true,
      "provisionVmAgent": true,
      "ssh": {
        "publicKeys": [
          {
            "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso",
            "path": "/home/azureuser/.ssh/authorized_keys"
          }
        ]
      }
    },
    "secrets": [],
    "windowsConfiguration": null
  },
  ....
}

Следующая команда предназначена для получения открытых ключей SSH, имеющих разрешение на подключение к виртуальной машине, с помощью запроса:The following command gets the SSH public keys authorized to connect to the VM by adding a query:

az vm show -g QueryDemo -n TestVM --query osProfile.linuxConfiguration.ssh.publicKeys -o json
[
  {
    "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso",
    "path": "/home/azureuser/.ssh/authorized_keys"
  }
]

Чтобы получить несколько свойств, заключите список выражений, разделенных запятыми, в квадратные скобки — [ ] (список из нескольких элементов).To get more than one property, put expressions in square brackets [ ] (a multiselect list) as a comma-separated list. Чтобы получить имя виртуальной машины, имя администратора и ключ SSH с помощью одной команды, введите ее в следующем виде:To get the VM name, admin user, and SSH key all at once use the command:

az vm show -g QueryDemo -n TestVM --query '[name, osProfile.adminUsername, osProfile.linuxConfiguration.ssh.publicKeys[0].keyData]' -o json
[
  "TestVM",
  "azureuser",
  "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso"
]

Эти значения включены в полученный массив в том порядке, в котором они были указаны в запросе.These values are listed in the result array in the order they were given in the query. Поскольку результат имеет формат массива, значения не имеют соответствующих ключей.Since the result is an array, there are no keys associated with the results.

Получение одного значенияGet a single value

Часто нужно, чтобы команда CLI должна вернуть только одно значение, например идентификатор ресурса Azure, имя ресурса, имя пользователя или пароль.A common case is that you need to only get one value out of a CLI command, such as an Azure resource ID, a resource name, a username, or a password. При этом значение должно быть сохранено в локальной переменной.In that case, you also often want to store the value in a local environment variable. Чтобы получить одно свойство, сначала убедитесь, что вам удалось извлечь только одно свойство из запроса.To get a single property, first make sure that you're only getting one property out of the query. В последнем примере показано, как получить только имя пользователя администратора:Modifying the last example to get only the admin username:

az vm show -g QueryDemo -n TestVM --query 'osProfile.adminUsername' -o json
"azureuser"

Оно выглядит как допустимое отдельное значение, но обратите внимание, что символы " возвращаются как часть выходных данных.This looks like a valid single value, but note that the " characters are returned as part of the output. Это означает, что объект представляет собой строку JSON.This indicates that the object is a JSON string. Важно отметить, что при назначении этого значения переменной среды непосредственно в качестве выходных данных команды, кавычки могут не интерпретироваться оболочкой:It's important to note that when you assign this value directly as output from the command to an environment variable, the quotes may not be interpreted by the shell:

USER=$(az vm show -g QueryDemo -n TestVM --query 'osProfile.adminUsername' -o json)
echo $USER
"azureuser"

Это явно не то, что нужно.This is almost certainly not what you want. В этом случае вам нужно использовать формат выходных данных с возвращаемыми значениями с информацией о типах без кавычек.In this case, you want to use an output format which doesn't enclose returned values with type information. Наилучший вариант, который предоставляет CLI для этой цели, — tsv или значение с разделением знаками табуляции.The best output option that the CLI offers for this purpose is tsv, tab-separated values. В частности, при извлечении отдельного значения (не словаря или списка) выходные данные tsv гарантированно не будут включать кавычки.In particular, when retrieving a value that's only a single value (not a dictionary or list), tsv output is guaranteed to be unquoted.

az vm show -g QueryDemo -n TestVM --query 'osProfile.adminUsername' -o tsv
azureuser

См. подробнее о формате выходных данных tsv.For more information about the tsv output format, see Output formats - TSV output format

Переименование свойств в запросеRename properties in a query

Чтобы при запросе нескольких значений получить словарь вместо массива, используйте оператор { } (хэш-таблица из нескольких элементов).To get a dictionary instead of an array when querying for multiple values, use the { } (multiselect hash) operator. Формат запроса для получения хэш-таблицы имеет вид {displayName:JMESPathExpression, ...}.The format for a multiselect hash is {displayName:JMESPathExpression, ...}. displayName — это строка, отображаемая в выходных данных, а JMESPathExpression — вычисляемое выражение JMESPath.displayName will be the string shown in output, and JMESPathExpression is the JMESPath expression to evaluate. Изменим пример из предыдущего раздела, чтобы заменить список элементов хэш-таблицей:Modifying the example from the last section by changing the multiselect list to a hash:

az vm show -g QueryDemo -n TestVM --query '{VMName:name, admin:osProfile.adminUsername, sshKey:osProfile.linuxConfiguration.ssh.publicKeys[0].keyData }' -o json
{
  "VMName": "TestVM",
  "admin": "azureuser",
  "ssh-key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso"
}

Получение свойств из массиваGet properties in an array

Массив не имеет свойств как таковых, но доступ к нему может осуществляться по индексу.An array has no properties of its own, but it can be indexed. Эта возможность показана в предыдущем примере, когда выражение publicKeys[0] использовалось для получения элемента с индексом publicKeys из массива.This feature is shown in the last example with the expression publicKeys[0], which gets the first element of the publicKeys array. Порядок выходных данных в командах CLI не гарантирован. Поэтому используйте индексы, только если вы уверены в порядке выходных данных или вам все равно, какой элемент вы получите.There's no guarantee CLI output is ordered, so avoid using indexing unless you're sure of the order or don't care what element you get. Чтобы получить доступ к элементам массива, используется одна из двух операций: преобразование в плоскую структуру или фильтрация.To access the properties of elements in an array, you do one of two operations: flattening and filtering. В этом разделе описано преобразование массива в плоскую структуру.This section covers how to flatten an array.

Преобразование массива в плоскую структуру выполняется с помощью оператора JMESPath [].Flattening an array is done with the [] JMESPath operator. Все выражения после оператора [] применяются к каждому элементу в текущем массиве.All expressions after the [] operator are applied to each element in the current array. Если оператор [] стоит в начале запроса, он преобразовывает в плоскую структуру результат выполнения команды CLI.If [] appears at the start of the query, it flattens the CLI command result. Эта возможность позволяет изучить результат выполнения команды az vm list.The results of az vm list can be inspected with this feature. Чтобы получить имя, сведения об операционной системе и имя администратора для каждой виртуальной машины в группе ресурсов, выполните следующую команду:To get the name, OS, and administrator name for each VM in a resource group:

az vm list -g QueryDemo --query '[].{Name:name, OS:storageProfile.osDisk.osType, admin:osProfile.adminUsername}' -o json
[
  {
    "Name": "Test-2",
    "OS": "Linux",
    "admin": "sttramer"
  },
  {
    "Name": "TestVM",
    "OS": "Linux",
    "admin": "azureuser"
  },
  {
    "Name": "WinTest",
    "OS": "Windows",
    "admin": "winadmin"
  }
]

При использовании формата выходных данных --output table имена столбцов соответствуют значению displayKey в хэш-таблице:When combined with the --output table output format, the column names match up with the displayKey value of the multiselect hash:

az vm list -g QueryDemo --query '[].{Name:name, OS:storageProfile.osDisk.osType, Admin:osProfile.adminUsername}' --output table
Name     OS       Admin
-------  -------  ---------
Test-2   Linux    sttramer
TestVM   Linux    azureuser
WinTest  Windows  winadmin

Примечание

Некоторые ключи отфильтровываются и не печатаются в табличном представлении.Certain keys are filtered out and not printed in the table view. Эти ключи — id, type и etag.These keys are id, type, and etag. Чтобы отобразить эти значения, можно изменить имя ключа в хэш-таблице.To see these values, you can change the key name in a multiselect hash.

az vm show -g QueryDemo -n TestVM --query "{objectID:id}" -o table

Преобразовать в плоскую структуру можно любой массив, а не только массив верхнего уровня, возвращаемый командой.Any array can be flattened, not just the top-level result returned by the command. В предыдущем разделе с помощью выражения osProfile.linuxConfiguration.ssh.publicKeys[0].keyData мы получили открытый ключ SSH, используемый для входа.In the last section, the expression osProfile.linuxConfiguration.ssh.publicKeys[0].keyData was used to get the SSH public key for sign-in. Чтобы получить все открытые ключи SSH, выражение можно записать в следующем виде: osProfile.linuxConfiguration.ssh.publicKeys[].keyData.To get every SSH public key, the expression could instead be written as osProfile.linuxConfiguration.ssh.publicKeys[].keyData. Этот запрос преобразовывает массив osProfile.linuxConfiguration.ssh.publicKeys в плоскую структуру, а затем применяет выражение keyData к каждому элементу:This query expression flattens the osProfile.linuxConfiguration.ssh.publicKeys array, and then runs the keyData expression on each element:

az vm show -g QueryDemo -n TestVM --query '{VMName:name, admin:osProfile.adminUsername, sshKeys:osProfile.linuxConfiguration.ssh.publicKeys[].keyData }' -o json
{
  "VMName": "TestVM",
  "admin": "azureuser",
  "sshKeys": [
    "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso\n"
  ]
}

Фильтрация массивовFilter arrays

Еще одной операцией, используемой для получения данных из массива, является фильтрация.The other operation used to get data from an array is filtering. Фильтрация выполняется с помощью оператора JMESPath [?...].Filtering is done with the [?...] JMESPath operator. В этом операторе используется предикат.This operator takes a predicate as its contents. Предикат — это любое выражение, результат которого равен true или false.A predicate is any statement that can be evaluated to either true or false. Выражения, предикат которых возвращает true, включаются в выходные данные.Expressions where the predicate evaluates to true are included in the output.

JMESPath поддерживает стандартные операторы сравнения и логические операторы.JMESPath offers the standard comparison and logical operators. Это операторы <, <=, >, >=, == и !=.These include <, <=, >, >=, ==, and !=. JMESPath также поддерживает логические операторы "И" (&&), "ИЛИ" (||) и "НЕ" (!).JMESPath also supports logical and (&&), or (||), and not (!). Выражения можно объединять в группы с помощью круглых скобок. Это позволяет использовать более сложные выражения в качестве предикатов.Expressions can be grouped within parenthesis, allowing for more complex predicate expressions. Подробные сведения о предикатах и логических операциях см. в спецификации JMESPath.For the full details on predicates and logical operations, see the JMESPath specification.

В последнем примере мы преобразовали массив в плоскую структуру, чтобы получить список всех виртуальных машин в группе ресурсов.In the last section, we flattened an array to get the complete list of all VMs in a resource group. С помощью фильтров в эти выходные данные можно включить только виртуальные машины с ОС Linux:Using filters, this output can be restricted to only Linux VMs:

az vm list -g QueryDemo --query "[?storageProfile.osDisk.osType=='Linux'].{Name:name,  admin:osProfile.adminUsername}" --output table
Name    Admin
------  ---------
Test-2  sttramer
TestVM  azureuser

Важно!

В JMESPath строки всегда заключаются в одиночные кавычки (').In JMESPath, strings are always surrounded by single quotes ('). Если в строке, стоящей в предикате фильтра, используются двойные кавычки, команда вернет пустой результат.If you use double quotes as part of a string in a filter predicate, you'll get empty output.

В JMESPath также встроены функции, которые помогают фильтровать данные.JMESPath also has built-in functions that can help with filtering. Одна из таких функций — contains(string, substring). Она позволяет проверить, содержит ли строка указанную подстроку.One such function is contains(string, substring), which checks to see if a string contains a substring. Выражения вычисляются до вызова функции. Поэтому первым аргументом может быть полное выражение JMESPath.Expressions are evaluated before calling the function, so the first argument can be a full JMESPath expression. В следующем примере выполняется поиск всех машин, использующих диски SSD для размещения ОС:The next example finds all VMs using SSD storage for their OS disk:

az vm list -g QueryDemo --query "[?contains(storageProfile.osDisk.managedDisk.storageAccountType,'SSD')].{Name:name, Storage:storageProfile.osDisk.managedDisk.storageAccountType}" -o json
[
  {
    "Name": "TestVM",
    "Storage": "StandardSSD_LRS"
  },
  {
    "Name": "WinTest",
    "Storage": "StandardSSD_LRS"
  }
]

Этот запрос достаточно длинный.This query is a little long. Ключ storageProfile.osDisk.managedDisk.storageAccountType используется дважды, и в выходных данных ему присвоено другое имя.The storageProfile.osDisk.managedDisk.storageAccountType key is mentioned twice, and rekeyed in the output. Один из способов сократить запрос — применить фильтр после преобразования массива в плоскую структуру и выбора данных.One way to shorten it is to apply the filter after flattening and selecting data.

az vm list -g QueryDemo --query "[].{Name:name, Storage:storageProfile.osDisk.managedDisk.storageAccountType}[?contains(Storage,'SSD')]" -o json
[
  {
    "Name": "TestVM",
    "Storage": "StandardSSD_LRS"
  },
  {
    "Name": "WinTest",
    "Storage": "StandardSSD_LRS"
  }
]

Если в массиве с множество элементов, возможно, применение фильтра перед выбором данных ускорит операцию.For large arrays, it may be faster to apply the filter before selecting data.

Полный список встроенных функций см. в этом разделе спецификации JMESPath.See the JMESPath specification - Built-in Functions for the full list of functions.

Изменение выходных данныхChange output

Функции JMESPath также можно использовать для обработки результатов запроса.JMESPath functions also have another purpose, which is to operate on the results of a query. Любая функция, которая возвращает значение, отличное от логического, изменяет результаты выражения.Any function that returns a non-boolean value changes the result of an expression. Например, данные можно отсортировать по значению свойства с помощью функции sort_by(array, &sort_expression).For example, you can sort data by a property value with sort_by(array, &sort_expression). В JMESPath используется специальный оператор & для выражений, которые должны вычисляться позднее в функции.JMESPath uses a special operator, &, for expressions that should be evaluated later as part of a function. В следующем примере показано, как отсортировать список виртуальных машин по размеру диска с ОС:The next example shows how to sort a VM list by OS disk size:

az vm list -g QueryDemo --query "sort_by([].{Name:name, Size:storageProfile.osDisk.diskSizeGb}, &Size)" --output table
Name     Size
-------  ------
TestVM   30
Test-2   32
WinTest  127

Полный список встроенных функций см. в этом разделе спецификации JMESPath.See the JMESPath specification - Built-in Functions for the full list of functions.

Интерактивное использование запросовExperiment with queries interactively

Чтобы начать изучение JMESPath, можно использовать пакет Python JMESPath-terminal, который предоставляет интерактивную среду для работы с запросами.To start experimenting with JMESPath, the JMESPath-terminal Python package offers an interactive environment to work with queries. Данные подаются на вход, и в редакторе можно составлять и выполнять запросы.Data is piped as input, and then queries are written and run in the editor.

pip install jmespath-terminal
az vm list --output json | jpterm