Подстановка команды fish не работает, как в bash или zsh

Я наткнулся на проблему с оболочкой fish (моя любимая оболочка), когда пытаюсь использовать подстановку команд:

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 ’

Я тестировал как bash, так и zsh, и эквивалентный комментарий работает:

gcc $(pkg-config --libs --cflags gtk+-2.0 cairo) -o drawing_widget drawing_widget.c

person cedlemo    schedule 24.01.2015    source источник
comment
fish обрабатывает результаты pkg-config как один аргумент. Вам может понадобиться eval   -  person glenn jackman    schedule 24.01.2015
comment
Я прочитал документ и попытался использовать eval, но мне не удалось заставить его работать с gcc (eval pkg-config --libs --cflags gtk+-2.0 cairo) -o drawing_widget drawing_widget.c или установить pkg-config - -libs --cflags gtk+-2.0 cairo, затем gcc (eval $a) -o drawing_widget drawing_widget.c для примера   -  person cedlemo    schedule 24.01.2015
comment
Нет, я думал eval gcc (pkg-config ...) ...   -  person glenn jackman    schedule 25.01.2015
comment
Извините, я действительно иногда могу быть глупым. Ваше решение тоже работает, спасибо.   -  person cedlemo    schedule 25.01.2015


Ответы (1)


Соответствующее различие называется «разбиением слов», то есть как результат раскрытия переменной или подстановки команд превращается в несколько аргументов.

В bash и zsh разбиение слов происходит по всем пробелам. Пример:

> for i in $(echo 1 2 3) ; do echo $i; done
1
2
3

В fish разбиение слов происходит только на новые строки:

> for i in (echo 1 2 3); echo $i; end
1 2 3

В примере выше цикл запускается только один раз, когда $i установлено в '1 2 3'. Преимущество поведения рыбы в том, что имена файлов с пробелами и т. д. не вызывают проблем, как в bash.

pkg-config выводит текст, разделенный пробелами:

> pkg-config --libs --cflags libcurl libssl
-lcurl -lssl -lcrypto -lz

Таким образом, он полагается на поведение разделения слов bash. (Но у вас были бы проблемы, если бы какие-либо флаги нуждались в встроенных пробелах.)

Чтобы получить тот же эффект в fish, вы можете заменить пробелы символами новой строки. tr — хороший инструмент для этого:

pkg-config --libs --cflags libcurl libssl | tr -s ' ' \n

Флаг -s эффективно очищает конечный пробел, который выводит pig-config.

person ridiculous_fish    schedule 24.01.2015
comment
Это было не очевидно, но это работает, спасибо за ответ и за рыбу! - person cedlemo; 24.01.2015