Обновите `.bashrc` и перезагрузите

Обновите `.bashrc` и перезагрузите

У меня есть скрипт, который вставляет несколько строк в конец моего .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».

Связанный контент