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 named1
that happens to exist in the current directory (and would also match files named0
,2
,7
if such existed) – steeldriver Sep 06 '18 at 23:271
inbash 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' $(...)
. – Sparhawk Sep 06 '18 at 23:34curl
(so I couldgrep
the--verbose
output) months ago and created the file accidentally when I'd run it with2>1
rather than2>&1
. If you re-post this as an answer, I'll mark it as accepted. Thank you! – BQ. Sep 06 '18 at 23:371
is the symptom; the cause is insufficient quoting. – Jeff Schaller Sep 06 '18 at 23:46[...]
isn't treated as a filename glob) rather than relying on there being no files that happen to match it – steeldriver Sep 06 '18 at 23:55