Azure / azure-cli

Azure Command-Line Interface
MIT License
4.03k stars 3k forks source link

Azure CLI needs a "text" variant of the --output argument - "tsv" is not enough! #24140

Open michael-crawford opened 2 years ago

michael-crawford commented 2 years ago

Related command Azure commands need to have an --output text option, in addition to --output tsv. The latter leaves the '\r' and '\n' characters in place, and this causes problems when attempting to extract the command output and use it as a variable in following commands, or in interpolated strings, when using the Azure CLI in a bash or zsh shell on WSL2 or macOS.

Is your feature request related to a problem? Please describe. Here's an example of the problem and the workaround I've had to develop. I shouldn't have to use this workaround, as when I'm trying to use JMESquery syntax to extract a value, logically, I want ONLY that value, not that value with potentially a carriage return and line feed appended to that value.

use-case: I want to obtain billing scope, and the common/intuitive way to obtain a variable using one command for use in a second, doesn't work (FYI: Coming from AWS CLI, where this syntax is often used, but they have an --output text):

billing_account_display_name="John Doe"
billing_account_name=$(az billing account list --query "[?displayName == '${billing_account_display_name}'].name" --output tsv)
echo $billing_account_name

# This variable looks normal... until you redirect std out to a file instead, then examine it in a hex editor, where you can see it has '/r/n' appended.

# Causing the use of this variable in the next command to fail, because of these extra and unwanted characters.
invoice_section_display_name="John Doe"
billing_scope=$(az billing profile list --account-name $billing_account_name \ 
                                                --expand InvoiceSections \
                                                --query "[*].invoiceSections[].value[?displayName == '$invoice_section_display_name'].id" -o tsv)
echo $billing_scope

This forces me to add what I think is an unnecessary pipe into tr to remove these unwanted characters, so the following works.

billing_account_display_name="John Doe"
billing_account_name=$(az billing account list --query "[?displayName == '${billing_account_display_name}'].name" --output tsv | tr -d '\r\n')
echo $billing_account_name

# Now the variable IS exactly what I want - the value and ONLY the value, with no trailing '/r/n'

# Now the next command works, as the variable is as expected
invoice_section_display_name="John Doe"
billing_scope=$(az billing profile list --account-name $billing_account_name \
                                                --expand InvoiceSections \
                                                --query "[*].invoiceSections[].value[?displayName == '$invoice_section_display_name'].id" -o tsv | tr -d '\r\n')
echo $billing_scope

Describe the solution you'd like I should be able to use --output text to get a single value with the quotes and any line ending characters stripped off. If the value is a single array containing a single quoted string, this again should be only the string with no array notation or quotes, and no line ending characters.

I'll leave it up to you on how to handle values which contain multiple lines and fields. There is one major use case for this syntax, and that's to obtain a SINGLE value via a query, to use as a variable to make another API call for a dependent value. It should work in a simple and obvious way.

Describe alternatives you've considered See above, I can add | tr -d '\r\n' - it clutters up the code and I shouldn't have to do this to obtain a simple text value via a query.

Additional context

yonzhan commented 2 years ago

@jiasli for awareness