LINUX.ORG.RU

Поменять что-то в bashrc и других скриптах, чтобы заработало scp

 


2

2

Народ, кто хорошо bash знает, гляньте на мои стартовые скрипты и подскажите, что изменить нужно:

~/.bash_profile:

if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

/etc/profile:

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

if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`id -u`
        UID=`id -ru`
    fi
    USER="`id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi

if [ "$EUID" = "0" ]; then
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
fi

HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=20000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
export DISPLAY=":0"
export WINEPREFIX="/opt/wine"

if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
    umask 002
else
    umask 022
fi

for i in /etc/profile.d/*.sh ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then 
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge

~/.bashrc:

if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

/etc/bashrc:

if [ "$PS1" ]; then
  if [ -z "$PROMPT_COMMAND" ]; then
    case $TERM in
    xterm*|vte*)
      if [ -e /etc/sysconfig/bash-prompt-xterm ]; then
          PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm
      elif [ "${VTE_VERSION:-0}" -ge 3405 ]; then
          PROMPT_COMMAND="__vte_prompt_command"
      else
          PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
      fi
      ;;
    screen*)
      if [ -e /etc/sysconfig/bash-prompt-screen ]; then
          PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen
      else
          PROMPT_COMMAND='printf "\033k%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
      fi
      ;;
    *)
      [ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default
      ;;
    esac
  fi
  shopt -s histappend
  history -a
  shopt -s checkwinsize
  [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "
fi

if ! shopt -q login_shell ; then # We're not a login shell
    pathmunge () {
        case ":${PATH}:" in
            *:"$1":*)
                ;;
            *)
                if [ "$2" = "after" ] ; then
                    PATH=$PATH:$1
                else
                    PATH=$1:$PATH
                fi
        esac
    }

    if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
       umask 002
    else
       umask 022
    fi

    SHELL=/bin/bash
    for i in /etc/profile.d/*.sh; do
        if [ -r "$i" ]; then
            if [ "$PS1" ]; then
                . "$i"
            else
                . "$i" >/dev/null
            fi
        fi
    done

    unset i
    unset -f pathmunge
fi
if [ -z $STY ]; then
   exec /usr/bin/screen -d -RR
fi


Что не устраивает: когда я пытаюсь скопировать на компьютер файлы с помощью scp, то получаю ошибку:
Fatal: Received unexpected end-of-file from server
Однако ошибка изчезает, если я закоментирую строки:
if [ -z $STY ]; then
   exec /usr/bin/screen -d -RR
fi
Это мне не подходит, поскольку я хочу продолжать пользоваться screen. Мне нужно как-то сделать, чтобы не производилось выполнение /etc/bashrc при подключении по scp. Поскольку у меня прописан вызов ~/.bashrc из ~/.bash_profile получается что /etc/bashrc выполняется как при запуске bash как в начальном интерактивном режиме, так и в неначальном интерактивном. Но ведь при использовании scp происходит просто копирование файла, пользователь к терминалу не подключён - значит режим неинтерактивный и ~/.bash_profile выполняться не должен. Рассейте мои заблуждения и дайте совет.

★★★★★

Шелл может быть запущен как интерактивный/неинтерактивный логин/нелогин в любых сочетаниях. Т.е. эти его качества ортогональны. ~/.bash_profile выполняется при запуске логин-шелла (а не интерактивного, как вы считаете).

Поэтому определять интерактивность шелла нужно вручную. Например так (в .bash_profile):

# process .bashrc in interactive shell only
if [[ $- =~ i ]]; then
  . ~/.bashrc
fi

Но этого может быть недостаточно для решения вашей проблемы, если bash собран с опцией SSH_SOURCE_BASHRC. Т.к. в этом случае bash будучи запущенным через SSH будет выполнять ~/.bashrc (а не .bash_profile). На этот случай у меня ~/.bashrc начинается такой строчкой:

# Thank you, dear maintainers, for building bash with SSH_SOURCE_BASHRC
[[ ! $- =~ i ]] && return
unterwulf ()
Ответ на: комментарий от unterwulf

Спасибо, что дал направление куда копать. Дошло до меня наконец-то, что нужно проверять шелл на интерактивность условием:

[[ ! $- =~ i ]]
И вроде нашёл, что проверку интерактивность можно делать и другим условием:
[ -z $PS1 ]


Непонятным осталось то, с какой целью мейнтейнеры поместили следующие конструкции одновременно и в /etc/profile и в /etc/bashrc:
    if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
       umask 002
    else
       umask 022
    fi
и
    for i in /etc/profile.d/*.sh; do
        if [ -r "$i" ]; then
            if [ "$PS1" ]; then
                . "$i"
            else
                . "$i" >/dev/null
            fi
        fi
    done
Если я их оставлю только в /etc/profile у меня ничего не развалится?

sunny1983 ★★★★★ ()
Ответ на: комментарий от sunny1983

Непонятным осталось то, с какой целью мейнтейнеры поместили следующие конструкции одновременно и в /etc/profile и в /etc/bashrc

А что именно вас смущает? Эти файлы выполняются строго поодиночке при разных обстоятельствах, почему бы им не содержать одинаковые действия?

В организации стартовых скриптов есть известная доля свободы, поэтому каждый делает как ему удобно: кто-то делает bash_profile и bashrc независимыми, кто-то дёргает bashrc из bash_profile. Зачем в вашем дистрибутиве сделано именно так, нужно спрашивать мэйнтейнеров вашего дистрибутива или, если есть, читать комментарии. В Дебиане, например, сделано иначе.

Я никогда не включаю в свои стартовые скрипты вызов /etc/bash.bashrc и /etc/profile поэтому и теоретизировать про них не буду.

Если я их оставлю только в /etc/profile у меня ничего не развалится?

Это зависит. Я бы их не трогал, если дело касается только одного пользователя.

unterwulf ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.