sftp를 깨지 않고 .bashrc 사용


20

내 문제는 ssh 셸에 로그인 할 때마다 몇 가지 변수를 설정하고 몇 줄을 출력해야하며 동시에 Filezilla를 통해 sftp를 사용하여 파일을 tarnsfer 할 수 있어야한다는 것입니다.

이제 http://www.openssh.org/faq.html 의 openssh FAQ에 따라 시작 스크립트가 모든 종류의 출력을 출력하면 sftp와 충돌합니다. 따라서 무한정 지연되거나 "종료 코드 128의 서버에 의해 연결이 닫힘"으로 오류가 발생합니다.

.bashrc를 .bash_profile으로 옮기거나 .bashrc에서 다음 코드를 사용하는 것과 같은 솔루션을 시도했습니다.

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

과:

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

그러나 아무것도 작동하지 않습니다. 내 쉘 터미널은 bash이며 filezilla를 사용하여 sftp에 연결합니다.

답변:


23

대신 이것을 시도하십시오

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

17

마이크의 대답은 아마 효과가있을 것입니다. 그러나 자세한 내용을 넣을 시작 파일을 신중하게 선택 하여이 작업을 수행 할 수 있음을 지적하는 것이 좋습니다. bash 매뉴얼 페이지에서 :

bash가 대화식 로그인 쉘 또는 --login 옵션을 사용하는 비 대화식 쉘로 호출되면 파일이 존재하는 경우 먼저 / etc / profile 파일에서 명령을 읽고 실행합니다. 해당 파일을 읽은 후 ~ / .bash_profile, ~ / .bash_login 및 ~ / .profile을 순서대로 찾고 존재하고 읽을 수있는 첫 번째 파일에서 명령을 읽고 실행합니다. 이 동작을 막기 위해 쉘을 시작할 때 --noprofile 옵션을 사용할 수 있습니다.

로그인 쉘이 아닌 대화식 쉘이 시작될 때 bash는 ~ / .bashrc에서 해당 파일이있는 경우 명령을 읽고 실행합니다. --norc 옵션을 사용하여이를 방지 할 수 있습니다. --rcfile 파일 옵션은 bash가 ~ / .bashrc 대신 파일에서 명령을 읽고 실행하도록합니다.

sftp / scp 도구는 대화식 비 로그인 셸을 시작하므로 .bashrc가 제공됩니다. 많은 배포판이 .bash_profile에서 .bashrc를 소스로 또는 그 반대로 소스를 혼동하므로 혼동 될 수 있습니다. 로그인 환경의 청결도를 테스트하는 좋은 방법은 scp / sftp가 연결하는 것과 동일한 방법으로 시뮬레이션하는 명령을 사용하는 것입니다. 예를 들어 : ssh myhost /bin/truescp / 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 등을 중단시킵니다. 두 번째 버전은 잘 작동합니다.


"sftp / scp 도구는 대화식 비 로그인 셸을 시작 합니다 "라는 의견에 동의하지 않습니다 . 셸과 실제로 상호 작용할 수는 없습니다 . 그러나 왜 또는의 .bashrc소스가 될지 이해하지 못합니다 . scpssh host command
pynexj

2
"대화 형"이라는 용어는 주관적이지 않습니다. bash가 시작 모드 중 하나를 설명하기 위해 사용하는 용어입니다. sftp / scp가 "대화식 비 로그인 쉘"을 시작한다는 것은 사실입니다. 이 경우 .bashrc 소싱이 적절한 지 여부에 대해 개발자와 자유롭게 논의하십시오. 그게 무슨 일인지 말해 줄뿐입니다.
Insyte

2
Bash에 의해 호출 scp되거나 ssh host command실제로 비대화 형 입니다. 난 그냥 bash는 설명서에이 발견 : "배쉬 시도를 결정하기 위해 이 네트워크 연결에 연결된 표준 입력으로 실행되고있을 때 일반적으로 원격 쉘 데몬에 의해 실행될 때와 같은, 은 rshd, 또는 보안 쉘 데몬 SSHD . 배쉬 판단하는 경우 "이러한 방식으로 실행되고 있으며 ~/.bashrc파일이 존재하고 읽을 수있는 경우 명령을 읽고 실행합니다 ." 여기 흥미로운 역사가 있습니다.
pynexj

1
또한 섹션 참조 원격 비 로그인 비 대화 형 쉘 에서 이 위키 페이지 .
pynexj

3

csh를 사용하는 경우 :

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

그리고 그것이 bash라면 :

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

또는 대안으로 bash 정규 표현식을 사용하십시오.

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

이 줄은 다시 출력하거나 반향하는 줄 앞에 있어야합니다.


안녕하세요, 코드를 설명해 주시겠습니까? 그거 알아? 이전 명령의 리턴 레벨입니다. 그래도 $? prompt와 $-를 이해하지 못합니다. 또는 csh가 구체적입니까?
Joel G Mathew

1
@Droidzone : $?varin 은 정의되어 csh있으면 1을, var그렇지 않으면 0을 반환합니다. $-bash겠습니까가이 i값에 문자를 쉘은 상호 작용하는 경우.
pynexj

쉘 옵션의 특수 변수 인 $-를 설명하기 위해 답변을 업데이트해야합니다. 참조 stackoverflow.com/questions/5163144/...
maninvan

1

Mike의 솔루션도 저에게 효과적이었습니다. 그러나 기본 쉘은 TCSH이므로 다음과 같이 수정 사항을 약간 편집해야했습니다 (. tcshrc에서).

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

모든 사람의 이익을 위해 나누겠다고 생각했습니다.


0

나는 여기에 언급 된 다른 솔루션 중 일부를 더 좋아하지만, 누군가가 정보를 도움이되는 경우를 대비하여 시작 스크립트의 에코 명령으로 인해 SFTP 연결 끊기를 방지하기 위해 현재 bash 및 csh VM에서 사용하는 솔루션을 버리고 있다고 생각했습니다. .

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"

그것은 약간의 무차별적인 힘이지만 작동합니다.


위의 [ "$ SSH_TTY"] 코드를 사용해 보니 퍼티와 같은 간단한 클라이언트 프로그램에서만 작동한다는 것을 알았습니다. NoMachine을 사용하면 출력이 제공되지 않습니다. 이 때문에 위의 코드에 "xterm-256color"를 포함시켜야했습니다.
Bob Noonan

흥미롭게도 "if ($? SSH_TTY)"를 사용하면 csh VM에서도 작동하지 않았습니다. 확인했으며 SSH_TTY 환경 변수가 정의되어 있지 않습니다. 따라서 위의 코드는 비슷한 상황을 가진 다른 사람들에게 도움이 될 수 있습니다.
Bob Noonan

0

내 (기본) .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또는 다른 물건을 표준 출력에 인쇄, 당신은 오류의 종류를 얻을 수 있습니다 :

  • SFTP : Received message too long 168435779
  • SCP : protocol error: unexpected <newline>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.