.bashrc에서 에코 할 때 SCP가 작동하지 않습니까?


81

Fedora에 두 명의 사용자가 있습니다.

  1. 와니
  2. 뿌리 (아주 분명!)

사용자 Wani의 .bashrc 내용은 다음과 같습니다.

# .bashrc
echo "Hello"
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# User specific aliases and functions

이제 루트에 로그인 한 후 다음 명령을 입력합니다.

[root@Dell Wani]# touch try.txt
[root@Dell Wani]# service sshd start
[root@Dell Wani]# scp try.txt Wani@localhost:~/
Wani@localhost's password: 
Hello
[root@Dell Wani]# 

이제 Wani에 로그인하고 다음을 입력합니다.

[Wani@Dell ~]$ cat try.txt
cat: try.txt: No such file or directory
[Wani@Dell ~]$ 

이제 다시 루트에 로그인하고 다음과 같은 명령을 입력합니다 -v.

[root@Dell Wani]# scp -v morph.log Wani@localhost:
Executing: program /usr/bin/ssh host localhost, user Wani, command scp -v -t -- .
OpenSSH_5.6p1, OpenSSL 1.0.0j-fips 10 May 2012
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to localhost [127.0.0.1] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /root/.ssh/id_rsa type -1
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.6
debug1: match: OpenSSH_5.6 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.6
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'localhost' is known and matches the RSA host key.
debug1: Found key in /root/.ssh/known_hosts:2
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-     with-mic,password
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure.  Minor code may provide more information
Credentials cache file '/tmp/krb5cc_0' not found

debug1: Unspecified GSS failure.  Minor code may provide more information
Credentials cache file '/tmp/krb5cc_0' not found

debug1: Unspecified GSS failure.  Minor code may provide more information


debug1: Unspecified GSS failure.  Minor code may provide more information


debug1: Next authentication method: publickey
debug1: Trying private key: /root/.ssh/id_rsa
debug1: Trying private key: /root/.ssh/id_dsa
debug1: Next authentication method: password
Wani@localhost's password: 
debug1: Authentication succeeded (password).
Authenticated to localhost ([127.0.0.1]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env XMODIFIERS = @im=none
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending command: scp -v -t -- .
Hello
[root@Dell Wani]# debug1: client_input_channel_req: channel 0 rtype exit-status      reply      0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 1664, received 1976 bytes, in 0.1 seconds
Bytes per second: sent 22961.5, received 27266.8
debug1: Exit status 0

(그리고 Enter 키를 누른 후)

[root@Dell Wani]# 

누구든지 여기서 정확히 무슨 일이 일어 났는지 밝힐 수 있습니까? 왜 파일이 ​​루트에서 Wani로 복사되지 않았습니까?


어때 cp? 합니까의 cp try.txt ~Wani/작업?
nneonneo

실제로 대화 형 명령이나 가짜 출력이 .bashrc일부 비대화 형 시나리오를 망칠 수 있습니다. 코드를 조건부로 만들어보십시오 case $- in *i*.
tripleee

@nneonneo : 작동합니다. 사실 두 명의 사용자가 다른 컴퓨터에 있어도 파일이 복사되지 않습니다!
Nehal J Wani

1
내가 본 모든 게시물은 왜이 문제가 다양한 bashrc 파일 등에 존재하는지 설명합니다. 그러나 SCP / STFP가 시스템에 대해 소유하지 않고 시작 스크립트를 변경할 수없는 경우 솔루션은 무엇입니까 ???
ChuckB

결국 모든 에코를 stderr로 리디렉션했습니다. ... 작동하지만
안드레아스

답변:


78

echoin a .bashrc를 사용 하면 stdin / stdout 채널을 통해 프로토콜 데이터를 볼 수 있으므로 중단 scp됩니다 scp. 이 문제에 대한 자세한 내용은 https://bugzilla.redhat.com/show_bug.cgi?id=20527 을 참조 하십시오 .

사용 가능한 몇 가지 해결 방법이 있습니다.

  • '대화 형'플래그의 조건 (예 : case $- in *i*tripleee에서 제안한대로)
  • tty유틸리티를 사용하여 대화 형 셸 (예 : if tty > /dev/null또는 if [ -t 0 ]) 을 감지합니다.
  • 값 확인 $SSH_TTY

나는 당신이 당신을 위해 일하는 것을 사용해야한다고 생각합니다. 불행히도 가장 좋은 (가장 휴대 가능 / 가장 안정적인) 옵션이 무엇인지 모르겠습니다.


6
"case"명령을 명확히하기 위해 다음과 같습니다.case $- in *i*) echo This is safe since the shell is interactive; esac
mlathe

