ssh
ssh -t는 해당 쉘에 직접 접속해 명령어를 입력하는 대신 매개변수로 커맨드를 실행하는 방법이다.
다음과 같이 사용할 수 있다.
$ ssh test@test.com -t "npm install"
그러나 막상 명령을 실행해보면 제대로 동작하지 않을 것이다.
command not found
오류가 뜨게 되는데, 막상 직접 접속해서 사용할 때는 해당 문제가 발생하지 않는다.
왜 발생하는가
단순히 말하자면, 이는 .bashrc
의 실행 여부와 환경 변수인 PATH
의 문제에 의해 발생한다.
ssh -t 명령어를 실행할 때,
사용자의 권한은 ssh 키나 패스워드를 통해 검증되나 실제로 로그인 세션은 발생하지 않는다.
때문에 원격 접속과는 달리 빠르고 편리하게 명령어를 실행하는 것이 가능해지므로, 주로 크론잡이나 스크립트 등에서 사용한다.
그러나 해당 환경은 로그인 세션과 관련한 특정 환경 설정이 적용되지 않는 경우가 발생할 수 있다.
그 중 하나가 .bashrc
파일이다.
.bashrc
파일은 bash 셸의 초기화 스크립트로, 로그인 세션이 발생할 때마다 실행된다.
이는 사용자의 환경 변수 및 셸 환경을 설정하고 사용자가 지정 명령어나 별칭을 정의하는 데에도 사용된다.
.bashrc
는 각각의 사용자에게 따로 할당되는 값이므로 해당 값이 PATH로 전역 설정되어 있지 않으면 -t
옵션을 사용해 명령을 내려도 실행할 수 없다.
이는 -t
옵션이 로그인 세션을 발생시키지 않기 때문이다.
apt 레포지토리는 잘 되는 이유
which npm, whereis npm 등의 명령어를 실행해보자.
$ which npm
/home/octavesop/.nvm/versions/node/v18.14.0/bin/npm
$ whereis npm
npm: /home/octavesop/.nvm/versions/node/v18.14.0/bin/npm
octavesop은 내 사용자명이며, 나의 경우 nvm을 통해 설치해 다음과 같은 디렉토리에 위치하나,
일반적으로 각 사용자의 디렉토리 하단에 설치되어 있음을 알 수 있다.
apt 등의 패키지 관리자를 통해 설치한 프로그램들은 해당 패키지 관리자가 관리하는 디렉토리에 설치된다.
이 경우 /usr/bin
이나 /usr/local/bin
과 같은 시스템의 표준 디렉토리이다.
이런 디렉토리들은 일반적으로 PATH에 포함되어 있으므로, 패키지 관리자를 통해 설치한 프로그램들은 자연스럽게 PATH에 포함되게 된다.
가령 ci/cd 파이프라인을 쉘 기반으로 작업할 때 명령어가 실행되지 않다가 sudo apt-get install npm
하면 잘 되던데요? 하는 것은
apt repository를 통해 설치한 프로그램들의 위치가 PATH에 속해있기 때문이다.
이런 방식은 해결로 여기기 어렵다. npm이나 node.js를 제외한 여러 프로그램들이 apt repository에서는 구식인 경우가 적지 않다.
또한 이미 설치되어 있는 프로그램을 (심지어 대체로 구버전인 것을) 다른 디렉토리에 다시 설치하는 것도 이상한 모양새이다.
어떻게 해결하는가
직접 셸 초기화 스크립트 사용하기
다음의 방식으로 직접 셸 초기화 스크립트를 실행할 수 있다.
이 경우 사용자의 환경 변수를 읽어오게 되므로 command not found
문제는 더 이상 생기지 않는다.
그러나 프로그램이 전역적으로 실행되어야 하는 구조라면 다른 방법을 취해야 할 것이다.
$ ssh test@test.com -t "source ~/.bashrc; npm --version"
PATH에 해당 프로그램 포함시키기
해당 프로그램이 전역적인 시스템 설정으로 관리되어야 한다고 판단한다면, PATH를 설정해주는 것이 바람직하다.
$ export PATH=$PATH:/path/to/npm/bin
이제 실행되는 것을 확인할 수 있다.
$ ssh test@test.com -t "npm --version"
심볼릭 링크 설정하기
심볼릭 링크를 통해 가상 경로를 생성하는 것은 결국 PATH 설정과 크게 다르지 않다.
PATH의 기본 디렉토리에 이미 설치된 프로그램들의 심볼릭 링크를 생성하여 전역적으로 사용할 수 있게 만들어주는 것이다.
ln -s
를 통해 심볼릭 링크를 사용할 수 있다. 다음과 같이 사용하면 된다.
$ sudo ln -s "$(which node)" /usr/bin/node
$ sudo ln -s "$(which npm)" /usr/bin/npm
$ sudo ln -s "$(which pm2)" /usr/bin/pm2
이제 -t
옵션을 사용해도 명령이 잘 동작할 것이다.
'INFRA > LINUX' 카테고리의 다른 글
Linux Command Line tips (0) | 2024.05.09 |
---|---|
history에 시간값 추가하기 - Ubuntu (1) | 2024.03.15 |
시스템 로그 확인 (0) | 2023.10.20 |
깔끔하게 프로세스 죽이기 (0) | 2023.10.04 |
man 명령어 (0) | 2023.10.04 |