linux의 profile과 bashrc ( feat. source )

profile과 bashrc

Ubuntu와 같은 linux system에는 설정 파일을 .profile.bashrc 등으로 관리할 수 있다. 이 2가지를 어떻게 사용하면 좋을지 생각해 보자.

/etc 아래 전역 설정에도 이들이 있지만, 여기서는 user가 관리할 수 있는 ~/.prpfile~/.bashrc만 다루겠다. 특별한 경우가 아니라면 sudo 권한은 쓰지 않는 편이 좋다.

양자는 모두 사용자 환경 설정에 중요한 역할을 하지만, 실행되는 시점과 적용 범위에 차이가 있다.

profile

먼저 ~/.profile는 사용자(user) 전용 환경 설정 파일이다. 사용자에 종속되어 있다. 사용자가 터미널을 통해 로그인할 때 단 한 번 실행되므로 주로 사용자 환경에 필요한 설정을 담는다. 가장 많이 사용하는 예는 다음과 같다.

~/.profile는 shell이 열리기 전에 실행되므로 여기서 설정한 환경은 로그인 후 실행되는 모든 셸(bash뿐만 아니라 다른 셸도 포함)에 영향을 미친다.

bashrc

다음으로 ~/.bashrc는 bash shell 전용 환경 설정 파일이다. bash에 종속되어 있다. 새로운 bash 셸이 시작될 때마다 실행되므로 주로 bash 셸에서만 사용되는 편리한 기능들을 설정합니다. 가장 많이 사용하는 예는 다음과 같다.

사용 예시

정리하면, ~/.profile는 사용자와 관련된 환경 설정 파일이다. 로그인 시 한 번만 필요한 환경 변수나 초기 작업을 설정하며, 이는 시스템 전반에 영향을 준다. 반면 ~/.bashrc는 bash shell와 관련된 환경 설정 파일이다. 새로운 bash 셸이 시작될 때마다 필요한 bash 환경을 설정한다. 주로 bash 사용 편의성을 높이는 설정이 포함된다.

Ubuntu 등에 App(혹은 system package)를 설치할 때 종종 pre-compiled file을 어떤 위치에 저장하고, 해당 위치 경로를 PATH에 추가하라고 할 때가 있다. 그렇다면 이 PATH는 어디에서 설정해 주어야 할까. bash가 아니라 system에 대한 설정이므로 ~/.profile에 넣어 주는 것이 좋겠다.

만약 bash-it과 같이 bash의 모양이나 편의성을 추가하는 설정을 해야 할 때는 어떻게 해야 할까? system이 아니라 bash shell과 관련된 일이므로 ~/.bashrc에 넣어 주는 것이 좋겠다.

하지만 환경 설정을 변경할 때마다 이 두 파일을 수정하는 것은 그리 편리하지 않다. 어떻게 해야할까? 사용자 전용 파일을 만들고 이를 ~/.profile~/.bashrc에서 불러서 적용해주는 편이 더 편리하다. 우선 다음과 같이 해보자.

cd ~
# 사용자가 추가할 profile 파일을 넣을 directory 만들기
mkdir my.profile.d 
# 사용자가 추가할 bashrc 파일을 넣을 directory 만들기
mkdir my.bashrc.d 

/.profile 파일 마지막에 다음 내용을 추가하자. 그러면 /.profile이 호출될 때 ~/my.profile.d 속에 있는 설정 파일들이 차례로 함께 호출된다.

# ~/.profile
if [ -d "$HOME/my.profile.d" ]; then
  for i in "$HOME/my.profile.d/*" ; do
    if [ -r "$i" ]; then
      . "$i"
    fi
  done
  unset i
fi

같은 요령으로 /.bashrc 파일 마지막에 다음 내용을 추가하자. 그러면 /.bashrc가 호출될 때 ~/my.bashrc.d 속에 있는 설정 파일들이 차례로 함께 호출된다.

# ~/.bashrc
if [ -d ~/my.bashrc.d ]; then
  for i in ~/my.bashrc.d/* ; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

※ 따옴표 등을 잘못하면 에러가 날 수 있으므로 주의하자.

문제가 없는지 다음과 같이 테스트 해보자.

cd ~
source ~/.bashrc
source ~/.profile

이제 새로 추가할 환경 설정이 생기면 ~/my.profile.d이나 ~/my.bashrc.d 디렉토리 아래에 파일을 추가하여 처리하면 된다.

예를 들어 go 언어를 설치해야 한다면, 공식 문서 설명처럼 go binary 경로를 PATH에 등록시켜야 한다.

일반적인 방법처럼 ~/.profile에 직접 추가해야 할 때는 다음과 같이 해야 한다. ( 내용을 덧붙이므로 >>를 사용했다. )

echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile

하지만 우리는 추가된 설정 파일을 따로 관리하고자 하므로 ~/.profile를 수정하지 않고 다음과 같이 새로운 파일을 만들고 해당 내용을 넣어주기만 하면 된다. ( 파일을 만들고 내용을 쓰기 위해 >를 사용했다. )

echo 'export PATH=$PATH:/usr/local/go/bin' > ~/.my.profile.d/go

적용은 모두 아래와 같이 한다.

source ~/.profile

참고로 source 대신 아래와 같이 처리할 수도 있다.

. ~/.profile

참고

bash shell script foo.shbar.sh가 있다고 해보자. 아래와 같이 몇 가지 실행 방법이 있다. 어떤 차이가 있을까?

# in bash
# (1)
bash foo.sh    
# (2)
./foo.sh       
# (3)
source foo.sh  
# (4)
. foo.sh       

(1)과 (2)는 서로 같은 방법이고, (3)과 (4)도 서로 같은 방법이다. 하지만 (1)(2)와 (3)(4)는 서로 다르다.

앞의 (1)(2)는 현재 프로세스가 아닌 자식 프로세스에서 foo.sh를 실행시킨다. 따라서 현재 프로세스로 돌아오면 foo.sh의 정보를 사용할 수 없다.

반면 (3)(4)는 현재 프로세스에서 foo.sh를 실행시킨다.

만약 foo.sh 파일 내용이 다음과 같다면, 실행 결과가 서로 다르게 된다.

# foo.sh
#! /bin/bash
export MYNAME=WORLD
# `./foo.sh` or
bash foo.sh
echo $MYNAME
# 결과로 빈값을 출력한다. 
# `. foo.sh` or
source foo.sh
echo $MYNAME
# 결과로 "WORLD"를 출력한다. 

문제는 bar.sh 속에서 foo.sh를 호출할 때도 발생한다. bar.sh에서 foo.sh를 실행시킬지, 불러올지에 따라 결과가 달라지기 때문이다.

# bar.sh
#! /bin/bash
bash foo.sh
echo $MYNAME

이제 bash bar.sh라고 하면 빈값이 출력된다. bar.sh에서는 foo.sh에서 선언한 MYNAME이라는 변수가 더이상 존재하지 않기 때문이다.

# bar.sh
#! /bin/bash
source foo.sh
echo $MYNAME

반면 여기서 bash bar.sh라고 하면 “WORLD”라는 값이 출력된다. bar.sh에서 여전히 foo.sh에서 선언한 MYNAME를 사용할 수 있기 때문이다.

... ... ... ...
Back