4

I would like to print the contents of a variable in such a way, that the printed output could be pasted directly into a shell to get the original content of the variable.

This is trivial if the content doesn't contain any special characters, esp no quotes. e.g.

$ x=foo
$ echo x=${x}
x=foo

In the above example i can take the output (x=foo and paste it into a new terminal to assign foo to x).

If the variable content contains spaces, things get a bit trickier, but it's still easy:

$ x="foo bar"
$ echo x=\"${x}\"
x="foo bar"

Now trouble starts, if the variable is allowed to contain any character, e.g.:

$ x=foo\"bar\'baz
$echo ${x}
foo"bar'baz
$ echo x=\"${x}\"
x="foo"bar'baz"
$ x="foo"bar'baz"
>

(and the terminal hangs, waiting for me to close the unbalanced ")

What I would have expected was an output like the following:

x=foo\"bar\'baz

How would I do that, preferably POSIX compliant (but if it cannot be helped, bash only)?

umläute
  • 28,885
  • 9
  • 68
  • 122

2 Answers2

4

Use declare -p:

x=foo\"bar\'baz
declare -p x

declare -- x="foo\"bar'baz"

Even with an array:

arr=(a 'foo' 'foo bar' 123)
declare -p arr

declare -a arr='([0]="a" [1]="foo" [2]="foo bar" [3]="123")'

The -p option will display the attributes and values of each variable name that can be used to directly set the variable again.


As per comment, doing this in POSIX without help of declare -p would be:

set | grep '^x='
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • nice. obviously this is `bash` only (which is ok, as mentioned in the question). but is there a POSIX compliant sulotion as well? – umläute Apr 23 '18 at 11:28
  • Doing this in POSIX without help of `declare -p` would be probably `set | grep '^var='` – anubhava Apr 23 '18 at 11:37
3

You could use the printf command with its %q flag it supports to print the associated argument shell-quoted

x=foo\"bar\'baz

printf 'x=%q' "$x"
x=foo\"bar\'baz

Again though %q is not a POSIX extension but added to most recent versions of bash shell. If this is what you where looking for look up this to see POSIX sh equivalent for Bash's printf %q

Inian
  • 80,270
  • 14
  • 142
  • 161