Linux 환경에서 전역변수(Global Variable)와 지역변수(Local Variable)의 차이점 비교
1. 정의
-
- 전역변수
- Shell이나 프로세스 전체에 영향을 미치는 변수.
- Bash에서는 export 명령어로 선언하여, 하위 프로세스에서도 사용할 수 있음.
- 예:
-
bashexport VAR="hello"
- 지역변수
- 현재 Shell이나 함수 내에서만 유효한 변수.
- 하위 프로세스나 다른 함수에서는 사용할 수 없음.
- 예:
-
bashlocal VAR="hello" # 함수 내부에서만 사용 VAR="hello" # export하지 않은 변수, 현재 shell 내에서만 유효
- 전역변수
2. 유효 범위(Scope)
| 전역변수 | 현재 shell + 하위 프로세스 |
| 지역변수 | 현재 shell 또는 함수 내부 |
3. 사용 예시
-
- 전역변수 예시
- PATH 변수는 모든 하위 shell에서 사용 가능
-
export PATH=$PATH:/usr/local/bin
- 지역변수 예시 (함수 내부)
-
bashmy_func() { local MESSAGE="Hello" echo $MESSAGE } my_func # "Hello" 출력 echo $MESSAGE # 아무것도 출력X
- 전역변수 예시
4. 생명주기
-
- 전역변수: Shell이 종료될 때까지 또는 변수 unset될 때까지 유지됨.
- 지역변수: 변수 정의된 범위(예: 함수)에서만 유지, 범위가 끝나면 소멸.
5. 보안성과 안정성
-
- 전역변수
- 여러 프로세스에서 접근 가능하므로, 실수로 값이 덮어쓰여질 위험이 있음.
- 지역변수
- Scope가 한정되어 있어, 의도치 않은 오염(outside modification) 위험이 적음.
- 전역변수
요약 표
| 선언 방법 | export VAR=값 | local VAR=값 (함수 내) |
| 접근 가능 범위 | 전체 shell, 하위 프로세스 | 해당 shell, 함수 내부 |
| 유지 기간 | shell 전체 | 범위(함수 등) 내 |
| 활용 용도 | 시스템 설정, 환경 변수 | 함수 내 임시 데이터 저장 |
===
"부모 프로세스(PPID)와 자식 프로세스(PID) 사이에 지역변수와 전역변수가 어떻게 전달되느냐?"
즉, 프로세스 간 변수(데이터)가 상속되는지를 묻는 것이죠.
🔹 결론부터 말하면
- 부모 프로세스(PPID)에서 선언한 지역변수(Local Variable), **전역변수(Global Variable)**는 **자식 프로세스(PID)로 '메모리 자체'는 그대로 복사(copy)**되지만 완전히 별개의 메모리 공간을 사용합니다.
- 즉, 지역변수와 전역변수 값은 초기 상태로는 복사되지만 변경 사항은 부모와 자식 간에 서로 영향을 주지 않습니다.
🔹 왜 그럴까? (fork / exec 동작 원리)
1. 프로세스 생성 시 메모리 구조 복사
Linux나 Unix 계열에서 프로세스 생성은 보통 다음처럼 이루어집니다.
- fork() 호출 → 부모 프로세스의 모든 메모리(코드, 데이터, 힙, 스택)를 복사하여 새로운 프로세스 생성
- 복사는 copy-on-write 방식: 실제로는 페이지를 공유하다가 변경 시에만 물리적으로 복사
- exec() 호출 시 → 해당 자식 프로세스의 메모리 공간은 완전히 새 프로그램으로 덮어쓰기
- 이 경우 부모 프로세스의 변수 값은 더 이상 의미 없음
2. 변수 전달 방식
| 지역변수 | 예 | 서로 영향 없음 |
| 전역변수 | 예 | 서로 영향 없음 |
| 환경변수 | 예 | 자식 초기 실행 시 상속, 수정은 각각 독립 |
| 파일 디스크립터 | 예 (공유) | 초기에는 공유하지만, 각각 닫을 수 있음 |
🔹 예시 코드
c
#include <stdio.h> #include <unistd.h> int global_var = 10; int main() { int local_var = 20; pid_t pid = fork(); if (pid == 0) { // child process global_var += 1; local_var += 1; printf("[Child] global_var=%d, local_var=%d\n", global_var, local_var); } else { // parent process sleep(1); // child 먼저 실행되게 함 printf("[Parent] global_var=%d, local_var=%d\n", global_var, local_var); } return 0; }
실행 결과 예시:
[Child] global_var=11, local_var=21
[Parent] global_var=10, local_var=20
→ 부모와 자식의 전역변수 및 지역변수는 처음에는 동일하지만, 변경해도 서로 영향을 주지 않음.
🔹 정리
- PPID → PID 관계에서 변수는 '값 복사'를 통한 상속이지, 메모리 공유가 아님
- 부모-자식 간에 변수로 직접 통신은 불가능 → 통신하려면 IPC(Inter-Process Communication, 예: 파이프, 소켓, 공유 메모리) 필요
- 환경변수(environment variable)는 초기 실행 시점에 부모에서 자식으로 복사됨
리눅스 셸 스크립트에서 전역변수와 지역변수의 가장 큰 차이점은 변수의 유효 범위입니다. 전역변수는 스크립트 전체와 하위 프로세스에 영향을 미치는 반면, 지역변수는 특정 함수나 블록 내에서만 유효합니다.
1. 전역변수 (Global Variable)
전역변수는 스크립트 내 어디서든 접근하고 수정할 수 있는 변수입니다.
- 정의: 함수 외부에서 정의하거나, 함수 내에서 export 명령어를 사용하여 정의합니다.
- 유효 범위: 스크립트의 모든 부분에서 유효하며, export된 경우 스크립트가 실행하는 모든 자식 프로세스에서도 유효합니다.
- 예시:위 스크립트를 실행하면 함수 내부와 외부 모두에서 GLOBAL_VAR의 값이 출력됩니다.
-
Bash
#!/bin/bash GLOBAL_VAR="This is a global variable." function show_global() { echo "Inside function: $GLOBAL_VAR" } show_global echo "Outside function: $GLOBAL_VAR"
2. 지역변수 (Local Variable)
지역변수는 특정 함수나 코드 블록 내에서만 유효한 변수입니다.
- 정의: 함수 내부에서 local 키워드를 사용하여 정의합니다.
- 유효 범위: 변수가 선언된 함수나 코드 블록 내부에서만 유효합니다. 함수가 종료되면 변수도 소멸됩니다.
- 예시:위 스크립트를 실행하면 함수 내부에서는 LOCAL_VAR가 출력되지만, 함수 외부에서는 해당 변수가 정의되지 않았다는 오류가 발생하거나 아무 값도 출력되지 않습니다. echo "Outside function: " 뒤에 아무것도 출력되지 않습니다.
-
Bash
#!/bin/bash GLOBAL_VAR="This is a global variable." function show_local() { local LOCAL_VAR="This is a local variable." echo "Inside function: $LOCAL_VAR" } show_local echo "Outside function: $LOCAL_VAR"
3. 주요 차이점 요약
| 특징 | 전역변수 (Global Variable) | 지역변수 (Local Variable) |
| 선언 방법 | VAR_NAME="value" | local VAR_NAME="value" |
| 유효 범위 | 스크립트 전체, 하위 프로세스 | 선언된 함수/블록 내부 |
| 변수 충돌 | 발생 가능성 높음 | 함수 간 변수명 충돌 방지 |
| 용도 | 스크립트 전반에 필요한 공유 데이터 | 함수 내 임시 데이터 처리 |
주의: local 키워드 없이 함수 내부에서 변수를 선언하면, 기본적으로 전역변수로 간주됩니다. 변수 충돌을 피하고 코드를 명확하게 만들기 위해 함수 내에서는 항상 local을 사용하는 것이 좋습니다.
문제 2: $? 변수의 이해
다음 셸 스크립트를 실행한 결과는 무엇인가요?
#!/bin/bash
# A. 존재하지 않는 파일에 대한 cat 명령 실행
cat non_existent_file.txt
# B. 명령의 종료 상태 코드 확인
echo "Command A exit code: $?"
# C. 성공하는 명령 실행
echo "Hello, world!"
# D. 다시 종료 상태 코드 확인
echo "Command C exit code: $?"
-
cat: non_existent_file.txt: No such file or directory Command A exit code: 1 Hello, world! Command C exit code: 0 -
cat: non_existent_file.txt: No such file or directory Command A exit code: 0 Hello, world! Command C exit code: 0 -
cat: non_existent_file.txt: No such file or directory Command A exit code: 1 Hello, world! Command C exit code: 1 -
cat: non_existent_file.txt: No such file or directory Command A exit code: 0 Hello, world! Command C exit code: 1
정답:
1번
해설:
- $?는 **가장 최근에 실행된 명령어의 종료 상태(exit status)**를 저장하는 특수 변수입니다. 명령어가 성공하면 0을 반환하고, 실패하면 0이 아닌 값(일반적으로 1)을 반환합니다.
- A: cat non_existent_file.txt는 존재하지 않는 파일에 접근하므로 실패하고, cat 명령은 오류 메시지를 출력한 후 1의 종료 상태 코드를 반환합니다.
- B: echo "Command A exit code: $?"는 바로 직전 명령어(cat)의 종료 상태인 **1**을 출력합니다.
- C: echo "Hello, world!"는 정상적으로 실행되므로 성공하고, 종료 상태 코드는 0이 됩니다.
- D: echo "Command C exit code: $?"는 바로 직전 명령어(echo)의 종료 상태인 **0**을 출력합니다.
문제 3: 스크립트 실행 방식의 차이
다음 두 가지 방식으로 my_script.sh를 실행했을 때, 환경 변수 MY_VAR의 값에 어떤 차이가 발생하는지 설명하세요.
방식 A: ./my_script.sh 방식 B: . my_script.sh 또는 source my_script.sh
my_script.sh 파일 내용:
#!/bin/bash
export MY_VAR="Hello, from script!"
echo "Inside script, MY_VAR is: $MY_VAR"
스크립트를 실행하기 전, 현재 셸의 환경 변수 MY_VAR은 설정되지 않았다고 가정합니다. 스크립트 실행 후, 터미널에서 echo $MY_VAR을 했을 때의 예상 결과와 그 이유를 설명하세요.
정답:
- 방식 A (./my_script.sh) 실행 후:
- echo $MY_VAR의 결과는 빈 값이거나, 이전에 설정된 값이 그대로 출력됩니다.
- 방식 B (. my_script.sh) 실행 후:
- echo $MY_VAR의 결과는 Hello, from script! 입니다.
해설:
- 방식 A (자식 프로세스): . 또는 source 없이 스크립트를 실행하면, 새로운 자식 프로세스가 생성되어 스크립트를 실행합니다. 스크립트 내에서 export된 환경 변수는 이 자식 프로세스에만 존재하며, 스크립트가 종료되면 자식 프로세스도 함께 종료되면서 변수도 소멸됩니다. 따라서 원래의 부모 셸(터미널)에는 MY_VAR 변수가 영향을 주지 않습니다.
- 방식 B (현재 셸): . 또는 source 명령어를 사용하면, 스크립트가 현재 실행 중인 셸에서 직접 실행됩니다. 스크립트 내에서 설정된 변수나 함수가 현재 셸의 환경에 그대로 반영됩니다. 따라서 export된 MY_VAR 변수는 터미널 세션에 그대로 남아 있게 됩니다.
'기타' 카테고리의 다른 글
| 06. FG BG nohup & (0) | 2025.08.28 |
|---|---|
| 05. 파일 복사 / 이동 (0) | 2025.08.28 |
| 04. 파일 권한 및 파일 관리 (2) | 2025.08.28 |
| 03. 프로세스 (관리) (0) | 2025.08.28 |
| 01. 계정/그룹 관리 (1) | 2025.08.28 |