Какой файл профиля bash мне следует использовать для каждого сценария?

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

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

  2. Если мне нужна строка кода bash, которая запускается только при входе в систему fo В любых новых интерактивных оболочках, где мне разместить этот код?

  3. Если мне нужна строка кода bash, которая открывается в обоих графических терминалах и интерактивных оболочках входа в систему, какой файл должен Я поместил этот код в?

• Важный момент: хочу подчеркнуть, что я хотел бы, чтобы эти строки кода только запускались при открытии оболочки или терминала, а не ] для запуска во время вызова любого старого однострочного эха «Hello World!» скрипта, который я запускаю. т.е. я хочу, чтобы они применялись только тогда, когда я выбираю , чтобы открыть оболочку / терминал, а затем начинаю вводить текст, а для других сценариев не включать это. Должно быть просто, не так ли?

Меня это действительно смущает, потому что на них действительно должно быть невероятно просто ответить, и тем не менее, я никогда не видел ответа. Я видел множество непостижимых ответов о том, как нам нужно использовать источник .profile из .bashrc , или, может быть, все наоборот (в зависимости от погоды) и "вы должны прочитать документ x, и документ y, и , тогда все будет ясно!" - ответы становятся все более запутанными, и на три вышеприведенных сценария сложно получить ответ: просто / ясно / однозначно. Было бы очень приятно знать, в какой файл нужно поместить каждый фрагмент кода, чтобы он работал в этом сценарии? Я не возражаю, если для этого также потребуется минимальная структура. ie "Для сценария 3 добавьте код в file-x , но для облегчения этого вы также должны поместить следующий блок if-then-fi в file-y ] ", но было бы огромным бонусом, если бы ответ для трех сценариев мог быть кроссплатформенным (то есть универсальным решением, применимым к debian / ubuntu, centos / red hat, MacOS, suse и т. д., а также в Gnome / KDE / MacOS и т. д. для графического терминала). Если нет рационального / логического способа добиться этого, то это, мягко говоря, досадно, но, надеюсь, я ошибаюсь!Надеюсь, кто-то покажет мне ясный, эффективный, , надеюсь, кроссплатформенный (но я знаю, что это может быть слишком много, чтобы требовать), повторяемый, простой и однозначный способ достижения вышеуказанного.

4
задан 19 November 2020 в 13:27

3 ответа

Я использую:

  • ~ / .profile для установки переменных среды
  • ~ / .bashrc для
    • псевдонимы и функции
    • переменные и настройки для интерактивных оболочек

Обратите внимание, что ~ / .profile не является специфичным для bash, поэтому не используйте специфичные для bash команды. Это означает

# export FOO=bar      # bad
FOO=bar; export FOO   # good

Поскольку все мои терминальные приложения с графическим интерфейсом пользователя настроены на использование оболочки входа в систему, в моем ~ / .profile я помещаю это:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

Кроме того, мне нравится сохранять мой PATH аккуратным, без дубликатов, поэтому вместо использования

PATH="$PATH:/some/path/1"
PATH="/some/path/2:$PATH"

У меня

pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            [ ! -d "$1" ] && return
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}

# then
pathmunge "/some/path/1" after
pathmunge "/some/path/2" before
pathmunge "/some/path/1" before   # already in PATH, no changes made
1
ответ дан 3 January 2021 в 22:48

bash распознает три состояния оболочки :

  • оболочка входа в систему - экземпляр оболочки, который был вызван непосредственно при входе на сервер через, например, ssh или текстовую консоль
  • интерактивная оболочка - любая оболочка, в которой вы можете вводить команды, например, запуск оболочки в графическом терминале. оболочка также (обычно) интерактивная оболочка.
  • неинтерактивная оболочка - это обычно оболочка, вызываемая из какой-либо программы для запуска другой программы или команды. Как следует из названия, в неинтерактивной оболочке th Здесь нет взаимодействия с пользователем. Например, если вы используете ssh для запуска только одной команды на удаленном компьютере (например, ssh host.domain ls -l / etc ), то вы неявно вызываете неинтерактивную оболочку на удаленном компьютере и эта оболочка, в свою очередь, выполняет команду, а затем завершает работу.

Как работают файлы запуска:

  • оболочка входа в систему выполняет команды из / etc / profile (это глобальный файл для всех пользователей), а затем ищет файлы .bash_profile , .bash_login или .profile - в этом порядке - в домашнем каталоге отдельного пользователя и выполняет команды из того файла, который будет найден первым. В Ubuntu по умолчанию существует только файл .profile , и по умолчанию он также включает команды для выполнения содержимого файла .bashrc . Однако вы можете удалить код для запуска .bashrc из файла .profile или создать любой из двух других файлов с помощью нужных вам команд, а затем . профиль не будет запущен.
  • интерактивная (но без входа в систему ) оболочка выполняет команды из /etc/bash.bashrc (это global для всех пользователей), а затем из файла .bashrc в домашнем каталоге отдельного пользователя
  • неинтерактивные оболочки запускались локально (т. е. из программы или набрав bash в окне терминала) не запускайте ни один из этих файлов
  • неинтерактивные оболочки, запущенные из сети (например, в приведенном выше примере, где вы запускаете команда на удаленной машине через ssh) выполнять команды из файла .bashrc только в домашнем каталоге пользователя. Однако по умолчанию файл Ubuntu .bashrc содержит в начале фрагмент кода, который останавливает дальнейшее выполнение, если оболочка не интерактивна.

В некоторых случаях есть еще несколько тонкостей, но в основном он работает как указано выше.

Таким образом, решение зависит от того, хотите ли вы сохранить текущее содержимое по умолчанию файлов .profile и .bashrc или нет.

Если вы хотите сохранить их:

  • для случая 1) вы можете использовать решение Артура (но помните, ваш код будет запускаться не только после входа в систему или после запуска терминала, но также всякий раз, когда вы запускаете другой экземпляр оболочки, например, просто набрав bash в сеансе терминала. Если вы хотите избежать этого, вам следует немного изменить решение: [["$ TERM" == "xterm" *]] && ["$ SHLVL" = "1"] && run-command
  • для случая 2), поместите свой код в .profile
  • для случая 3), просто поместите свой код в .bashrc (не забудьте вставить его под исходным кодом, который завершается в случае, если оболочка не интерактивна). Однако помните, что, как и в случае 1), ваш код будет запускаться всякий раз, когда вы запускаете другой экземпляр оболочки, поэтому, чтобы избежать этого, он должен быть похож на ["$ SHLVL" = "1"] && run-command

Если вы хотите сделать это для всех пользователей, а не только для себя, используйте файлы /etc/bash.bashrc и / etc / profile вместо ~ / .bashrc и ~ / .profile .

Если вы хотите удалить значения по умолчанию:

  • переименуйте .bashrc во что-нибудь другое (чтобы иметь возможность восстановить его позже, если вы передумали)
  • создайте пустой файл .bash_profile или .bash_login а затем:
  • для случая 1), сделайте, как указано выше
  • для случая 2), поместите свой код в .bash_profile или .bash_login (какой бы файл вы ни создали)
  • для случая 3), сначала добавьте код для запуска .bashrc в ваш файл .bash_profile или .bash_login (в зависимости от того, что вы создали), поскольку он нет там по умолчанию. Затем используйте решение Артура - однако, как и в случае 1) выше,при необходимости измените его на форму [[$ - == * "i" *]] && ["$ SHLVL" = "1"] && run-command

Я не рекомендую удалять значения по умолчанию в случае общесистемные файлы ( /etc/bash.bashrc и / etc / profile ):)

1
ответ дан 3 January 2021 в 22:48

Мое предложение.

Сценарий 1: Поместите свою команду в ~ / .bashrc следующим образом: [["$ TERM" == "xterm" *]] && run-command (проверьте, является ли терминал xterm)

Сценарий 2: Поместите свою команду в ~ / .bash_login (не забудьте указать исходный код ~ / .bashrc , если вы все еще хотите его запустить)

Сценарий 3: Поместите свою команду в ~ / .bashrc следующим образом: [[$ - == * "i" *]] && run-command (проверьте, является ли оболочка интерактивной)

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

2
ответ дан 3 January 2021 в 22:48

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

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