SSH 원격 명령이 수동으로 실행될 때 환경 변수가 더 적은 이유는 무엇입니까? [닫은]


239

컴퓨터에 ssh하고 실행하면 정상적으로 실행되는 명령이 있지만 다음과 같은 원격 ssh 명령을 사용하여 실행하려고하면 실패합니다.

ssh user@IP <command>

두 가지 방법을 모두 사용하여 "env"의 출력을 비교하면 다른 환경에서 다시 시작됩니다. 수동으로 컴퓨터에 로그인하고 env를 실행하면 다음을 실행할 때 훨씬 더 많은 환경 변수가 나타납니다.

ssh user@IP "env"

왜 그런지 알아?


30
왜이 질문이 주제와 다른 주제로 닫혀 있습니까?
jottr

13
프로그래밍과 관련이 없기 때문일 수 있습니다. 닫힌 대신 수퍼 유저로 이동해야합니다.
Daniel H

8
bash스크립팅 언어가 아닙니까?
Dan Nissenbaum

데비안 8에서는 어떤 이유로 쉘을 / etc / passwd에서 bash로 변경해야했습니다. / bin / sh가 bash를 가리 키도록 대시를 재구성해도 도움이되지 않았습니다.
user1050755

답변:


173

껍질에는 여러 가지 유형이 있습니다. SSH 명령 실행 셸은 비 대화식 셸이지만 일반 셸은 로그인 셸 또는 대화식 셸입니다. man bash의 설명은 다음과 같습니다.

       로그인 쉘은 인수의 첫 문자
       0은-이거나 --login 옵션으로 시작한 것입니다.

       대화식 쉘은 옵션이 아닌 시작된 것입니다.
       표준 입력의 -c 옵션이없는 인수
       오류는 모두 터미널에 연결되어 있습니다 (결정된대로)
       isatty (3)) 또는 -i 옵션으로 시작합니다. PS1은
       bash가 대화식 인 경우 set 및 $-i를 포함하여
       이 상태를 테스트하기 위해 쉘 스크립트 또는 시작 파일.

       다음 단락은 bash가 어떻게 실행되는지 설명합니다.
       시작 파일. 파일이 있지만 존재하지 않는 경우
       bash는 오류를보고합니다. 틸드는 파일에서 확장됩니다
       아래의 Tilde Expansion 아래에 설명 된 이름
       확장 섹션.

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

       로그인 쉘이 종료되면 bash는 명령을 읽고 실행합니다.
       ~ / .bash_logout 파일에서 존재합니다.

       로그인 쉘이 아닌 대화식 쉘이
       bash는 ~ / .bashrc에서 명령을 읽고 실행합니다.
       해당 파일이 존재하는 경우 이를 사용하여 억제 할 수 있습니다.
       --norc 옵션. --rcfile 파일 옵션은 강타를 강요합니다
       파일 대신 명령을 읽고 실행
       ~ / .bashrc.

       bash가 비 대화식으로 시작될 때 쉘을 실행하려면
       예를 들어 스크립트는 BASH_ENV 변수를 찾습니다.
       환경이 나타나면 그 가치가 확대되고
       확장 된 값을 읽을 파일 이름으로 사용합니다.
       실행하십시오. Bash는 다음 명령처럼 동작합니다
       처형 :
              [-n "$ BASH_ENV"] 인 경우; 그때. "$ BASH_ENV"; fi
       그러나 PATH 변수의 값은 검색에 사용되지 않습니다
       파일 이름으로


7
큰 대답은 이것이 정확히 문제였습니다. 필요한 환경 변수는 / etc / bashrc에 있으며 비 대화식 모드에서는 소스가 아닙니다. / etc / profile로 옮기면 문제가 해결되었습니다. 대단히 감사합니다!
Tom Feiner

1
이것은 부분적인 해결책으로 만 대답합니다. 여기에 더 많은 정보가 있습니다 : / etc / profile, etc / bashrc, ~ / .profile, ~ / .bash_profile, ~ / bashrc. 그런 다음 Jenkins 출력에서 ​​해당 고유 변수를 찾으십시오. 필자의 경우 'export SOURCED_SYSTEM_ETC_BASHRC = yes'를 포함하도록 / etc / bashrc를 업데이트했으며 해당 변수가 노드의 Jenkins 로그에 표시되었습니다. 제 경우에는 jenkins 슬레이브에 대한 환경 변수를 설정하려면 / etc / bashrc에 가야합니다. Jenkins SSH 로그인 / etc / bashrc 에서만 제공됩니다.
코더 Roadie

수정 : 나는 / etc / bashrc가 아니라 /etc/bash.bashrc를 의미했다.
코더 Roadie

