Возникла странная проблема с SCP:
$ scp [email protected]:~/test.txt ./
Password:
\033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H
Пароль принимается нормально, но получаю эту странную штуку \033H. И файл не передается. Есть у кого-нибудь идеи?
решение1
Исправление этого обычно простое. Обычно вы можете проверить .bashrc
, найти строку или несколько строк вверху, которые вызывают проблему, и переместить или удалить их. Самое сложное — убедить людей, что эта проблема действительно существует. Подробности ниже, но если вы просто хотитеисправитьэтой проблемы, то вам нужно будет использовать только этот более короткий первый раздел.
Проблема и как ее решить
Это происходит, когда .bashrc
в домашнем каталоге пользователя на удаленной машине содержатся команды, которые производят выводи которые работают даже в неинтерактивных оболочках.Реже это также может произойти, если systemwide /etc/bash.bashrc
содержит такие команды. Конкретный вывод зависит от того, что его производит. Но сочетание получения неожиданного вывода инетиметь какие-либо переводы успешными или даже начатымиоченьявно указывает на эту причину (особенно когда сервер представляет собой систему Debian или Ubuntu). scp
используетстандартный ввод и выводдля отправки и получения данных, и если через них передаются несвязанные данные, то они не могут передавать файлы.
Если вы думаете,«Это невозможно, .bashrc
это только для интерактивных оболочек!»или иным образом заинтересованы в подробном объяснении того, почему это происходит, см. второй раздел ниже.
Эта проблема не нарушает нормальный SSHing. Поэтому, если система настроена так, чтобы разрешить вам ssh
успешно войти в интерактивную оболочку входа, вы можете сделать это, открыть .bashrc
домашний каталог удаленного пользователя и либо удалить, либо закомментировать (с помощью #
) проблемную команду или команды, если они вам не нужны. Или, если они вам нужны, переместите их под другую команду, которая прерывает работу, когда оболочка неинтерактивна. Такая команда может уже присутствовать.В Ubuntu и некоторых других дистрибутивах файлы пользователей .bashrc
и всей системы /etc/bash.bashrc
обычно начинаются с таких проверок.
Файл по умолчанию .bashrc
в Ubuntu, скопированный из/etc/skel
при создании учетной записи пользователя, содержит этот код для проверки того, является ли запущенная оболочка интерактивной, и для предотвращения запуска любых дальнейших команд в файле, если это такнет:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Другой распространенный метод, который некоторые люди используют в своих .bashrc
файлах и который в настоящее время применяется в общесистемном /etc/bash.bashrc
файле для всех пользователей, это:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
Если файлы были заменены или изменены по сравнению с файлами по умолчанию, то вы можете увидеть использование любого из этих методов в любом из файлов. Существуют и другие возможные способы проверки интерактивной работы, но они не распространены. Если пользователь написал свой собственный .bashrc
файл с нуля или перенес его из другой операционной системы, которая не является Debian, Ubuntu или другой производной Debian, то, скорее всего, у него вообще нет такого кода. Но если он вам нужен, вы все равно можете его добавить.
Любая команда, которая создает вывод и появляется в .bashrc
или/etc/bash.bashrc
, если только она не отображаетсяпослеКод, подобный показанному выше, приведет к отправке непредвиденных данных в начале сеанса scp
и не позволит scp
передавать файлы.
Если вы недавно сами отредактировали один из этих файлов, добавив команду в начало, то вам должно быть легко выяснить конкретное изменение, вызвавшее проблему. Даже если нет, описание выше может дать вам достаточно информации.
Однако я рекомендую вам отредактировать свой вопрос с полными подробностями, включая содержимое этих файлов, независимо от того, сможете ли вы решить проблему на основе объяснения выше. Помните, чтоэто файлы на удаленном сервере, а не на клиентской машине. Это должно помочь другим, кто найдет ваш вопрос, понять проблему, а также дать возможность дать более конкретный совет, если это необходимо.
Я считаю, что вероятность того, что ваша проблема вызвана чем-то совершенно другим, очень мала, но в любом случае дополнительная информация должна позволить узнать наверняка.Другие людичем автор этого вопроса, у которого есть похожие проблемы и которому нужна помощь в их решении, конечно, долженнетотредактировать этот вопрос, но следует опубликовать свой собственный вопрос.
Почему возникает проблема
Люди часто говорят, что .bashrc
это касается только интерактивных оболочек, но это заблуждение или, в лучшем случае, сильное упрощение. bash
запускает команды из ~/.bashrc
и /etc/bash.basrhc
когда:
- оболочка интерактивна,или
- другой скрипт запуска, например
/etc/profile
или~/.profile
источники это,но и - когда
bash
не работает ни в интерактивном режиме, ни как оболочка входа в систему, но определяет, что она, вероятно, запускается как начальная оболочкав удаленном соединении.
Что bash
принимает в качестве достаточного доказательства, что это удаленная оболочка, и, таким образом, возникает ли на практике этот эффект с SSH или нет, зависит в основном откак он был скомпилирован, что отличается в разных операционных системах, и во вторую очередь по версии bash
иверсияsshd
который используется.
В текущих системах Debian и Ubuntu при bash
запуске в качестве неинтерактивной оболочки без входа в систему проверяется, SSH_CLIENT
установлена ли переменная окружения и не является ли она пустой. (Он также проверяет и другие параметры, но для SSH в текущих системах Ubuntu они ничего не показывают.) Если это так, и SHLVL
переменная окружения установлена на значение меньше 2, что указывает на то, что это сеансисходныйshell-- bash
запускает команды в /etc/bash.bashrc
и ~/.bashrc
.
Чтобы быстро проверить это, не изменяя файлы конфигурации, читатели могутвручную передайте эти переменные в bash -c ''
среду и отследите, что она читает, или изучить run_startup_files
функцию вshell.c
(которая в этой версии начинается со строки 1022).
Неинтерактивная bash
оболочка без входа в систему — это то, что вы получаете, когда запускаете скрипт с помощью bash
, либо выполняя его после установки необходимых разрешений и предоставления емусоответствующая строка хэшбэнгаили запустив явно. Это также то, что вы получаете, когда делаете запуск однострочника с опцией, например:bash your-script
bash
-c
bash -c 'echo hello world'
Как и следовало ожидать, оболочка, которую вы получаете, когда выавторизоватьсячерез SSH дляинтерактивная сессияэто интерактивная оболочка входа. Вот что вы получите, если выполните команду вроде этой (при условии, что она будет успешной):
ssh [email protected]
Но вот тут-то и появляется неинтуитивная часть: оболочка, которую вы получаете, когда выавторизоватьсячерез SSH длянеинтерактивныйсессия не является интерактивнойне-логинshell. Вот что вы получите, выполнив одну команду через SSH:
ssh [email protected] command args...
То есть запуск одной команды через SSH выполняется bash
как та же оболочка — неинтерактивная, не требующая входа в систему, — что и при запуске одной команды локально (или в рамках уже установленного удаленного сеанса) с использованием bash -c
.
Как и ssh
в целом, scp
запускает оболочку на удаленной машине от имени удаленного пользователя. Это все еще то, что они настроили в качестве своей оболочки, т. е. оболочка, указанная в записи пользователя в /etc/passwd
или выводе getent passwd
(которая также устанавливается как значение $SHELL
переменной окружения при входе в систему). Если они не изменили ее, запустив chsh
, это оболочка пользователя по умолчанию, которая в Ubuntu — bash
.
Вот почему такие команды, какэтоттакже запустите неинтерактивную bash
оболочку без входа на удаленном сервере:
scp [email protected]:~/test.txt ./
Если они не защищены кодом, останавливающим, если оболочка неинтерактивна, команды в .bashrc
или /etc/bash.bashrc
запускаются такой оболочкой. Если они производят вывод — намеренно или ненамеренно — тоscp
не сможет копировать файлы.