Bash: How to use operator parameter expansion ${parameter@operator}?
Asked Answered
W

2

21

I've googled and tried so many things and never could get anything to work with ${parameter@operator}. All I find is more links to the same documentation. So I think a proper answer with practical examples would be very helpful to its understanding.

The documentation says:

${parameter@operator}

The expansion is either a transformation of the value of parameter or information about parameter itself, depending on the value of operator. Each operator is a single letter:

Q
The expansion is a string that is the value of parameter quoted in a format that can be reused as input.

It also says about quoting:

3.1.2 Quoting
Quoting is used to remove the special meaning of certain characters or words to the shell.

So my reasoning is that the output of this (special character $):

a="To be reused as an input string, \$0 needs to be quoted"
echo ${a@Q}

should be this (between "", the '\' is removed, so needs quoting again to be used as an input):

To be reused as an input string, \$0 needs to be quoted

but I get:

bash: ${a@Q}: bad substitution

I tried different combinations of:

${a@q}, "${a@Q}", a='To be reused as an input string, $0 needs to be quoted'

to no avail.

Actually, any operators I try to use always yields the bad substitution error. Those seems to be very obscure features of bash. I've omitted from this post about half an hour of attempts each one more twisted than the previous!

Warranty answered 22/11, 2016 at 1:6 Comment(2)
I have noticed that if I try this in an interactive shell it works but if I have it in a script it fails. Anyone know why that it?Bircher
@WilliamRusnack It's likely that your script was not shebang'd to use Bash 4.4+.Metropolis
V
34

For those who arrive here looking for information on a different expansion operator, here's a quick list of the available expansion characters and their effects.

${varname@Q} returns a single-Quoted string with any special characters (such as \n, \t, etc.) escaped.

Examples:

$ foo="one\ntwo\n\tlast"
$ echo "$foo"
one\ntwo\n\tlast

$ echo ${foo@Q}
'one\ntwo\n\tlast'

${varname@E} returns a string with all the escaped characters Expanded (e.g. \n -> newline).

Examples:

$ foo="one\ntwo\n\tlast"
$ echo "${foo}"
one\ntwo\n\tlast

$ echo "${foo@E}"
one
two
        last

${varname@P} returns a string that shows what the variable would look like if it were used as a Prompt variable (i.e. PS1, PS2, PS3)

Example:

$ bar='host: \h'
$ echo ${bar@P}
host: myhost1

(There are many more escape sequences that can be applied in prompt variables. See the bash documentation.)

${varname@A} returns a string that can be used to Assign the variable with its existing name, value, and declare options if any.

Example:

$ foo="test1"
$ echo ${foo@A}
foo='test1'

$ declare -i foo=10
$ echo "${foo@A}"
declare -i foo='10'

${varname@a} returns a string listing the Attributes of the variable.

Example:

$ declare -ir foo=10
$ echo ${foo@a}
ir

(The available declare options are: -r readonly, -i integer, -a array, -f function, -x exportable.)

Valuate answered 30/1, 2017 at 16:18 Comment(0)
W
6

Sorry, I didn't browse Stack properly, there is an example use here:

How to display a file with multiple lines as a single string with escape chars (\n)

$ foo=$(<file.txt)
$ echo "${foo@Q}"
$'line1\nline2'

Plus, I don't have bash 4.4 in which the feature was implemented < sigh >

Warranty answered 22/11, 2016 at 1:13 Comment(1)
You could download and compile bash 4.4 from here. Just untar, ./configure, make to get the compiled version.Amnesty

© 2022 - 2024 — McMap. All rights reserved.