问题
I have stumbled on a problem with the fish shell (which is my favorite shell) when I am trying to use command substitution:
gcc (pkg-config --libs --cflags gtk+-2.0 cairo) -o drawing_widget drawing_widget.c
gcc: erreur: unrecognized command line option ‘-pthread -I/usr/include/gtk-2.0
-I/usr/lib/gtk-2.0/include -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/gdk-pixbuf-2.0
-I/usr/include/libpng16 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/glib-2.0
-I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2
-I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/harfbuzz
-I/usr/include/libdrm -I/usr/include/libpng16 -lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0
-lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lfontconfig -lfreetype -lcairo ’
I have tested with both bash and zsh and the equivalent comment works:
gcc $(pkg-config --libs --cflags gtk+-2.0 cairo) -o drawing_widget drawing_widget.c
回答1:
The relevant difference is called "word splitting," which is how the result of a variable expansion or command substitution is turned into multiple arguments.
In bash and zsh, word splitting occurs on all whitespace. Example:
> for i in $(echo 1 2 3) ; do echo $i; done
1
2
3
In fish, word splitting occurs only on newlines:
> for i in (echo 1 2 3); echo $i; end
1 2 3
In the above, the loop only runs once, with $i set to '1 2 3'. The advantage of the fish behavior is that filenames with spaces, etc. don't cause problems like they do in bash.
pkg-config
outputs space-separated text:
> pkg-config --libs --cflags libcurl libssl
-lcurl -lssl -lcrypto -lz
So it's relying on bash's word splitting behavior. (But you'd be in trouble if any flags needed embedded whitespace.)
To get the same effect in fish, you can replace spaces with newlines. tr
is a good tool for that:
pkg-config --libs --cflags libcurl libssl | tr -s ' ' \n
The -s
flag effectively cleans up a trailing space that pig-config outputs.
来源:https://stackoverflow.com/questions/28128669/fish-command-substitution-doesnt-work-like-in-bash-or-zsh