Node 버전 자동화

김동현·2023년 11월 25일

Question

목록 보기
7/15
post-thumbnail

서로 다른 Nodejs 버전

회사에 프로젝트가 여러개 있는데 Nodejs 버전이 크게 두 개로 나뉜다.
오래 된 프로젝트는 16버전을 사용하고 최근 프로젝트는 18버전을 사용하고 있다.

로컬에서 해당 프로젝트들을 띄울 때 nvm use를 사용해 변경해 주고 있었지만 자동으로 변경해 줄 수 있는 방법을 찾아 이번에 적용 했다.

.zshrc

. 으로 시작하는 파일

.으로 시작하는 파일은 숨김 파일이다.
이러한 파일은 일반적으로 시스템 설정 파일이나 중요한 시스템 파일 등과 같이 사용자에게 직접적으로 보이지 않아야 하는 파일들이다.

예를 들면, git의 .git, .gitignore등이 있다.
ls -al 명령어를 치면 아래와 같이 나온다.

zshrc
zsh + rc(runtime configuration? run command?)
🤔 rc가 뭘까 검색해 보았을 때 위 두가지를 줄인 것이라 나왔다. 둘다 설득력이 있는 것 같다.
ChatGPT에게도 물어보니 어떨때는 run command라고, 어떨때는 runtime configuration이라고 알려줬다.

.zshrc 파일은 ZSH을 실행할 때마다 실행되는 스크립트 파일과 같다.

⚠️ 쉘을 설치하더라도 홈에 .zshrc이 존재하지 않는다.
해당 프로세스를 사용하기 위해 ~ 홈 디렉토리에에서 .zshrc을 생성하여 스크립트를 작성하고 나면, zsh이 실행될 때마다 스크립트가 실행된다고 생각하면 된다!

자동 실행 스크립트

nvm Deeper-Shell-Integration 링크를 접속하면 디렉토리를 변경할 때마다 자동으로 nvm을 통해 버전을 맞추어주는 방법에 대한 설명이 있다!
1. 프로젝트 최 상위에 .nvmrc를 만들고 프로젝트에 사용되는 버전을 입력해 놓는다.

  1. ~/.zshrc에 실행 스크립트를 작성한다.

⚠️ 이 부분은 nvm이 관리하고 있지 않지만, PR은 받고 있다고 한다! ⚠️

autoload -U add-zsh-hook
load-nvmrc() {
  local nvmrc_path="$(nvm_find_nvmrc)"

  if [ -n "$nvmrc_path" ]; then
    local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")

    if [ "$nvmrc_node_version" = "N/A" ]; then
      nvm install
    elif [ "$nvmrc_node_version" != "$(nvm version)" ]; then
      nvm use
    fi
  elif [ -n "$(PWD=$OLDPWD nvm_find_nvmrc)" ] && [ "$(nvm version)" != "$(nvm version default)" ]; then
    echo "Reverting to nvm default version"
    nvm use default
  fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc

  1. 😎 그럼 아래와 같이 zsh을 실행할 때마다 node버전을 동일하게 맞추어 준다.


Shell

쉘은 키보드에서 Command를 입력 받아 운영 체제에 전달하여 명령을 실행하는 프로그램이다.
쉘은 운영 체제의 세부 정보를 숨기고 운영 체제의 커널 인터페이스를 구현하여 세부 정보를 관리하게 됩니다.

shell 이 명령어 위치를 찾는 방법

명령 이름 식별하기
셸은 CLI에서 I/O 리디렉션을 처리하고 제거 한 뒤 CLI의 제일 왼쪽에 남아 있는 첫번째 토큰/단어를 명령 이름으로 간주한다.

built-in command 로는 echo가 있다.

date 명령어와 같이 내장되어 있지 않은 명령 이름실행 프로그램 파일의 이름으로 간주되며 셸은 해당 이름을 가진 실행 파일을 찾아 실행한다. (셸은 명령을 찾고 실행하는 프로그램이다!)

🤔 어디에 실행 프로그램 파일이 있는 지 알 수 있을까?
셸은 $PATH 환경 변수에 저장된 디렉토리 목록에서 정확한 실행 파일의 이름을 찾는다. $PATH는 셸 환경 변수로서 목록을 변경할 수 있다!

해당 목록에서 date를 입력하면 가장 먼저 시도되는 디렉토리 경로는 /opt/homebrew/bin 이므로, /opt/homebrew/bin/date라는 실행 파일을 찾게 된다!

$PATH 환경 변수 경로를 쭉 뒤지다가 :/bin: 디렉토리에 date 파일이 존재하므로 해당 경로의 date 실행 파일을 실행한다!

만약 /bin/date 와 같이 경로를 주고 실행 파일을 실행한다면 PATH를 통해 조회하지 않고 셸이 직접 /bin/date를 실행하게 된다!

🤔 동일한 이름의 명령 파일이 있으면?

쉘은 $PATH 디렉토리에서 가장 먼저 발견된 실행 프로그램만 실행된다!
만약 /bin/ 과 /usr/bin 두 경로에 date라는 실행 프로그램 파일이 존재하더라도 먼저 만나는 /bin/ 디렉토리에서 멈추고 해당 파일 한 번만 실행하게 된다!!

명령어 위치 찾아보기

which 명령어를 사용하면 된다.

ls!

ls는 /bin 경로에 가면 파일로 존재한다.

#include <stdio.h>
#include <unistd.h>

int main() {
    // 명령어와 인자들을 배열로 준비합니다.
    char *args[] = { "/bin/ls", "-l", NULL };

    // 환경 변수를 배열로 준비합니다.
    char *envp[] = { "PATH=/bin", NULL };

    // execve 시스템 콜을 호출합니다.
    if (execve("/bin/ls", args, envp) == -1) {
        perror("execve");
        return 1;
    }

    // 이 부분은 실행되지 않습니다.
    printf("This line will not be executed.\n");

    return 0;
}

😁 위처럼, 환경 변수와 배열을 넘겨주고 execve 시스템 콜을 호출하면 ls가 실행되게 된다!!

execvc system call manual page

+ ls의 뒤 20줄을 찍어보면 아래와 같다.

참고 자료

profile
달려보자

0개의 댓글