생각해 보세요:
$ 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
을 실행합니다 ).-c
bash -c export foo=bar
대부분의 쉘은 이 명령줄을 , 및 인수로 bash
명령 을 실행하는 것으로 해석하지만 (따라서 include에서 실행), 사용자는 , 및 인수로 실행하기를 원합니다.bash
-c
export
foo=bar
export
$0
foo=bar
bash
-c
export 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
원격 사용자의 로그인 쉘이 특수 인용 연산자가 아닌 경우에는 es
작동 "
하지 않습니다 . 작은따옴표는 가장 이식성이 뛰어난 인용 연산자입니다(비록 쉘 간에 해석되는 방식에는 약간의 차이가 있지만,원격 사용자의 로그인 셸을 모르고 SSH를 통해 임의의 간단한 명령을 어떻게 실행할 수 있습니까?더 많은 정보를 알고 싶다면).