Вопрос: Пространства в переменных среды Linux?


Данный каталог: /media/foo/can haz/bar, Я пробовал редактировать bash.rc с:

export Foo=/media/foo/can haz/bar
export Foo=/media/foo/can\ haz/bar
export Foo='/media/foo/can haz/bar'
export Foo="/media/foo/can haz/bar"
export Foo='"/media/foo/can haz/bar"'
export Foo="'/media/foo/can haz/bar'"

Каждый раз, хотя, я не мог получить что-то вроде следующего для работы (без использования "$Foo"):

cd $Foo

Как установить переменную окружения с пробелами в системе Linux?


4
2017-07-06 18:13


Источник


Может быть, если я установил псевдоним или что-то еще? - A T


Ответы:


Проблема заключается не в том, что ваша переменная окружения содержит пробел. Вы забываете цитируйте свои аргументы:

cd "$Foo"

Если вы не цитируете $Foo, cd команда фактически увидит два (или более) аргумента, поскольку пробел по умолчанию разделяет аргументы, В вашем конкретном случае вы пройдете /media/foo/can а также haz/bar отдельно, так как оболочка разбивает их в пространстве. Переменные с двойным кавычком - хорошая привычка развиваться и сэкономит вас в довольно многих случаях, когда речь идет о пробелах.

Если вы хотите действительно уродливый способ добиться этого без кавычек, перезапишите свой cd встроенный:

cd() { builtin cd "$*"; }

Это будет работать, если путь содержит пробелы, поскольку $* будут содержать отдельные аргументы (/media/foo/can а также haz/bar), разделенные первым символом IFS (обычно это пробел), а затем вы склеиваете их вместе с двойными кавычками.

Однако никогда не рекомендуется переписывать встроенные функции, подобные этому.


8
2017-07-06 18:17



Как уже упоминалось, я хочу избежать этого; вот и вся проблема, которую я пытаюсь решить. - A T
Вы украли эту часть? Я не помню, чтобы это было в первой ревизии вопроса, который я видел :) Во всяком случае, ваш вопрос: «Как установить переменную окружения с пробелом?», И ответ заключается в том, что вы можете просто это сделать. Как вы справляетесь с этим, это другая проблема, и вы не можете заставить ее работать без кавычек, это всего лишь вопрос о том, как работает оболочка. - slhck
@AT Вы видели мое обновление? - slhck


Как сказал @slhck, правильный способ сделать это - поставить двойные кавычки вокруг ссылки на переменные (например, cd "$Foo"). Причиной этого является порядок, в котором оболочка анализирует различные аспекты командной строки: сначала он сканирует кавычки и экраны (и удаляет их, применяя их эффекты), затем заменяет ссылки на переменные своими значениями (например, $Foo -> /media/foo/can haz/bar), то он возвращается через замененные значения и применяет расширение подстановочных знаков (*.txt -> a.txt b.txt и т. д.) и разбиение слов (/media/foo/can haz/bar -> "/ media / foo / can" "haz / bar"), но он никогда не возвращается и ищет кавычки и / или экранирует значения переменных. В результате, вложение кавычек и / или экранирование в значение переменной делает ничего даже мало полезно; к тому времени, когда они являются частью командной строки, слишком поздно для них иметь предполагаемый эффект. Я знаю только три способа избежать разделения слов по расширенному значению:

  1. Двойная кавычка ссылки на переменные. Это не так удобно, но это требование стандартного синтаксиса оболочки.
  2. Измените значение IFS (список символов, которые используются для разбиения слов на расширенные переменные). Затем наблюдайте, как все скрипты, зависящие от стандартного расщепления слов, ломаются странно. Пожалуйста, не делайте этого. Шутки в сторону.
  3. Переключитесь на оболочку, которая не выполняет разбиение слов на расширенные переменные: zsh. Вам придется привыкнуть к другим отличиям от bash, но если вы действительно этого хотите, это лучший способ пойти. Я не использую его сам, но тем, кому это нравится, очень нравится ...

2
2017-07-06 21:32



Zsh также красиво автозаполняет cd $Foo в cd /path\ with/spaces, Я нашел Bash, чтобы сделать это неправильно, если вы запускаете его с Ctrl-A-E, но я не использовал Bash через некоторое время, поэтому было бы возможно настроить это также. - slhck