Назад | Перейти на главную страницу

Используйте .bashrc, не нарушая sftp

Моя проблема в том, что мне нужно установить несколько переменных и выводить несколько строк каждый раз, когда я вхожу в оболочку ssh, и в то же время я должен иметь возможность использовать sftp для переноса файлов через Filezilla.

Теперь, согласно FAQ по openssh на http://www.openssh.org/faq.html, если ваши сценарии запуска повторяют какой-либо вывод, это неправильно с sftp. Таким образом, он либо задерживается на неопределенный срок, либо выдает ошибку с сообщением «Соединение закрыто сервером с кодом выхода 128».

Я пробовал такие решения, как перемещение .bashrc в .bash_profile или использование следующего кода в .bashrc:

if [ "$TERM" != "dumb" ]
then
   source .bashc_real
fi

И:

if [ "$TERM" = "xterm" ]
then
   source .bashc_real
fi

Однако ничего не работает. Мой терминал оболочки - bash, и я подключаюсь к sftp с помощью filezilla.

Попробуйте сделать это вместо этого

if [ "$SSH_TTY" ]
then
   source .bashc_real
fi

Ответ Майка, вероятно, сработает. Но стоит отметить, что вы можете выполнить это, тщательно выбрав, в какие файлы запуска нужно добавить подробный материал. На странице руководства bash:

Когда bash вызывается как интерактивная оболочка входа или как неинтерактивная оболочка с параметром --login, она сначала считывает и выполняет команды из файла / etc / profile, если этот файл существует. После чтения этого файла он ищет ~ / .bash_profile, ~ / .bash_login и ~ / .profile в указанном порядке, а также читает и выполняет команды из первого существующего и доступного для чтения файла. Параметр --noprofile может использоваться при запуске оболочки, чтобы запретить такое поведение.

При запуске интерактивной оболочки, которая не является оболочкой входа в систему, bash читает и выполняет команды из ~ / .bashrc, если этот файл существует. Это можно запретить с помощью параметра --norc. Параметр --rcfile file заставит bash читать и выполнять команды из файла вместо ~ / .bashrc.

Инструменты sftp / scp запускают интерактивную оболочку без входа в систему, поэтому будет получен .bashrc. Многие дистрибутивы исходят из .bashrc из .bash_profile или наоборот, так что это может сбивать с толку. Хороший трюк для проверки чистоты вашей среды входа в систему - это использовать ssh с помощью команды, которая имитирует тот же способ подключения scp / sftp. Например: ssh myhost /bin/true покажет вам, что именно scp / sftp видит при подключении.

Простая демонстрация:

insyte@mazer:~$ echo "echo Hello from .profile" > .profile
insyte@mazer:~$ echo "echo Hello from .bashrc" > .bashrc

sazerac:~ insyte$ ssh mazer /bin/true
Hello from .bashrc
sazerac:~ insyte$

insyte@mazer:~$ rm .bashrc

sazerac:~ insyte$ ssh mazer /bin/true
sazerac:~ insyte$

Первый тест вызовет сбой scp / sftp / rsync и т. Д. Вторая версия будет работать нормально.

Если вы используете csh:

if ($?prompt)
  ... interactive stuff ...

А если это bash:

if [[ $- == *i* ]]; then
  ... interactive stuff ...
fi

или, альтернативно, используя регулярные выражения bash:

if [[ $- =~ i ]]; then
  ... interactive stuff ...
fi

Эти строки должны предшествовать строкам, в которых вы что-то выводите / повторяете эхо.

Решение Майка сработало и для меня. Но поскольку моя оболочка по умолчанию - TCSH, мне пришлось немного отредактировать исправление следующим образом (в .tcshrc):

if ( $?SSH_TTY ) then
    exec /bin/bash
endif

Просто подумал, что поделюсь для всеобщего блага.

Мне больше нравятся некоторые другие решения, упомянутые здесь, но я подумал, что выброшу решение, которое я сейчас использую на своих виртуальных машинах bash и csh, чтобы предотвратить отключение SFTP из-за эхо-команд в моих сценариях запуска, на всякий случай, если кто-то сочтет эту информацию полезной .

В BASH:

if [ $TERM == "xterm" ] || [ $TERM == "xterm-256color" ]; then
  echo "Xterm display identified: echo enabled"
  echo_disable="0"
else
  echo_disable="1"
fi

# Use the following for all subsequent echo commands
if [ $echo_disable == 0 ]; then
 echo "Safe to display on Xterm"
fi

В csh:

if ($TERM == "xterm") then
  echo "Xterm display identified: echo enabled"
  set echo_disable = "0"
else
  set echo_disable = "1"
endif

# Use the following for all subsequent echo commands
if !( "$echo_disable" ) echo "Safe to display on Xterm"

Это немного грубая сила, но она работает.

Вот первые строчки моего (по умолчанию) .bashrc файл:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

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

Проверка интерактивного сеанса позволяет избежать проблем с SCP, SFTP или ssh remote-host command Режим.

Без этого, если ваш файл .bashrc использует echo или какой-то другой материал, печатаемый на stdout, вы можете получить такие ошибки:

  • SFTP: Received message too long 168435779
  • SCP: protocol error: unexpected <newline>