Не вдається успішно виправити .bashrc із сценарію оболонки


51

Зазвичай ми можемо створити ~/.bashrcфайл за допомогою цієї команди

source ~/.bashrc

але якщо я напишу це в сценарії оболонки і виконую його, нічого не вийде. Чому?
Чи можна це зробити?

Мій сценарій:

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

Також спробували .(крапка) замість source. Той самий результат.

Відповіді:


26

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

На противагу цьому sourceкоманда не запускає новий екземпляр оболонки, але використовує поточну оболонку, так що зміни залишаються.

Якщо ви хочете, щоб ярлик читав ваш .bashrc, використовуйте функцію оболонки або псевдонім замість сценарію оболонки, наприклад

alias brc='source ~/.bashrc'

Дякуємо за швидку відповідь. Можливо, ваше рішення спрацює, але мені потрібно редагувати файл bashrc вручну, щоб зберегти рядок 'aliac brc = ....'. Я намагаюся розробити gui для зміни змінної середовища. Тому я не можу редагувати файл bashrc іншого комп’ютера вручну.
шантану

1
Ви повинні бігти source ~/.bashrcв оболонці, яку ви хочете змінити. Ви не можете змінити це в іншому процесі. Можливо (глобально) додавання цього псевдоніма може бути частиною процесу встановлення вашого графічного інтерфейсу.
Флоріан Дієш

1
тож я ставлю свою команду псевдоніму раніше в скрипті, а потім викликаю brc, коли мені потрібно створити свій .bashrc або мені потрібно десь помістити цю псевдонім у файл?
користувач137717

Що я в кінцевому підсумку робив - це продовження відповіді Флоріана Діеша. Ви можете просто використовувати багаторядковий псевдонім: alias brc = 'chmod a + x ~ / .bashrc; Джерело ~ / .bashrc 'Я все ще досить новий, тому я не впевнений, чи вважається це "поганою практикою". Це все-таки працює.
A_user_appears

13

Ваш .bashrcзазвичай починається:

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

Оскільки у вашого сценарію не встановлено PS1 (оскільки він не є інтерактивним), він не скидає шлях, тому що він виходить рано. Щоб продемонструвати, змініть свій сценарій:

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

це дозволить вашим сценаріям працювати з новими .bashrc. Примітка. Після того, як ваш скрипт закінчиться, env буде встановлений таким, яким він був до запуску сценарію. Зміни будуть відображені при наступному запуску терміналу.


Принаймні з 16.04 і, ймовірно, раніше, Ubuntu за замовчуванням .bashrcвикористовує більш надійний спосіб перевірити, чи оболонка інтерактивна. /etc/bash.bashrcдосі є тест PS1.
Занна

12

Спробуйте:

exec bash

Це має перезавантажити ~ / .bashrc, ~ / .bash_aliases тощо.


9
Це замінює поточний процес bash новим. Це не набагато коротше або простіше, ніж використання, sourceале знищує будь-які змінні та такі, що користувач встановив вручну - що може, а може, і не те, що ви хочете.
Флоріан Дієш

тримайте, в контексті сценарію Shell з іншими командами після пошуку bashrc, ви ставите команди, які потребують нового стану bash після цього exec bash, як я розумію, команда після цього все ще буде в тих же налаштуваннях bash, що і раніше?
тацу

11

Я хочу доповнити відповідь Раві :

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

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

Це зупинить оцінку файлу, якщо він працює в неінтерактивній оболонці, що стосується вашого сценарію, оскільки всі сценарії виконуються в неінтерактивній оболонці , а згодом кожен файл, який ви sourceбудете успадковувати це властивість.

eval рубати

Я виявив некрасивий хак для вирішення Ubuntu спеціально, використовуючи evalзамість source:

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

Він просто пропускає кілька перших рядків і оцінює решту, ~/.bashrcтому решта оцінюється і змінює поточне виконання.

Будьте в курсі, що це чарівне число і може не працювати в версіях Ubuntu; але може бути хорошим рішенням, якщо ви розробляєте сценарії для більш-менш відомих систем.

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

Альтернатива Шебангу

Іншою альтернативою, яка може працювати краще в деяких сценаріях, є змушування сценарію запускатися в інтерактивній оболонці, додаючи прапор у шебанг :

#!/bin/bash -i

Будьте в курсі кількох речей:

  • Це краще практика використовувати #!/usr/bin/env bashформу , але таким чином , ви не можете запустити оболонку з аргументами .
  • Використовуючи -iсвій власний набір наслідків, серед них програми підкажуть про взаємодію користувачів, і це, як правило, не призначено для сценаріїв, наприклад, встановлення debпакетів може зупинити скрипт dpkg configureпідказки .
  • Спочатку я намагався використовувати set -iта set +iвмикати функцію там, де мені це потрібно, але це не працює .

2

Жоден з інших методів для мене не працював [ source /path/to/fileпроти . ./path/to/file, псевдоніму тощо], поки, завдяки цьому підручнику я не виявив, що використовуючи:

#!/usr/bin/env bash shebang

замість більш простого #!/usr/bin/envможна передати аргументи перекладачеві, що, на мою думку, тут є ключовим - див. цей документ для отримання додаткової інформації.

У будь-якому випадку, якщо вихідні команди в будь-якій формі не працюють для вас, спробуйте перевірити свій шебанг, це може бути проблемою :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.