내 문제는
$ ssh localhost fswatch
bash: fswatch: command not found
SSH 명령(예: fswatch)이 없으면 정상적으로 작동합니다.
SSH 세션의 PATH가 기본 Mac의 PATH라는 것을 알았습니다.
$ ssh localhost echo \$PATH
/usr/bin:/bin:/usr/sbin:/sbin
SSH가 없기 때문에
$ echo $PATH
/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
PATH를 어떻게 설정했는지 기억이 나지 않지만 PATH 변수를 편집하지 마십시오 ~/.bashrc
. ~/.bash_profile
구성 파일이 있습니다 /etc/paths
.
$ cat /etc/paths
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
Homebrew, npm, pip는 일반적으로 에 프로그램을 설치하므로 설치된 모든 프로그램이 거기에 있으며 MacOS를 /usr/local/bin
통해 액세스할 수 없습니다 . ssh localhost command
리눅스에는 문제가 없습니다.
그래서 내 질문은/etc/paths
및 PATH를 사용하도록 OpenSSH를 구성하는 방법/etc/paths.d?
나는 또한 해킹을 시도했습니다.
$ ssh localhost sh -lc 'echo empty;echo $PATH'
/usr/bin:/bin:/usr/sbin:/sbin
$ ssh localhost bash -lc 'echo empty;echo $PATH'
/usr/bin:/bin:/usr/sbin:/sbin
첫 번째 줄은 항상 비어 있습니다. 이유를 모르시나요?
그리고 내 마지막 해결 방법
$ ssh localhost bash -lc ':;
export PATH="$( cat /etc/paths /etc/paths.d/* | tr \\\\n : )";
echo $PATH;
fswatch --version'
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Applications/VMware Fusion.app/Contents/Public
fswatch 1.14.0
Copyright (C) 2013-2018 Enrico M. Crisostomo <[email protected]>.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Enrico M. Crisostomo.
첫 번째 명령이 어떻게든 실행에서 제외되기 때문에 여기서는 첫 번째가 :;
중요합니다.
시스템: MacOS Mojave 10.14.5
ssh -V
:OpenSSH_7.9p1, LibreSSL 2.7.3
bash --version
GNU bash, version 5.0.7(1)-release (x86_64-apple-darwin18.5.0)
답변1
사용자 정의 변수를 포함하여 클라이언트에 사용자 정의 환경을 제공하도록 SSH 서버를 구성할 수 있습니다 PATH
. 다음 2가지를 구성해야 합니다.
~/.ssh/environment
다음을 포함하는 서버에 파일을 만듭니다 .PATH=/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
/private/etc/ssh/sshd_config
다음 줄을 포함하도록 SSH 서버 구성 파일을 변경합니다 .PermitUserEnvironment PATH,LANG
마지막으로 서버에서 SSH 데몬을 다시 시작/다시 로드합니다. SSH 로그인 클라이언트는 사용자 정의된 환경에 액세스할 수 있어야 합니다!
답변2
내 시스템에서는 이것을 편집 .bashrc
하고 넣을 수 있습니다맨 꼭대기에:
PATH=/my/path:$PATH
먼저 다음을 입력하는 것이 중요합니다.
# If not running interactively, skip the rest
[ -z "$PS1" ] && return
답변3
내 대답에서는 Bourne Again SHell을 사용한다고 가정하지만 다음은 대부분의 다른 쉘에서도 마찬가지입니다.
관찰된 동작의 이유는 명령이 대화형이 아닌 비대화형 셸에서 실행되기 때문입니다.
사용자의 신원이 서버에 의해 승인되면 서버는 비대화형 세션에서 주어진 명령을 실행하거나 명령이 지정되지 않은 경우 시스템에 로그인하여 사용자에게 대화형 세션으로 일반 쉘을 제공합니다. 원격 명령 또는 셸과의 모든 통신은 자동으로 암호화됩니다.
-$ man ssh
나는 당신의 어딘가에서 변수를 .bashrc
확장한다고 생각합니다 PATH
. 그러나 .bashrc
대화형 셸을 실행하지 않으면 BASH는 파일을 해석하지 않습니다 .
언제로그인 쉘이 아닌 대화형 쉘이 시작되면 bash는 /etc/bash.bashrc 및 ~/.bashrc(이 파일이 존재하는 경우)에서 명령을 읽고 실행합니다.
-$ man bash
따라서 이 문제에 대한 가장 쉬운 해결책은 다음과 같이 실행 파일에 대한 전체 경로를 제공하는 것입니다. $ ssh localhost /full/path/to/fswatch
이것은 이 문제에 대한 가장 안정적이고 안전한 솔루션이며 항상 작동합니다!
에 연결하면 다음 명령 localhost
을 활용할 수 있습니다 which
. $ ssh localhost $(which fswatch)
그러나 다른 호스트에 연결하면 이 방법이 작동하지 않을 가능성이 높습니다.
PATH
또 다른 가능한 방법 은 비대화형 쉘에 대한 원격 호스트의 환경 변수를 조작하는 것입니다 (@hedgie의 답변 참조). 그러나 이는 보안에 영향을 미치므로 프로덕션에서는 사용하면 안 됩니다.
환경 처리를 활성화하면 사용자는 LD_PRELOAD와 같은 메커니즘을 사용하여 일부 구성에서 액세스 제한을 우회할 수 있습니다.
-man sshd_config