저는 Mac OS Big Sur에서 가상 Ubuntu 16.04 Linux 인스턴스(vagrant 사용)를 실행하고 있습니다. 다음 두 명령을 제대로 실행할 수 있습니다(하나는 가상 서버에 ssh로 접속하고 두 번째는 그 안에서 명령을 실행합니다)...
$ ssh myvirtual.local
Warning: Permanently added '10.0.4.19' (ECDSA) to the list of known hosts.
Last login: Wed Sep 15 16:37:57 2021 from 10.0.4.1
$ foreman start -f Procfile.debug
16:38:26 rails.1 | started with pid 27884
16:38:26 worker.1 | started with pid 27885
16:38:26 scheduler.1 | started with pid 27887
...
나는 이 두 명령을 결합할 수 있기를 원했기 때문에 시도해 보았습니다.
$ ssh -t myvirtual.local 'foreman start -f Procfile.debug’
Warning: Permanently added '10.0.4.19' (ECDSA) to the list of known hosts.
bash: foreman: command not found
Connection to 10.0.4.19 closed.
단일 명령을 사용하여 원래 수행한 작업을 시뮬레이션하기 위해 실행해야 하는 다른 설정이 무엇인지 혼란스럽습니다. 어떤 아이디어가 있나요?
답변1
이 경우의 주요 차이점은 ssh host
로그인 모드에서 로그인 쉘을 시작한다는 것입니다. 접두어는 , sshd
, 또는 (아마도 쉘의 시스템 시작 스크립트에서 시스템 시작 스크립트를 읽어 로그인 세션을 초기화해야 함을 쉘에 알려줍니다. 구현) 및 대화형(입력 프롬프트를 표시하기 때문). 이것이 패턴이다.-
argv[0]
.profile
.bash_profile
.zprofile
.zlogin
.login
/etc
rlogin
ssh
에서는 ssh -t host 'some shell code'
및 인수를 사용하여 로그인 쉘을 실행 sshd
하지만 로그인 쉘이라고 지시하지 마십시오. 쉘은 또한 비대화형이며 터미널에서 코드를 묻는 메시지를 표시하지 않습니다. 이것이 패턴이다.-c
some shell code
rsh
귀하의 경우 변수를 설정하기 위한 세션 초기화 파일의 일부 지침이 $PATH
아직 실행되지 않았기 때문에 명령을 찾을 수 없을 가능성이 높습니다.
모든 쉘이 동시에 로그인 쉘로 작동하고 인수로 제공된 코드를 해석할 수 있는 것은 아닙니다.
케이스는 bash
괜찮습니다. 시작 시 로그인 셸로 시작 되며 bash
또는 옵션이 전달되면 실행 명령이 전달되더라도 1은 여전히 로그인 세션 초기화 파일을 읽습니다(POSIX 모드 제외).argv[0]
-
-l
--login
-c
따라서 이렇게 하는 대신 다음과 같이 하세요.
ssh -t host 'some code'
다음을 수행할 수 있습니다.
ssh -t host "exec bash --login -c 'some code'"
이것은 또 다른 것을 시작 bash
하지만 이번에는 해석하기 전에 로그인 셸로 사용됩니다(그 안의 코드 ~/.bash_profile
와 초기화가 있는 곳을 해석할 것입니다 /etc/profile
)./etc/profile.d
$PATH
some code
또는 정의가 작성된 파일을 찾아 $PATH
다음을 수행할 수 있습니다.
ssh -t host '. /path/to/that/file && some code'
이것은 여전히 또 다른 차이점을 남깁니다. 즉, 쉘은 대화형이 아니며 시작 파일은 대화형일 때와 비대화형일 때 다르게 동작하도록 결정할 수 있습니다( i
존재 여부를 확인하거나 $-
변수가 존재하는지 확인하여 $PS1
).
bash
로그인 셸로 실행하면 ~/.bashrc
(대부분의 다른 셸에서 발생하는 것과는 반대로) 시작 시 (대화형 셸 사용자 정의 파일)이 해석되지 않지만 대부분의 사람들은 데비안 및 그 파생 제품 source ~/.bashrc
에서 이를 사용합니다. ~/.bash_profile
버전은 ~/.profile
기본적으로 이 작업을 수행합니다(물론 쉘이 인 경우에만 bash
).
bash
이는 ssh를 통해 호출될 때 기본적으로 해석되지 않지만 ~/.bashrc
구성 옵션을 사용하여 컴파일 타임에 구성할 수 있습니다 SSH_SOURCE_BASHRC
. Debian 및 Ubuntu와 같은 파생 제품이 이를 가능하게 합니다. 따라서 이렇게 할 때 ssh ubuntu-host 'some code'
로그인 쉘이 해당 시스템에서 bash이면 실행될 쉘이 bash
해석되기 전에 sshd
해석 됩니다.~/.bashrc
some code
따라서 궁극적으로 모드 안팎 으로 ~/.bashrc
해석되지만 @Quasimodo가 지적했듯이 Debian 및 Ubuntu의 기본값은 맨 위에 있습니다.rlogin
rsh
~/.bashrc
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
$PATH
따라서 이 줄 아래에 정의가 있는 경우 rlogin
모드( bash
대화형, $-
포함 i
및 ~/.bashrc
소스가 있는 경우)에서만 해석되며 모드( 소스는 있지만 해당 내용의 대부분을 건너뛰는 경우) ~/.profile
에서는 해석되지 않습니다 . 쉘은 대화형이 아닙니다.)rsh
~/.bashrc
1 (/와 반대로)로 시작하는 경우 argv[0]
a 전달이 로그인 셸로 처리되는지 여부는 컴파일 활성화 여부에 따라 달라집니다.-
-l
--login
-c code
bash
NON_INTERACTIVE_LOGIN_SHELLS
답변2
두 가지 경우가 항상 동일하지는 않기 때문에 환경 설정이 누락되었습니다.
ssh remoteHost
someCommand
ssh -t remoteHost someCommand
다음 명령 블록은 선호하는 솔루션에서 누락된 변수 세트를 제공합니다(위 두 예의 두 번째 형식). 질문에 이러한 내용을 추가하면 설정 방법을 설명하는 질문을 완성해 드리거나, 이 정보를 사용하여 직접 설정할 수도 있습니다.
ssh -t myvirtual.local env | grep = | sort >/tmp/env.1
( echo env; echo exit ) | ssh -tt myvirtual.local | grep = | sort >/tmp/env.2
comm -13 /tmp/env.1 /tmp/env.2
내 시스템의 간단한 출력 예는 여기에 있습니다.
EDITOR=vi
HISTCONTROL=ignoredups
LESSCLOSE=/usr/bin/lesspipe %s %s
LESSOPEN=| /usr/bin/lesspipe %s
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:...
PAGER=less
PATH=/home/roaima/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/bin:/bin
PROMPT_COMMAND_WAS=echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"
SHLVL=1
SSH_CLIENT=192.1.1.9 31996 22
SSH_CONNECTION=192.1.1.9 31996 192.1.1.18 22
TTY=/dev/pts/0
XDG_SESSION_ID=c61
이는 Ruby 또는 Rails에만 해당되는 내용은 아니지만 제 경우에는 변수가 다르다는 것을 보여줍니다 ( 및 에서 실제 값을 볼 PATH
수 있습니다 )./tmp/env.1
/tmp/env.2
이를 추적하고 정렬한 후에는 연결이 종료될 때 신호를 받지 않도록 또는 foreman
아래에서 실행 하는 것이 좋습니다 . 하지만 이러한 추가 도구를 도입하기 전에 초기 문제를 해결하는 것이 좋습니다.screen
tmux
SIGHUP
ssh