«. ~ / .bashrc "не устанавливает переменные, как ожидалось, в вызывающем скрипте

Задний план

Я написал скрипт для установки node через nvm .

вопрос

Команда . $LOCAL_SHELL_CONFIG_FILE . $LOCAL_SHELL_CONFIG_FILE внутри install_latest_stable_node() не запускается и, таким образом, когда он печатает PATH для node и npm ( echo "$(which node)" && echo "$(which npm)" ), он печатает две пустые строки.

После завершения сценария я могу запустить . ~/.bashrc . ~/.bashrc а затем запустите echo "$(which node)" && echo "$(which npm)" который будет отсылать PATH, на этот раз без двух пустых строк.

Зачем?

Код

 #!/bin/bash ask_for_sudo() { # Ask for the administrator password upfront. sudo -v &> /dev/null # Update existing `sudo` time stamp # until this script has finished. # # https://gist.github.com/cowboy/3118588 while true; do sudo -n true sleep 60 kill -0 "$$" || exit done &> /dev/null & } show_spinner() { local -r FRAMES='/-\|' # shellcheck disable=SC2034 local -r NUMBER_OR_FRAMES=${#FRAMES} local -r CMDS="$2" local -r MSG="$3" local -r PID="$1" local i=0 local frameText="" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Note: In order for the Travis CI site to display # things correctly, it needs special treatment, hence, # the "is Travis CI?" checks. if [ "$TRAVIS" != "true" ]; then # Provide more space so that the text hopefully # doesn't reach the bottom line of the terminal window. # # This is a workaround for escape sequences not tracking # the buffer position (accounting for scrolling). # # See also: https://unix.stackexchange.com/a/278888 printf "\n\n\n" tput cuu 3 tput sc fi # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Display spinner while the commands are being executed. while kill -0 "$PID" &>/dev/null; do frameText=" [${FRAMES:i++%NUMBER_OR_FRAMES:1}] $MSG" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Print frame text. if [ "$TRAVIS" != "true" ]; then printf "%s\n" "$frameText" else printf "%s" "$frameText" fi sleep 0.2 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Clear frame text. if [ "$TRAVIS" != "true" ]; then tput rc else printf "\r" fi done } execute() { local -r CMDS="$1" local -r MSG="$2" local -r TMP_FILE="$(mktemp /tmp/XXXXX)" local exitCode=0 local cmdsPID="" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # If the current process is ended, # also end all its subprocesses. set_trap "EXIT" "kill_all_subprocesses" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Execute commands in background eval "$CMDS" \ &> /dev/null \ 2> "$TMP_FILE" & cmdsPID=$! # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Show a spinner if the commands # require more time to complete. show_spinner "$cmdsPID" "$CMDS" "$MSG" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Wait for the commands to no longer be executing # in the background, and then get their exit code. wait "$cmdsPID" &> /dev/null exitCode=$? # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Print output based on what happened. print_result $exitCode "$MSG" if [ $exitCode -ne 0 ]; then print_error_stream < "$TMP_FILE" fi rm -rf "$TMP_FILE" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - return $exitCode } set_trap() { trap -p "$1" | grep "$2" &> /dev/null \ || trap '$2' "$1" } print_error_stream() { while read -r line; do print_error "↳ ERROR: $line" done } print_error() { print_in_red " [✖] $1 $2\n" } print_success() { print_in_green " [✔] $1\n" } print_in_red() { print_in_color "$1" 1 } print_in_green() { print_in_color "$1" 2 } print_in_purple() { print_in_color "$1" 5 } print_in_color() { printf "%b" \ "$(tput setaf "$2" 2> /dev/null)" \ "$1" \ "$(tput sgr0 2> /dev/null)" } print_result() { if [ "$1" -eq 0 ]; then print_success "$2" else print_error "$2" fi return "$1" } fix_dpkg() { declare -a files=("/var/lib/dpkg/lock" "/var/cache/apt/archives/" "/var/cache/apt/archives/lock") for i in "${files[@]}" do # If there is a dpkg lock, then remove it. if [ -e "$i" ]; then sudo rm -rf "$i" &> /dev/null fi done } install_package() { declare -r PACKAGE="$2" declare -r PACKAGE_READABLE_NAME="$1" if ! package_is_installed "$PACKAGE"; then fix_dpkg execute "sudo apt-get install --allow-unauthenticated -qqy $PACKAGE" "$PACKAGE_READABLE_NAME" # suppress output ─┘│ # assume "yes" as the answer to all prompts ──┘ else print_success "$PACKAGE_READABLE_NAME" fi } package_is_installed() { dpkg -s "$1" &> /dev/null } install_nvm() { # Install `nvm` and add the necessary # configs in the local shell config file. # One-liner: # wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | PROFILE=~/.bash.local bash && . ~/.bash.local execute \ "wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | \ PROFILE=$LOCAL_SHELL_CONFIG_FILE NVM_DIR=$NVM_DIRECTORY bash" \ "nvm (install)" } update_nvm() { execute \ "cd $NVM_DIRECTORY \ && git fetch --quiet origin \ && git checkout --quiet \$(git describe --abbrev=0 --tags) \ && . $NVM_DIRECTORY/nvm.sh" \ "nvm (upgrade)" } install_latest_stable_node() { # Install the latest stable version of Node # (this will also set it as the default). # One-liner: #. ~/.bash.local && nvm install node . $LOCAL_SHELL_CONFIG_FILE execute \ "source $LOCAL_SHELL_CONFIG_FILE \ && nvm install node" \ "nvm (install latest Node)" } main() { ask_for_sudo touch "$LOCAL_SHELL_CONFIG_FILE" print_in_purple "\n Dependencies\n\n" install_package "git" "git" print_in_purple "\n nvm\n\n" if [ -d "$NVM_DIRECTORY" ]; then rm -rf "$NVM_DIRECTORY" fi install_nvm update_nvm install_latest_stable_node print_in_purple "\n PATHs\n\n" echo "$(which node)" echo "$(which npm)" } declare -r LOCAL_SHELL_CONFIG_FILE="$HOME/.bashrc" declare -r NVM_DIRECTORY="$HOME/.nvm" main 

  • Как определить, существует ли внешняя команда в сценарии?
  • Как использовать sed для замены строк, в которых есть «\»?
  • поиск и увеличение значений между символом второй тильды и символом третьей тильды в каждой строке файла txt
  • Скрипт для сравнения «размер файла» с «фамилией файла», и если непревзойденное удаление файла
  • Возможно одновременное использование скобок (перестановки) и расширения массива?
  • как удаленно выполнять сценарий оболочки с повышенными привилегиями
  • Могу ли я помещать диапазоны в параметры?
  • Что означает -s и ] в условии if в bash?
  • One Solution collect form web for “«. ~ / .bashrc "не устанавливает переменные, как ожидалось, в вызывающем скрипте”

    Ваш скрипт выдает указанный файл.

    Причина, по которой вы видите две пустые строки вместо ожидаемых имен путей, заключается в том, что сценарий $LOCAL_SHELL_CONFIG_FILE из вашей функции « execute() », которая выполняет команды в фоновом режиме (то есть в подоболочке).

    Подголовки не могут изменять среду родительской оболочки.

    Linux и Unix - лучшая ОС в мире.