shopt또한 대안
vesperto

1
내 호스트는 항상 SSH를 통해 액세스되므로 SSH_TTY가 항상 설정됩니다. -t 0조건을 사용하면 잘 작동했습니다. 이제 bashrc 전체에서 다음 기능을 사용합니다. safe_echo() { if [[ -t 0 ]];then echo -e "$*" fi }
Sandip Bhattacharya

if [[ "$SSH_TTY" == */dev/pts/* ]] ; thenstdout에 인쇄되는 내용을 넣으면 scp가 정상적으로 작동합니다.
BeatingBytes

@BeatingBytes & @Sandip Bhattacharya [[는 휴대용이 아니며 posix라고 생각하지도 않습니다. dash쉘 에서 이것을 시도하십시오 : if [[ 0 = 0 ]]; then echo x; else echo y; fi. 당신은 dash: 3: [[: not found.
타원형 뷰

19

nneonneo의 옵션에 추가하려면 다음과 같이 대화 형 플래그로 조건을 지정할 수도 있습니다.

if [[ $- =~ "i" ]]

bash에서 가장 명확한 방법이라고 생각합니다.


[[휴대용이 아니며 posix라고 생각하지도 않습니다. dash쉘 에서 이것을 시도하십시오 : if [[ 0 = 0 ]]; then echo x; else echo y; fi. 당신은 dash: 3: [[: not found.
타원형 뷰


11

기본 우분투는 .bashrc이미 문제를 돌봐 다음 코드를 포함 :

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

4
더 짧게 :[[ $- != *i* ]] && return
phil294

2
답변에 제공된 양식은 POSIX와 호환됩니다. 귀하의 의견에서 제공하는 것은 [[기능 사용으로 인해 POSIX가 아닙니다 . bashrc 파일에는 그리 문제가되지 않지만 다른 컨텍스트 / 쉘에서 사용할 수 있기를 원할 수 있습니다.
Totor

4

에서는 .bashrc대신 STDERR을 출력으로 사용하십시오.

echo "# Important Notice" >&2

업데이트 : 사용하지 마십시오! 최근 echo에 .NET의 STDERR 로 인해 (닫힌 소스) 도구가 실패하는 문제가 발생했습니다 .bashrc. 도구 (사용 rcp)는 STDOUT 또는 STDERR 모두에서 출력이 전혀 예상되지 않았습니다. 그리고 메아리가 들렸을 때 멈췄습니다. 교훈 : 사람과 기계 (스크립트)에 대해 별도의 계정을 만들거나 .bashrc.


"인간과 기계에 대해 별도의 계정을 만드십시오"는 과소 평가됩니다.
Andreas

1

대화 형 셸을 테스트하는 가장 이식 가능한 방법은 다음과 같습니다.

test -t 0
if [ $? -eq 0 ]
then
    # interactive
    ;
else
    # non-interactive
    ;
fi

0

nneonneo의 솔루션은 저에게도 효과적이었습니다. 하지만 내 기본 셸이 TCSH이기 때문에 다음과 같이 수정을 약간 수정해야했습니다 (.tcshrc에서).

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

모든 사람의 이익을 위해 나눌 것이라고 생각했습니다.


0

Red Hat Enterprise Linux (RHEL) 또는 변형을 사용하는 경우 echo, 또는 원하는 작업을 수행하는 스크립트 를 /etc/profile.d/에 드롭합니다.


0

@Blauhirn의 답변에서 echo 문도 원한다면 case 조건 뒤에 echo 문을 계속 배치 할 수 있습니다.

case $- in
    *i*) ;;
    *) return;;
esac

echo "Your Greeting/Warning Message/s here!"

-1
if [ 0 -eq $(shopt -q login_shell; echo $?) ]; then
  echo "do something?"
fi

출처


OP에 대한 컨텍스트를 제공하면 좋을 것입니다.
aljabear

컨텍스트 및 관련 정보는 다른 답변과 질문 자체에서 이미 추출 할 수 있습니다. 이것은 낮은 신호 대 잡음비로 이미 이해 된 것을 수행하는 또 다른 방법입니다.
vesperto
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.