Не удается успешно получить исходный код .bashrc из сценария оболочки

Обычно мы можем получить файл ~/.bashrc с помощью этой команды

source ~/.bashrc

, но если я напишу это в сценарии оболочки и выполню, ничего не произойдет. Почему?
Есть ли способ сделать это?

Мой сценарий:

#!/bin/bash
chmod a+x ~/.bashrc
source ~/.bashrc

Также попытался . (точка) вместо source. Тот же результат.

65
задан 15 December 2018 в 12:01

5 ответов

Сценарий оболочки выполняется в собственном экземпляре оболочки. Все настройки переменных, определения функций и т.п. влияют только на этот экземпляр (и, возможно, его дочерние элементы), но не на вызывающий оболочку, поэтому после завершения работы скрипта они исчезают.

Напротив, команда source не запускает новый экземпляр оболочки, а использует текущий экземпляр оболочки, поэтому изменения остаются неизменными.

Если вам нужен ярлык для чтения .bashrc, вместо скрипта shell'а используйте функцию shell'а или псевдоним, например

alias brc='source ~/.bashrc'
26
ответ дан 15 December 2018 в 12:01

Попробуйте:

exec bash

Это должно перезагрузить ~/.bashrc, ~/.bash_aliases и т.д.

12
ответ дан 15 December 2018 в 12:01

Ваш .bashrc обычно запускается:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Поскольку в вашем скрипте не установлен PS1 (потому что он не интерактивный), он не сбрасывает путь, потому что выходит рано . Для демонстрации измените ваш скрипт:

    #!/bin/bash
    chmod a+x ~/.bashrc
    PS1='$ '
    source ~/.bashrc

теперь это позволит вашим скриптам работать с новым .bashrc . Примечание: как только ваш скрипт завершится, env будет установлено на то, что было до запуска скрипта. Изменения будут отражены при следующем запуске терминала.

15
ответ дан 15 December 2018 в 12:01

Ни один из у меня работали другие методы [ источник / путь / к / файлу vs . ./path/to/file, псевдоним и т. д.], пока, благодаря этому руководству я не обнаружил, что с помощью:

#! / usr / bin / env bash shebang

вместо более простого #! / Usr / bin / env позволяет аргументам передаваться интерпретатору, что, я думаю, является ключевым здесь - см. этот документ для получения дополнительной информации.

В любом случае, если исходные команды в какой-либо форме не работают для вас, попробуйте проверить свой шебанг, это может быть проблемой:)

2
ответ дан 15 December 2018 в 12:01

Я хочу дополнить ответ ravi :

Это поведение специфично для Ubuntu (и, вероятно, большинства производных дистрибутивов), поскольку ваш файл по умолчанию ~ / .bashrc начинается с короткого замыкания, Ubuntu 18.04, например:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Это остановит оценку файл, если он запущен в неинтерактивной оболочке, как в случае вашего сценария, поскольку все сценарии запускаются в неинтерактивной оболочке , и впоследствии каждый файл, который вы исходный будет унаследовать это свойство.

eval hack

Я обнаружил уродливый прием для обхода специфики Ubuntu, используя eval вместо sour ce :

eval "$(cat ~/.bashrc | tail -n +10)"

Он просто пропускает несколько первых строк и оценивает оставшуюся часть ~ / .bashrc , поэтому остальная часть оценивается и изменяет текущее выполнение.

Имейте в виду, что это - магическое число и может не работать в разных версиях Ubuntu; но может быть хорошим решением, если вы создаете сценарии для более или менее известных систем.

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

Альтернатива Shebang

Другая альтернатива который может работать лучше в некоторых сценариях, - это принудительный запуск сценария в интерактивной оболочке путем добавления флага в shebang :

#!/bin/bash -i

Помните о нескольких вещах:

  • Это a лучше использовать форму #! / usr / bin / env bash , но таким образом вы не можете запустить оболочку с аргументами .
  • Использование - i имеет свой собственный набор последствий, среди которых программы будут запрашивать взаимодействие с пользователем, и это обычно не предназначено для сценариев, например, установка пакетов deb может остановить сценарий на dpkg configure запрашивает .
  • Сначала я пытался использовать set -i и set + i чтобы включить и выключить эту функцию там, где она мне нужна, но это не работает .
19
ответ дан 15 December 2018 в 12:01

Другие вопросы по тегам:

Похожие вопросы: