У меня есть скрипт, который вставляет несколько строк в конец моего .bashrc
, есть ли способ получить их .bashrc
из скрипта, чтобы эти изменения сохранились после завершения скрипта? Вот MWE похожего скрипта:
#!/bin/bash
echo "export MyDir='MyAnalysis'" >> ~/.bashrc
echo "alias llA='ll MyAnalysis'" >> ~/.bashrc
source ~/.bashrc
После запуска скрипта ни , MyDir
ни не llA
будут доступны, если .bashrc
файл не будет получен вручную.
решение1
Не напрямую.
Ваш скрипт выполняется в отдельном процессе от вашей интерактивной оболочки. Любые изменения, которые оболочка скрипта вносит в среду, исчезнут при выходе из этой оболочки.Дочернему процессу не разрешается изменять среду родительского процесса.
Что вы можете сделать:
скрипт обновляет ваш .bashrc и больше ничего не делает: вы получаете доступ к своему bashrc, если скрипт успешно завершается
bash yourScript.bash && source .bashrc
скрипт обновляет .bashrc, иотпечаткиисходная команда: убедитесь, что она больше ничего не печатает. Затем вы
eval
запускаете скрипт.eval "$(bash yourScript.bash)"
скрипт обновляет .bashrc итакжепечатает то, что он делает. Вы оцениваете это: это скрипт
#!/bin/bash exec > >(tee -a "$HOME/.bashrc") echo "export MyDir='MyAnalysis'" echo "alias llA='ll MyAnalysis'"
и вы управляете им как
eval "$(bash yourScript.bash)"
не обновляйтеродительshell, но запустить новую интерактивную оболочку, которая будет читать bashrc
#!/bin/bash { echo "export MyDir='MyAnalysis'" echo "alias llA='ll MyAnalysis'" } >> ~/.bashrc exec bash -i
Родительская оболочка не обновляется.
Если вы сделаете код .bashrc-updatingфункция, то это будет работать так, как и ожидалось, поскольку функции выполняются в текущей оболочке (по умолчанию):
addMyAnalysis() {
echo "export MyDir='MyAnalysis'" >> ~/.bashrc
echo "alias llA='ll MyAnalysis'" >> ~/.bashrc
source ~/.bashrc
}
Альтернативный метод: создайте каталог "conf" $HOME/.bash.d
. Запишите туда файл bash
# this is "~/.bash.d/some_file.bash"
export MyDir='MyAnalysis'
alias llA='ll MyAnalysis'
И ваш .bashrc будет источником любого bash-файла в этом каталоге:
if [[ -d ~/.bash.d ]]; then
shopt -s nullglob
for f in ~/.bash.d/*.bash; do
source "$f"
done
shopt -u nullglob
fi
решение2
Как отметил @glenn-jackman, ваш источник происходит в подоболочке, где выполняется ваш скрипт, и в конце вашего скрипта вы возвращаетесь в родительскую оболочку, где источник не выполнялся, и .bashrc не выполняется заново — это разделение родительской и подоболочки обусловлено общими соображениями безопасности.
То, что вы ищете exec bash
, находится не внутри вашего скрипта, а сгруппировано с ним, т.е.
bash your-script.sh && exec bash
Это ведет себябудтовы бы снабжали и затем оставались в той оболочке, где вы снабжали. Действительно, этозаменяеттекущую оболочку на новую оболочку, и эта новая оболочка запускается, как и каждая (интерактивная) оболочка, с запуском вашего .bashrc, теперь уже с вашими изменениями, и то же самое происходит с каждой новой оболочкой / терминалом, которые вы запускаете.
Обратите внимание, что если вы выполните «exec bash» в своем скрипте, он заменит подоболочку, в которой выполняется ваш скрипт, но все равно останется подоболочкой.
Если ваша цель — динамическая и временная манипуляция .bashrc, вам следует рассмотреть предложения @glenn-jackman о внесении изменений в отдельные файлы, которые можно легко удалить в любой момент по вашему выбору. Для этого вы также можете просто иметь постоянную строку
[ -f ~/.bashrc-temporary-addons ] && source ~/.bashrc-temporary-addons
в конце вашего .bashrc и затем выполните (! толькоодин">" в первой строке, чтобы иметь свежий файл)
echo "" > ~/.bashrc-temporary-addons
echo "export MyDir='MyAnalysis'" >> ~/.bashrc-temporary-addons
echo "alias llA='ll MyAnalysis'" >> ~/.bashrc-temporary-addons
и, в момент по вашему выбору, просто
rm ~/.bashrc-temporary-addons
(Благодаря тесту "-f" ошибка не возникнет, если "~/.bashrc-temporary-addons" не существует).
Если ваши манипуляции с .bashrc должны существовать столько же, сколько и ваш сеанс, т. е. до выхода из системы (но не появляться снова при следующем входе в систему), то вы можете создать файл .bash_logout
для удаления временных файлов в «bash.d/» или всего содержимого «bash.d/» или «~/.bashrc-temporary-addons».