ssh 원격 명령의 $ PATH가 대화식 쉘의 $ PATH와 다른 이유는 무엇입니까?


20

도트 파일에서 $ PATH를 수정하지 않은 사용자가 있습니다. 정확히 시스템 기본 설정입니다. 로그인 쉘에서 :

$ ssh example.com
user@example.com:~$ cat /tmp/hello.hs
#!/bin/bash

echo "$SHELL"
echo "$PATH"

user@example.com:~$ /tmp/hello.hs
/bin/bash
/usr/local/bin:/usr/bin:/bin

에 지정된대로 정확하게 /etc/profile. 이것은 다소 예기치 않은 것을 발견합니다.

$ ssh example.com '/tmp/hello.sh'
/bin/bash       
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

내가 말했듯이에서 ~/.bashrc또는에서 $ PATH의 수정은 없습니다 /etc/bash.bashrc. ~/.ssh/environment둘 다 아닙니다 . 는 ssh(1)환경 변수가 선언 PATH이다

ssh를 컴파일 할 때 지정된대로 기본 PATH로 설정하십시오.

그러나 StackOverflow 의이 스레드 와이 메일 링 목록 기사는 / etc / profile, 쉘 시작 파일 중 하나 등을 수정하여 주어진 명령의 $ PATH에 영향을 줄 수 있어야 한다고 제안합니다 .

무슨 일이야?

답변:


16

에서 ssh(1)매뉴얼 페이지 : "명령이 지정된 경우, 대신 로그인 쉘의 원격 호스트에서 실행됩니다."

즉, 실제로 컴퓨터에 로그인 할 때 bash는 로그인 셸로 시작되고 적절한 파일을로드합니다. 원격으로 연결하고 명령을 실행할 때 bash 대신 명령이 실행됩니다. 즉, 이러한 파일은로드되지 않습니다. su -l -cssh의 명령 부분에서 사용 하거나 이와 유사한 방법 으로 문제를 해결할 수 있습니다 .

어떤 경우에는 -tssh work (tty를 할당)에 대한 논쟁을 보았습니다 .

편집 1 :
찾은 PATH 정보는 기본 경로 (재정의하지 않는 한)가 sshd로 컴파일 된 경로라고 생각합니다. 내 / etc / profile, / etc / bash *, 로컬 도트 파일 등에 PATH 정보가 없는지 확인한 다음 로그온하여 여전히 PATH가있었습니다. 나는 이것을 sshd에서 검색하고 거기에서 발견했다. 맨 페이지의 내용은 다음과 같습니다.

ahnberg@remote$ strings /usr/sbin/sshd | grep -i x11 | grep bin
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

그런 다음 원격에서 파일 PATH=$PATH:/my/test맨 위에 추가 .bashrc하고 다시 확인하십시오.

ahnberg@local$ ssh ahnberg@remote "env | grep PATH"
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/my/test

따라서 절대적으로 영향을 줄 수 있으며 기본 PATH는 sshd로 컴파일 된 것입니다. :)


흠, "원격 호스트에서 실행"이라는 문구는 생각보다 많은 것을 의미합니다. 앞에서 놓친 더 흥미로운 비트는 같은 맨 페이지의 'ENVIRONMENT'섹션에 있습니다. "PATH ssh를 컴파일 할 때 지정된 기본 PATH로 설정하십시오." 를 제외하고 나는 것을 제안 한다 명령의 PATH에 영향을 미칠 수 있습니다.
troutwine 2012 년

요점은 로그인 쉘이 아니기 때문에 로그인 쉘과 동일한 방식으로 시작 파일을 실행 / 소스 / 포함하지 않으므로 시도해 볼 것을 제안합니다. 물건을 넣는 .bashrc것도 효과가 있지만 PATH가 중요하다면 전반적으로 문제를 해결할 것입니다. 또는 ssh를 실행하는 '명령'방법이 필요한 경우 전체 경로 이름을 지정하지 않는 이유는 무엇입니까? :)
Mattias Ahnberg 2012 년

