Обычно мы можем получить файл ~/.bashrc
с помощью этой команды
source ~/.bashrc
, но если я напишу это в сценарии оболочки и выполню, ничего не произойдет. Почему?
Есть ли способ сделать это?
Мой сценарий:
#!/bin/bash
chmod a+x ~/.bashrc
source ~/.bashrc
Также попытался .
(точка) вместо source
. Тот же результат.
Сценарий оболочки выполняется в собственном экземпляре оболочки. Все настройки переменных, определения функций и т.п. влияют только на этот экземпляр (и, возможно, его дочерние элементы), но не на вызывающий оболочку, поэтому после завершения работы скрипта они исчезают.
Напротив, команда source
не запускает новый экземпляр оболочки, а использует текущий экземпляр оболочки, поэтому изменения остаются неизменными.
Если вам нужен ярлык для чтения .bashrc, вместо скрипта shell'а используйте функцию shell'а или псевдоним, например
alias brc='source ~/.bashrc'
Попробуйте:
exec bash
Это должно перезагрузить ~/.bashrc, ~/.bash_aliases и т.д.
Ваш .bashrc
обычно запускается:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
Поскольку в вашем скрипте не установлен PS1 (потому что он не интерактивный), он не сбрасывает путь, потому что выходит рано . Для демонстрации измените ваш скрипт:
#!/bin/bash
chmod a+x ~/.bashrc
PS1='$ '
source ~/.bashrc
теперь это позволит вашим скриптам работать с новым .bashrc
.
Примечание: как только ваш скрипт завершится, env будет установлено на то, что было до запуска скрипта. Изменения будут отражены при следующем запуске терминала.
Ни один из у меня работали другие методы [ источник / путь / к / файлу
vs . ./path/to/file
, псевдоним и т. д.], пока, благодаря этому руководству я не обнаружил, что с помощью:
#! / usr / bin / env bash
shebang
вместо более простого #! / Usr / bin / env
позволяет аргументам передаваться интерпретатору, что, я думаю, является ключевым здесь - см. этот документ для получения дополнительной информации.
В любом случае, если исходные команды в какой-либо форме не работают для вас, попробуйте проверить свой шебанг, это может быть проблемой:)
Я хочу дополнить ответ 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 :
#!/bin/bash -i
Помните о нескольких вещах:
#! / usr / bin / env bash
, но таким образом вы не можете запустить оболочку с аргументами . - i
имеет свой собственный набор последствий, среди которых программы будут запрашивать взаимодействие с пользователем, и это обычно не предназначено для сценариев, например, установка пакетов deb
может остановить сценарий на dpkg configure
запрашивает . set -i
и set + i
чтобы включить и выключить эту функцию там, где она мне нужна, но это не работает .