37
그것은 꽤 벽의 텍스트 ssh user@host "bash --login -c 'command arg1 ...'"입니다. 원격 셸이 로그인 환경을 설정하도록 강조 할 가치가 있다고 생각 합니다. 인용 한 섹션에서 언급 --login했지만이를 간과하기 쉽습니다.
codebeard

이 게시물에 감사드립니다. 저는 ssh <ssh options> <IP> bash --login my_script.sh원격 컴퓨터에서 스크립트를 실행하고 치료를 JAVA_HOME
해왔으며 다음

117

명령을 실행하기 전에 프로파일을 소싱하는 것은 어떻습니까?

ssh user@host "source /etc/profile; /path/script.sh"

당신은 그 변경하도록 최선을 찾을 수있는 ~/.bash_profile, ~/.bashrc또는 무엇 이건.

( 여기서 (linuxquestions.org) )


1
이 문제가 있었으면이 솔루션은 훌륭하게 작동했습니다.
Sam152

10
환경을 소싱하기 위해 항상 추가 코드를 입력해야한다는 것은 말도 안됩니다!
Michael

4
이런 종류의 것들을 반복적으로 타이핑하는 일은 거의 없으며, 일반적으로 스크립트 내에있을 것입니다. 따라서 작동하는 한 "추가 코드"의 양에 상관없이 : tm :
Ian Vaughan

1
/ etc / profile과 ~ / .bash_profile (경로에 사용자 추가를 가져 오기 위해)을 모두 제공하면 작동하지만 추한 것입니다. "대화 형"로그인을 사용하고 원격 시스템의 전체 사용자 별 경로로 끝나도록 명령 (내 경우에는 xterm)에 더 쉬운 방법이 있어야합니까?
Jess

ssh $ 1 "source ~ / .bashrc; ~ / temp_unix.sh"여기 temp_unix.sh에 MANI_HOME = "mani deepak"내보내기가 있지만 작동하지 않습니다.
mani deepak

90

원격 ssh 명령을 실행할 때 쉘 환경이로드되지 않습니다. ssh 환경 파일을 편집 할 수 있습니다.

vi ~/.ssh/environment

형식은 다음과 같습니다.

VAR1=VALUE1
VAR2=VALUE2

또한 옵션 sshd구성을 확인하십시오 PermitUserEnvironment=yes.


1
완전! 내가 할 수 있다면 +100 :)
Dexter

VisualGDB는 "bash : gcc : command not found"오류와 함께 실패했으며이 솔루션은이를 수정했습니다.
KalenGi

환상적입니다. 내가 몇 년 전에 알고 있었으면 좋겠다.
중력

이것은 완벽한 답변입니다!
Jirapong

1
@ pg2455 서버에서 sshd를 항상 구성 할 수있는 것은 아니지만 모든 기능을 사용하지 않으려는 경우에도 사용자 환경을 편집 할 수 있습니다.
dpedro

63

비슷한 문제가 있었지만 결국 ~ / .bashrc가 내가 필요한 전부라는 것을 알았습니다.

그러나 우분투에서는 ~ / .bashrc 처리를 중지하는 줄을 주석 처리해야했습니다.

#If not running interactively, don't do anything
[ -z "$PS1" ] && return

8
또는 "비 대화식"코드를 모두 해당 줄 위에 둘 수 있습니다.
machineghost

아름답고 많은 시간을 절약했습니다 :) 감사합니다
Lance Pollard

감사. return 문이있는 파일을 추가하면에서 찾을 수 있습니다 /etc/bash.bashrc.
adarshr

이 코드를 변경하지 않고 서버에서 우회 할 수 있습니까?
요니

스크립트가 작동하지 않는 이유를 이해하려고 많은 시간을 보냈습니다. 이 줄을 .bashrc에 넣는 것이 좋은 생각이라고 누가 생각 했습니까 ???
Sharcoux

4

이 문제에 대한 쉬운 해결책은 대상 시스템에서 실행하려는 script.sh 파일의 맨 위에 source / etc / profile을 추가하는 것입니다. 여기의 시스템에서 이로 인해 script.sh에 필요한 환경 변수가 로그인 쉘에서 실행되는 것처럼 구성되었습니다.

이전 응답 중 하나에서 ~ / .bashr_profile 등을 사용하는 것이 좋습니다. 나는 이것에 많은 시간을 소비하지 않았지만, 이것에 대한 문제는 당신이 로그인 한 소스 시스템의 쉘과 다른 타겟 시스템의 다른 사용자에게 ssh하면 이것이 소스 시스템 사용자를 일으키는 것으로 나에게 나타납니다 ~에 사용될 이름.


완전한! 문제에 대한 좋은 단선 솔루션.
corpico

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