4

Для данного каталога: /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?

2 ответа2

8

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

cd "$Foo"

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

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

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

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

Впрочем, никогда не стоит перезаписывать встроенные функции подобным образом.

2

Как сказал @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, но если вы действительно этого хотите, это лучший способ. Я сам им не пользуюсь, но тем, кому это очень нравится ...

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .