Как автоматически запускать «исходный .bashrc» после его редактирования и сохранения?

Что происходит, так это то, что ваш двоичный файл содержит управляющую последовательность для установки заголовка окна (в xterms это ]2, я не знаю, отличается ли она в putty).

3
04.06.2017, 01:16
4 ответа

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

  1. открывает ваш редактор на . bashrc
  2. источники .bashrc

такие как:

vibashrc() { vi $HOME/.bashrc; source $HOME/.bashrc; }

У этого есть некоторые недостатки:

  • это потребует, чтобы вы не забывали набирать vibashrc каждый раз, когда вы хотите получить источник
  • это произойдет только в вашем текущем окне bash
  • он попытается получить исходный файл .bashrc независимо от того, внесли ли вы какие-либо изменения в него

Другим вариантом может быть подключение PROMPT_COMMAND bash к функциям source . bashrc в любой/всех оболочках bash всякий раз, когда он видит, что файл .bashrc был обновлен (и непосредственно перед отображением следующего приглашения).

Вы должны добавить следующий код в ваш файл .bashrc (или расширить с его помощью любую существующую функциональность PROMPT_COMMAND):

prompt_command() {
  # initialize the timestamp, if it isn't already
  _bashrc_timestamp=${_bashrc_timestamp:-$(stat -c %Y "$HOME/.bashrc")}
  # if it's been modified, test and load it
  if [[ $(stat -c %Y "$HOME/.bashrc") -gt $_bashrc_timestamp ]]
  then
    # only load it if `-n` succeeds ...
    if $BASH -n "$HOME/.bashrc" >& /dev/null
    then
        source "$HOME/.bashrc"
    else
        printf "Error in $HOME/.bashrc; not sourcing it\n" >&2
    fi
    # ... but update the timestamp regardless
    _bashrc_timestamp=$(stat -c %Y "$HOME/.bashrc")
  fi
}

PROMPT_COMMAND='prompt_command'

Затем, при следующем входе в систему, bash будет загружать эту функцию и ловушку приглашения, и каждый раз собирается отобразить приглашение, он проверит, был ли обновлен $HOME/.bashrc. Если это так, он запустит быструю проверку на наличие синтаксических ошибок (опция set -n ), и, если файл чист, отобразит его.

Он обновляет внутреннюю переменную метки времени независимо от проверки синтаксиса, чтобы не пытаться загрузить ее до тех пор, пока файл не будет снова сохранен/обновлен.

5
27.01.2020, 21:18

Может быть, функция оболочки, например:

nano .bashrc ; source .bashrc

Или просто запустить эту команду?

0
27.01.2020, 21:18

Вы можете указать bash перечитать .bashrc при получении сигнала. Поместите следующую строку в ваш .bashrc:

trap '. ~/.bashrc' USR1

Затем, всякий раз, когда вы редактируете свой .bashrc, отправьте интерактивные экземпляры bash сигнала. (Не отправляйте его сценариям! Это убьет их.) Не существует надежного способа сделать это, поэтому существует некоторый риск уничтожения несвязанного процесса. Следующий фрагмент bash подходит ближе — он ищет bash, запущенный без аргументов и со стандартным вводом, поступающим с терминала (или любого другого символьного устройства, но на практике это не проблема):

ps -u "$(id -u)" -o pid= -o args= | while read -r pid args; do
  if [[ $args = bash || $args = */bin/bash ]]; then
    stdin="$(lsof -p"$pid" | sed -n '/^f0$/ { n; s/^n//p; q; }')"
    if [ -c "$stdin" ]; then
      kill -USR1 "$pid"
    fi
  fi
done

В качестве альтернативы, чтобы избежать ненадежности signal, вы можете заставить bash перечитать .bashrc из-за его собственного нарушения. Недостатком этого подхода является то, что он будет перечитывать файл, даже если вы только что сохранили его с синтаксической или логической ошибкой (например, бесконечный цикл). Содержимое переменной PROMPT_COMMAND выполняется каждый раз, когда bash отображает подсказку, поэтому поместите это в свой .bashrc:

reread_bashrc () {
  if ((SECONDS > bashrc_last_read)); then
    . ~/.bashrc
    bashrc_last_read=$SECONDS
  fi
}
bashrc_last_read=$SECONDS
PROMPT_COMMAND="$PROMPT_COMMAND
reread_bashrc"

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

0
27.01.2020, 21:18
edit_and_source () {
    local tmpfile=$(mktemp)
    trap 'rm -f "$tmpfile"' EXIT RETURN

    cp -p "$1" "$tmpfile"

    while true; do
        command "${EDITOR:-vi}" "$tmpfile"
        bash -n "$tmpfile" && break

        echo 'There were errors. Re-edit?' >&2
        read -p 'Yes/No/Force: '

        case "$REPLY" in
            [Yy]*) continue ;;
            [Ff]*) break    ;;
            *)     return   ;;
        esac
    done

    mv "$tmpfile" "$1"
}

Эта функция bash позволит вам редактировать указанный файл с помощью редактора, определенного в $EDITOR (или vi, если он не установлен), и затем будет его источником.

$ edit_and_source ~/.bashrc

Если файл содержит ошибки после редактирования, функция спросит вас, хотите ли вы отредактировать его снова:

/tmp/tmp.ETdo10orcg: line 4: syntax error near unexpected token `('
/tmp/tmp.ETdo10orcg: line 4: ` nt hn thnt();0'
There were errors. Re-edit?
Yes/No/Force: n

Если вы ответите «нет», исходный файл останется нетронутым. Ответ «force» (или любое слово, начинающееся с «f») принудительно установит файл с ошибками.

0
27.01.2020, 21:18

Теги

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