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

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

생각해 보세요:

$ 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"

SSH를 통해 실행되는 세션에서 변수를 내보내면 bash -c이 명령 목록 declare -x(내가 아는 한 현재 내보낸 변수 목록)이 생성되는 이유는 무엇입니까?

다음 없이 동일한 작업 실행 bash -c:

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

우리가 이것을 하지 않는다면, 그 일도 일어나지 않을 것입니다 export:

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

나는 하나의 Ubuntu 시스템에서 다른 시스템으로 sshing을 통해(둘 다 bash 4.3.11 실행), Arch 시스템에서는 위에 표시된 대로 자체적으로 sshing을 통해(bash 버전 4.4.5) 이것을 테스트했습니다.

여기서 무슨 일이 일어나고 있는 걸까요? 호출 시 변수를 내보내면 bash -c이 출력이 생성되는 이유는 무엇입니까?

답변1

명령을 실행하면 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'"

답변2

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

ssh localhost bash -c 'export foo=bar'

ssh원격 쉘 설명 요청

bash -c export foo=bar

명령(실제로 원격 호스트가 Unix 계열인 경우 및 인수를 사용하여 원격 셸 the-shell을 실행합니다 ).-cbash -c export foo=bar

대부분의 쉘은 이 명령줄을 , 및 인수로 bash명령 을 실행하는 것으로 해석하지만 (따라서 include에서 실행), 사용자는 , 및 인수로 실행하기를 원합니다.bash-cexportfoo=barexport$0foo=barbash-cexport foo=bar

이렇게 하려면 다음과 같은 명령줄을 사용해야 합니다.

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

(또는:

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

이를 위해) 그래서:

bash -c 'export foo=bar'

명령줄이 원격 셸로 전달됩니다. 이 명령줄은 대부분의 쉘에서 사용되는 것으로 해석되며 bash명령을 실행하기 위한 인수로 사용됩니다. 이용시 참고해주세요bash-cexport foo=bar

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

rc원격 사용자의 로그인 쉘이 특수 인용 연산자가 아닌 경우에는 es작동 "하지 않습니다 . 작은따옴표는 가장 이식성이 뛰어난 인용 연산자입니다(비록 쉘 간에 해석되는 방식에는 약간의 차이가 있지만,원격 사용자의 로그인 셸을 모르고 SSH를 통해 임의의 간단한 명령을 어떻게 실행할 수 있습니까?더 많은 정보를 알고 싶다면).

관련 정보