How can I get unmodified output from $() in bash?
I need to have bash return the results of command substitution (via $(command) or `command`), but bash treats the left square bracket as the test builtin and evaluates the text.
> echo "This shows an IP in brackets [127.0.0.1] when not in the command substitution context."
This shows an IP in brackets [127.0.0.1] when not in the command substitution context.
> echo $(echo "This should show an IP in brackets [127.0.0.1] but instead evaluates to '1'.")
This should show an IP in brackets 1 but instead evaluates to '1'.
> echo $(echo "The subtle addition of a space causes [127.0.0.1 ] to behave differently.")
The subtle addition of a space causes [127.0.0.1 ] to behave differently.
Background
Please note that the use of echo above to provide a minimal example is just that; my ultimate use will be including output from ping or tracert to show the IP of a host as seen by that host (i.e. respecting any hosts entries). In this usage, I have little control over the string being output by the command.
> grep -E "^[^#].*stackoverflow" /c/Windows/System32/drivers/etc/hosts
127.0.0.1 stackoverflow.com
> tracert -h 1 -w 1 stackoverflow.com | awk '/Tracing/'
Tracing route to stackoverflow.com [127.0.0.1]
> ping -n 1 -w 1 stackoverflow.com | awk '/Pinging/'
Pinging stackoverflow.com [127.0.0.1] with 32 bytes of data:
# Using dig or nslookup would show a real IP rather than the forced IP from the hosts entry.
> dig @ns1 +nocmd stackoverflow.com +noall +answer
stackoverflow.com. 118 IN A 151.101.129.69
stackoverflow.com. 118 IN A 151.101.193.69
stackoverflow.com. 118 IN A 151.101.1.69
stackoverflow.com. 118 IN A 151.101.65.69
> echo $(ping -n 1 -w 1 stackoverflow.com | awk '/Pinging/')
Pinging stackoverflow.com 1 with 32 bytes of data:
> echo $(ping -n 1 -w 1 stackoverflow.com | awk '/Pinging/ {print $3}')
1
> ping -n 1 -w 1 stackoverflow.com | awk '/Pinging/ {print $3}'
[127.0.0.1]
[test operator;[127.0.0.1]is a shell glob that's matching a file named1that happens to exist in the current directory (and would also match files named0,2,7if such existed)1inbash 4.4.23(1). I also agree that it's probably not the test operator, because you need a space after the[to use that. Finally, I'm not sure if relevant, but you can always useprintf '%s\n' $(...).curl(so I couldgrepthe--verboseoutput) months ago and created the file accidentally when I'd run it with2>1rather than2>&1. If you re-post this as an answer, I'll mark it as accepted. Thank you!1is the symptom; the cause is insufficient quoting.[...]isn't treated as a filename glob) rather than relying on there being no files that happen to match it