Вопрос или проблема
Мне нужно добавить модификатор командной строки PS1="..."
в сценарий оболочки, который я настраиваю. Проблема в том, что я использую обратные кавычки для выполнения команды перед основной командой:
sudo tee ~/.bashrc <<EOF
# Отображать абсолютный путь в командной строке, команды на новой строке
PS1='\[`[ $? = 0 ] && X=2 || X=1; tput setaf $X`\]\h [\u]\[`tput sgr0`\]:$PWD\n\$ '
EOF
cat ~/.bashrc
показывает:
# Отображать абсолютный путь в командной строке, команды на новой строке
PS1='\[\]\h [\u]\[\]:/Users/myuser/Library/Application Support/Sublime Text 3/Packages/User\n$ '
nano ~/bashrc
показывает:
PS1='\[^[[32m\]\h [\u]\[^[(B^[[m\]:/Users/myuser/Library/Application Support/Sublime Text 3/Packages/User\n$ '
Это явно означает, что все в обратных кавычках не читается правильно. Как я могу экранировать обратные кавычки или иначе записать строку, которая включает обратные кавычки, в файл, используя оболочку?
В документе here, как вы его написали, оболочка выполнит расширение параметров ($PWD
будет расширен до пути текущего каталога в момент обработки сценария, например), подстановку команд (обратные кавычки будут выполнены, и то, что эта команда производит, будет вставлено на их место в момент обработки документа here) и арифметическое расширение (в вашем случае этого нет).
Если вы не хотите этого, то есть если вы хотите, чтобы содержимое документа here было доставлено как есть, вы можете сделать следующее:
tee -a "$HOME/.bashrc" <<'EOF'
# содержимое here-документа здесь
EOF
Апострофы вокруг EOF
на первой строке предотвращают расширение оболочкой чего-либо в самом документе here. Использование любого из 'EOF'
, "EOF"
или \EOF
, или экранирование любой части строки-разделителя имеет тот же эффект. Строка сама по себе, EOF
, произвольна. В приведенном выше примере можно было бы использовать BASHRC_ADDITION
вместо этого или какую-либо аналогичную описательную строку.
Ответ или решение
Ваша проблема связана с тем, как интерпретируется содержимое here-документа в оболочке (shell). Когда вы используете here-документ с <<EOF
, оболочка выполняет подстановку параметров, подстановку команд (например, с использованием обратных кавычек) и так далее, что может привести к нежелательному поведению, когда специальные символы, такие как обратные кавычки, не обрабатываются должным образом.
Чтобы записать содержимое в файл без выполнения интерпретации, вам нужно заключить метку here-документа (например, EOF
) в одинарные кавычки. Это предотвратит интерпретацию содержимого, и оболочка будет записывать всё как есть. Вот как это можно сделать:
sudo tee -a ~/.bashrc << 'EOF'
# Отображение абсолютного пути в командной строке, команды на новой строке
PS1='\[`[ $? = 0 ] && X=2 || X=1; tput setaf $X`\]\h [\u]\[`tput sgr0`\]:$PWD\n\$ '
EOF
Что происходит здесь:
- Используем
sudo tee -a ~/.bashrc
для добавления текста к файлу~/.bashrc
. - Заключаем
EOF
в одинарные кавычки, чтобы отключить все виды подстановок, которые может сделать оболочка (включая подстановку команд и переменных).
Таким образом, весь текст внутри here-документа будет записан точно так, как вы его указали, и ваши обратные кавычки будут оставлены нетронутыми.
Если вы хотите увидеть изменения, выполните команду cat ~/.bashrc
, и вы должны увидеть:
# Отображение абсолютного пути в командной строке, команды на новой строке
PS1='\[`[ $? = 0 ] && X=2 || X=1; tput setaf $X`\]\h [\u]\[`tput sgr0`\]:$PWD\n\$ '
Теперь обратные кавычки и все остальное, что вы написали, будут правильно сохранены в вашем файле ~/.bashrc
без нежелательной интерпретации. После этого вы можете перезагрузить терминал или выполнить source ~/.bashrc
, чтобы применить изменения.