Примечание: есть недостаток в процессе, описанном ниже.В частности, если для некоторой переменной среды задано многострочное значение, где одна из строк значений соответствует выражению sed
, вы также захватите эту строку.Чтобы избежать этого, если у вас есть Python, вы можете использовать:
python -c 'import os; print(os.getenv("FOO(BAR)"))'
например.Это выведет None
, если переменная не установлена, поэтому вы можете захотеть сделать ее более привлекательной: например, указать значение по умолчанию или использовать sys.exit(1)
, например, если переменная не установлена.(Но если у вас есть доступный интерпретатор Python, вы можете подумать о написании на Python, а не непосредственно в bash.)
Имена переменных в оболочке Unix (sh, bash и т. Д.), Включая переменные среды, ограниченык наборам символов, которые исключают скобки.В частности, "$FOO(BAR)"
всегда анализируется как ссылка на переменную $FOO
, за которой следует (BAR)
как отдельное слово.Это справедливо даже для форм расширения в фигурных скобках, где отдельное слово (BAR)
синтаксически недопустимо:
bash$ echo "${FOO(BAR)}"
bash: ${FOO(BAR)}: bad substitution
Тем не менее, возможно для установки таких переменных и доступа к ним, используя другиепрограммы.Например, используя Python I , установите FOO(BAR)
в hello
:
>>> import os
>>> os.environ["FOO(BAR)"] = "hello"
>>> import subprocess
>>> subprocess.call("bash")
bash$
Этот экземпляр bash не может напрямую получить доступ к переменной, но env
печатает все переменные:
bash$ env | grep FOO
FOO(BAR)=hello
Если у вас есть env
(возможно, у вас есть) и sed
, вы можете объединить их для извлечения произвольных переменных:
bash$ setting="$(env | sed -n 's/^FOO(BAR)=//p')"
bash$ echo "$setting"
hello
При условии, что Windows Bash не имеетв любом особом случае, чтобы лучше обойти эту конкретную неловкость, этот же трюк должен работать для "ProgramFiles (x86)".
Подстановка нескольких обратных косых черт с прямой косой чертой
Вы в основном здесь: проблемаявляется то, что ваш шаблон выглядит специально для :\
, но строки имеют несколько \
s без двоеточий.Лучше всего, вероятно, иметь программу или функцию, которая на самом деле понимает пути Windows, поскольку они не обязательно имеют буквы дисков на передней панели (см. https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats). Но этот шаблон работает для обратной косой черты:
bash$ v='a\b\c'
bash$ echo ${v//\\/\/}
a/b/c
Двойная косая черта означает «заменить все вхождения». Шаблон равен \\
, что соответствует одному обратному слешу. Следующий слеш вводит заменяющую строку, которая является \/
, что означаетодна косая черта (это также можно записать как просто /
, но мне кажется, что это сложнее читать, как ни странно.)
Конечно, это не заменяет двоеточие в C:
, поэтому нам нужен одинбольше подстановок. Вы не можете сделать это в одном ${...}
расширении, поэтому хитрость заключается в том, чтобы добавить еще один:
bash$ v='C:\a\b\c'
bash$ echo ${v//\\/\/}
C:/a/b/c
bash$ v1="${v//\\//}"; echo ${v1/:/}
C/a/b/c
Поместите это в функцию оболочки, которую вы в конечном итоге можете сделать достаточно умной, чтобы справиться с ней.все допустимые пути, и таким образом вы можете использовать local
для предотвращения утечки имени переменной v1
.