대화형 모드를 유지하면서 SSH를 통해 bash 명령 실행

대화형 모드를 유지하면서 SSH를 통해 bash 명령 실행

아마도 이것은 내가 달성하려는 이상한 일이지만
SSH를 통해 원격 호스트에 연결한 다음 "alias"와 같은 일부 bash 명령을 자동화하여 대화형 모드에서 사용하고 싶습니다. 원격 호스트는 개인 환경을 허용하지 않습니다.

가능합니까? 그렇게 될 것으로 "예상"됩니까? 아니면 이것을 달성하는 다른 방법이 있습니까?
기본적으로 bashrc가 원격 호스트의 파일을 수정하지 않기를 바랍니다.

답변1

즉, 리모콘을 갖고 싶지만 ~/.bashrc다른 이름으로도 가질 수 없는 것입니다. Bash는 초기 명령을 명령줄 인수로 전달하거나 환경 변수를 통해 전달하는 것을 지원하지 않으며 파일에 있어야 합니다. 그러나 파일이 파일 시스템에 있을 필요는 없습니다!

bash --rcfile /dev/fd/3 3< <(echo 'alias foo="echo hello"')
$ foo
hello

LC_XXX많은 SSH 서버에서는 로케일 설정을 나타내는 데 자주 사용되며 호스트 간에 전송해야 하며 보안에 영향을 미치지 않으므로 이름이 지정된 환경 변수의 전송을 허용합니다 . 허용하는 경우 환경 변수를 통해 콘텐츠를 전송 .bashrc한 다음 해당 환경 변수를 파일 설명자에 제공할 수 있습니다.

LC_BASHRC=$(cat ~/.bashrc; exec 3<&-) \
ssh -t remote.example.com \
    'exec bash --rcfile /dev/fd/3 3< <(printf %s "$LC_BASHRC")'
  • 로컬 콘텐츠는 ~/.bashrc환경 변수를 통해 서버로 전송됩니다 LC_BASHRC.
  • exec 3<&-파일을 읽은 후 파일 설명자를 닫으려면 추가하세요.
  • 원격 측에서 로그인 셸은 exec파일 설명자 3의 초기화 파일을 읽으라는 새로운 bash 인스턴스로 대체됩니다( ).
  • 3< <(…)파일 설명자 3의 출력을 명령 대체로 리디렉션합니다. printf상위 프로세스로 파이프됩니다.

서버의 로그인 셸이 /bin/shbash 또는 ksh가 아닌 경우 해당 셸에서 직접 프로세스 대체를 사용할 수 없으므로 추가 계층이 필요합니다.

LC_BASHRC=$(cat ~/.bashrc; exec 3<&-) \
ssh -t remote.example.com \
    'exec bash -c '\''exec bash --rcfile /dev/fd/3 \
                           3< <(printf %s "$LC_BASHRC")'\'

/etc/sshd_config /etc/ssh/sshd_config` AcceptEnv directive in its [구성을 찾아 SSH 서버에서 어떤 환경 변수가 허용되는지 확인할 수 있습니다 .](http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config&sektion=5) (or

3< <(…)명령 대체를 사용하는 대신 이 문자열을 사용할 수 있습니다. 이렇게 하면 파이프가 아닌 임시 파일( $TMPDIR또는 /tmp)이 생성되므로 임시 파일 생성에 신경 쓰지 않는 경우에만 작동합니다.

LC_BASHRC=$(cat ~/.bashrc; exec 3<&-) \
ssh -t remote.example.com \
    'exec bash --rcfile /dev/fd/3 3<<<"$LC_BASHRC"'

임시 파일을 생성해도 괜찮다면 다음과 같은 더 쉬운 방법이 있습니다.

  1. 파일을 .bashrc임시 원격 파일에 복사합니다. 임시 파일이 삭제될 때까지 이 작업은 한 번만 수행하면 됩니다.
  2. 대화형 셸을 시작하고 --rcfile임시 파일을 가리킵니다.
remote_bashrc=$(ssh remote.example.com 'bashrc=$(mktemp) && cat >>"$bashrc" && echo "$bashrc"' <~/.bashrc)
ssh -t remote.example.com "exec bash --rcfile '$remote_bashrc'"

SSH 구현이 너무 오래되지 않았다면 다음을 수행할 수 있습니다.기본 연결 사용동일한 호스트에 대한 여러 SSH 명령 실행 속도를 높입니다.

키로 로그인하고 공개 키 파일을 제어할 수 있으면 더 많은 자동화가 가능합니다. 존재하다~/.ssh/authorized_keys, 키에는 command=…명령줄에 지정된 명령 이외의 명령을 실행할 수 있는 지시문이 있을 수 있습니다. 바라보다원격 rsync 프로세스에 대한 환경 변수를 설정하는 방법은 무엇입니까?더 많은 설명을 원하시면.

command="if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then
           eval \"$SSH_ORIGINAL_COMMAND\";
         else exec bash -c 'bash 3<<<\"$LC_BASHRC\"'; fi" ssh-rsa …

또는

command="if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then
           eval \"$SSH_ORIGINAL_COMMAND\";
         else exec bash -c 'bash 3<<<\"alias foo=bar; …\"'; fi" ssh-rsa …

(이것은 한 줄에 모두 작성해야 합니다. 가독성을 위해 줄 바꿈했습니다.)

답변2

Gilles의 솔루션을 기반으로 AcceptEnv서버에 추가할 필요가 없습니다 LC_XXX.

ssh -t remote.example.com "
  exec bash --rcfile <(
    printf '%s\n' '$(
      sed "s:':'\\\\'':g" ~/.bashrc
    )'
  )
"

~/.bashrc이는 원격 세션에서 로컬을 사용하는 것입니다. bash에서 작은따옴표 사이의 모든 내용이 문자 그대로 처리된다는 점을 활용하므로 이스케이프에 대해 걱정해야 할 유일한 것은 내부 작은따옴표 자체입니다. bash 코드를 로 둘러싸고 's '를 내부 s로 대체하여 '\''안전하게 참조 할 수 있습니다.

별칭이나 인라인 콘텐츠를 추가하려는 경우외딴 ~/.bashrc:

ssh -t remote.example.com "
  exec bash --rcfile <(
    printf '%s\n' '
      . ~/.bashrc
      alias ll=\"ls -l\"
    '
  )
"

답변3

ssh_config 매뉴얼 페이지의 .from SendEnv에서 이 작업을 수행할 수 있습니다 ..ssh/config

SendEnv는 로컬 환경(7)의 어떤 변수를 서버로 보내야 하는지 지정합니다. 환경 전달은 프로토콜 2에서만 지원됩니다. 서버도 이를 지원해야 하며 서버는 이러한 환경 변수를 허용하도록 구성되어야 합니다. 서버 구성 방법을 알아보려면 sshd_config(5)의 AcceptEnv를 참조하세요. 변수는 와일드카드 문자를 포함할 수 있는 이름으로 지정됩니다. 여러 환경 변수는 공백으로 구분하거나 여러 SendEnv 지시문에 배포할 수 있습니다. 기본적으로 환경 변수는 전송되지 않습니다.

관련 정보