내 게시물을 약간 수정했습니다. 이제 로그인 셸, 비 로그인 셸 및 대화 형 / 비대화 형 변형이 있습니다. SSH 명령은 비 대화식 비 로그인 형식으로 사용자의 셸에서 호출됩니다. bash(1)호출에는 시작 파일이 방식으로 읽을 것을 제안,하지만 난에 대한 문서를 찾을 수없는 방법 SSH 쉘을 호출됩니다. 다른 사람들이 내가 가지고 있지 않은 / etc / ssh / sshrc 시작 파일 소싱을 가지고 있지 않으면 위의 링크 된 소스와 반대되는 것처럼 보입니다. (물론 해결 방법이 있지만 요점은 데비안 SSHD가 기본적으로 경로를 처리하는 방법을 정확히 이해하는 것입니다.)
troutwine

/etc/profile원격 상자 경로 에서 PATH를 수정 ssh user@remotebox 'env'하면 업데이트 된 PATH가 표시됩니다. 내가 추가 할 경우 같은 일이 간다 export PATH=$PATH:/my/testpath(하지만 파일의 상단에 내 경우에는 (대화 형 쉘을 검사하기 전에 .bashrc에로 -z "$PS1").
마티아스 Ahnberg

내 테스트 / 발견으로 업데이트되었습니다.
Mattias Ahnberg 2012 년

3

ssh가 다음을 실행하여 원격 경로를 사용하여 명령을 실행하도록 할 수있었습니다.

ssh dist@d6 "bash --login -c 'env'"

여기서 env는 원하는 명령으로 바꿀 수 있습니다.

키를 인증 했으므로 명령 또는 ssh를 실행하기 위해 비밀번호가 필요하지 않았습니다.


3

문제를 해결하기 위해 다른 솔루션을 생각해 냈습니다. 개인적으로 선호하는 것은 기존 구성 파일을 변경하는 대신 새 구성 파일을 만드는 것입니다. 이렇게하면 기본 구성에서 변경 사항을 쉽게 처리 할 수 ​​있습니다.

내용은 다음과 같습니다 /etc/profile.d/ssh_login.sh.

#!/bin/sh
if [ "$SSH_CONNECTION" ]; then
    echo "User '$USER' logged in from '${SSH_CONNECTION%% *}'"
    . /etc/environment
fi

사용 dropbear대신에 openssh-server내가 원격으로 로그인 할 때 (이 또한 OpenSSH를 작동한다)의 SSH_CONNECTION 변수가 자동으로 설정됩니다. SSH 로그인을 감지하고, 화면에 일부 정보를 표시하고, 가장 중요한 것은 /etc/environment컴파일 된 값을 대체하기 위해 전역 환경 설정을로드하기 위해 새로운 쉘 프로파일 구성을 작성했습니다 . 이것은 원격 명령 실행이 아닌 대화식 SSH 셸에만 영향을 미칩니다.

또는 openssh를 사용하고 대화식 쉘인지 여부에 관계없이 항상 전역 환경을로드하려는 경우 다음 ~/.ssh/과 같이 심볼릭 링크를 배치 할 수 있습니다 .

ln -s /etc/environment ~/.ssh/environment

그런 다음의 PermitUserEnvironment옵션 을 활성화해야합니다 /etc/sshd/sshd_config. LD_PRELOAD와 같은 메커니즘을 사용하는 일부 구성에서는 액세스 제한을 무시할 수 있으므로 신뢰할 수있는 사용자에게만이 작업을 수행하십시오. man sshd_config자세한 정보, 특히 Match블록을 사용 하여 옵션을 특정 사용자 / 그룹에 제한 하는 방법을 참조하십시오 .


0

프로파일 경로를로드하려면 다음을 시도하십시오.

#!/bin/bash -i

스크립트 상단에. 그렇게하면 스크립트를 실행할 때 쉘이 대화식 모드에있게됩니다.

bash가 대화식 로그인 쉘 또는 --login 옵션을 사용하는 비 대화식 쉘로 호출되면 파일이 존재하는 경우 먼저 / etc / profile 파일에서 명령을 읽고 실행합니다. 해당 파일을 읽은 후 ~ / .bash_profile, ~ / .bash_login 및 ~ / .profile을 순서대로 찾고 존재하고 읽을 수있는 첫 번째 파일에서 명령을 읽고 실행합니다. 이 동작을 막기 위해 쉘을 시작할 때 --noprofile 옵션을 사용할 수 있습니다.

http://linux.die.net/man/1/bash

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