ssh 셸에서 변수를 내 보내면 내 보낸 변수 목록이 인쇄되는 이유는 무엇입니까?


17

이걸 고려하세요:

$ ssh localhost bash -c 'export foo=bar'
terdon@localhost's password: 
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x HOME="/home/terdon"
declare -x LOGNAME="terdon"
declare -x MAIL="/var/spool/mail/terdon"
declare -x OLDPWD
declare -x PATH="/usr/bin:/bin:/usr/sbin:/sbin"
declare -x PWD="/home/terdon"
declare -x SHELL="/bin/bash"
declare -x SHLVL="2"
declare -x SSH_CLIENT="::1 55858 22"
declare -x SSH_CONNECTION="::1 55858 ::1 22"
declare -x USER="terdon"
declare -x XDG_RUNTIME_DIR="/run/user/1000"
declare -x XDG_SESSION_ID="c5"
declare -x _="/usr/bin/bash"

bash -c세션 내에서 변수 를 ssh를 통해 내보내는 이유는 declare -x명령 목록 (내가 알 수있는 한 현재 내 보낸 변수 목록)을 초래 하는 이유는 무엇 입니까?

없이 동일한 것을 실행하면 bash -c그렇게하지 않습니다.

$ ssh localhost  'export foo=bar'
terdon@localhost's password: 
$

다음과 같은 경우에도 발생하지 않습니다 export.

$ ssh localhost bash -c 'foo=bar'
terdon@localhost's password: 
$ 

우분투 컴퓨터에서 다른 컴퓨터로 bash 4.3.11을 실행하여 위의 bash 버전 4.4.5와 같이 아치 컴퓨터에서 sshing하여 테스트했습니다.

무슨 일이야? bash -c호출 내에서 변수를 내 보내면 왜이 출력이 생성됩니까?


이것은 질문에 대답하지 않지만 출력은 running의 결과입니다 export. Zsh도 마찬가지입니다.
Stephen Kitt

@StephenKitt 예, 나는 그것이 export무엇인지 이해하려고 노력하고 있습니다. 내보내기 할 때만 발생한다는 것을 명확히하기 위해 편집 할 것입니다.
terdon

아, 나는 출력이 어디에서 왔는지 알지 못한다는 것을 의미하는 "현재 내 보낸 변수의 목록"을 읽었습니다.
Stephen Kitt

@StephenKitt 나는 그것이 모든 내 보낸 변수 또는 특정 하위 집합인지 또는 무엇인지 확실하지 않다는 것을 의미 합니다. 오! 당신은 export혼자 실행 의 결과를 의미 합니까? 나는 이해하지 못했다.
terdon

참고 foo=bar목록에 표시되지 않습니다.
deltab

답변:


31

를 통해 명령을 ssh실행 $SHELL하면 -c플래그를 사용 하여 명령을 호출하여 실행됩니다 .

-c    If the -c option is present, then commands are read from 
      the first non-option argument command_string.  If there  are
      arguments  after the command_string, the first argument is 
      assigned to $0 and any remaining arguments are assigned to
      the positional parameters.  

따라서 ssh remote_host "bash -c foo"실제로 실행됩니다.

/bin/your_shell -c 'bash -c foo'

이제 실행중인 명령 ( export foo=bar)에 공백이 포함되고 전체를 구성하기 위해 제대로 인용되지 않으므로이 export명령은 실행될 명령으로 간주되고 나머지는 위치 매개 변수 배열에 저장됩니다. 이것은 export실행되고 foo=bar로 전달됨을 의미합니다 $0. 최종 결과는 달리기와 동일

/bin/your_shell -c 'bash -c export'

올바른 명령은 다음과 같습니다.

ssh remote_host "bash -c 'export foo=bar'"

9

ssh 인수를 공백으로 연결하고 원격 사용자의 로그인 쉘이이를 해석하도록합니다.

ssh localhost bash -c 'export foo=bar'

ssh 원격 쉘에게

bash -c export foo=bar

명령 (실제로, 원격 호스트가 Unix와 유사한 경우 the-shell, -c을 사용 bash -c export foo=bar하여 인수로 원격 쉘을 실행합니다 ).

대부분의 쉘은 실행으로 그 명령 줄을 해석합니다 bash으로 명령을 bash, -c, exportfoo=bar인수로 (그래서 실행 export중에 $0포함 foo=bar당신이 그것을 실행하려는 것 동안) bash, -cexport foo=bar인수로.

이를 위해서는 다음과 같은 명령 줄을 사용해야합니다.

ssh localhost "bash -c 'export foo=bar'"

(또는:

ssh localhost bash -c \'export foo=bar\'

그 문제에 대해) 그래서 :

bash -c 'export foo=bar'

명령 행은 원격 쉘로 전달됩니다. 즉, 명령 줄 실행중인 대부분의 쉘에 의해 해석 될 수 bash와 명령을 bash, -c그리고 export foo=bar인수로. 사용하여

ssh localhost 'bash -c "export foo=bar"'

원격 사용자의 로그인 쉘이 특별 인용 연산자가 아닌 경우 rc또는 작동하지 않습니다. 작은 따옴표는 가장 인용하기 쉬운 인용 연산자입니다 (쉘 사이에서 해석되는 방식에 약간의 차이가 있지만 원격 사용자의 로그인 쉘을 모르고 ssh를 통해 임의의 간단한 명령을 실행하는 방법? 을 참조하십시오).es"

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.