Переменная Shell с пробелами, заключающими в кавычки для единственного параметра командной строки

Я знаю, что Вы сказали, чтобы не сказать Вам использовать Emacs.

Использование Emacs.

Серьезный, СЛИЗЬ установка для Emacs в значительной степени стандартная платформа разработки для Lisp, и на очень серьезном основании.

14
задан Patrick 12 November 2009 в 17:40
поделиться

5 ответов

Вам следует попробовать установить переменную среды $ IFS .

из man bash (1):

IFS - Внутренний разделитель полей, который используется для разбиение слов после раскрытия и разбивать строки на слова с помощью встроенной функции чтения команда. Значение по умолчанию - «пробел табуляции с новой строкой».

Например

IFS=<C-v C-m>  # newline
file="a b"
touch $file
ls $file

Не забудьте вернуть $ IFS назад, иначе произойдут странные вещи.

9
ответ дан 1 December 2019 в 13:59
поделиться

Использование кавычек интересно. Из (легкого) чтения страницы руководства bash я подумал, что вам нужно избежать пробела с помощью \, поэтому "/ path with space" становится / path \ with \ space Я никогда не пробовал кавычки, но кажется, что это не так работать в целом (ваш пример ls). Экранирование работает с ls без кавычек и без изменения IFS.

Что произойдет, если вы воспользуетесь форматом команды «экранирование пробелов»?

0
ответ дан 1 December 2019 в 13:59
поделиться

Вы хотите процитировать весь аргумент одним из следующих способов:

./configure "CPPFLAGS=-I/path with space"
./configure CPPFLAGS="-I/path with space"

Команда ./ configure затем видит единственный аргумент

"CPPFLAGS=-I/path with space"

, который анализируется как параметр с именем «CPPFLAGS» , имеющий значение «- I / путь с пробелом» (скобки добавлены для ясности) .

1
ответ дан 1 December 2019 в 13:59
поделиться

если вы дадите команду

 gcc -I"x y z"

в оболочке, то, безусловно, единственный параметр командной строки «-Ix y z» будет передан gcc. В этом нет никаких сомнений. В этом весь смысл двойных кавычек: вещи, заключенные в двойные кавычки, НЕ подлежат разделению полей и, следовательно, не подчиняются, например, $ IFS.

Но вы должны быть осторожны с количеством необходимых кавычек. Например, если вы скажете

 file="a b" # 1

, а затем

 ls $file # 2

, произойдет то, что содержимое переменной файла будет 'a b', а не 'ab', потому что двойные кавычки были «съедены» при анализе строки 1 . Замененное значение затем разделяется полями, и вы получаете ls для двух файлов 'a' и 'b'. Правильный способ получить то, что вы хотите:

 file="a b"; ls "$file"

Теперь проблема в вашем исходном случае заключается в том, что когда вы устанавливаете переменную в строку, СОДЕРЖАЩУЮ двойные кавычки, двойные кавычки позже интерпретируются не как символы кавычек оболочки, а как обычные буквы . Вот почему, когда вы выполняете что-то вроде

 file="\"a b\""; ls $file

, на самом деле оболочка токенизирует содержимое файловой переменной в '"a' и 'b"' при анализе команды ls; двойная кавычка больше не является символом кавычки оболочки, а просто частью содержимого переменной. Это аналогично тому, что если вы установите

 file="\$HOME"; ls $file

, вы получите сообщение об ошибке, что каталог «$ HOME» не существует - поиск переменных среды не выполняется.

Так что ваш лучший вариант -

  1. Взломать autoconf
  2. Do не используйте имена путей с пробелами (лучшее решение)
4
ответ дан 1 December 2019 в 13:59
поделиться

Использование пробела в именах каталогов в Unix мир просто напрашивается на неприятности. Это не просто проблема цитирования в сценариях оболочки (что в любом случае нужно делать правильно): некоторые инструменты просто не справляются с пробелами в именах файлов. Например, вы не можете (переносимо) написать правило Makefile , которое говорит: build « baz.o » из « foo bar / baz.c ».

В случае CPPFLAGS выше я бы в порядке предпочтения:

  1. исправил, что система не использовала пространство в именах каталогов
  2. напишите небольшую оболочку вокруг компилятора и вызовите ./ настроить CC = mygcc . В этом случае mygcc может быть
    
    

    ! gcc "-I / foo bar / include" " $ @ "

  3. создайте символическую ссылку (например, / tmp / mypath ) на ужасный путь и используйте CPPFLAGS = -I / tmp / mypath
2
ответ дан 1 December 2019 в 13:59
поделиться