set, env, export, source, exec 바보 구분 못 해?
export
입 니까? export 를 언제 사용 합 니까? 왜 가끔 export 를 사용 합 니까?source
로 설정 하고 export 를 사용 하지 않 으 면 무슨 좋 은 점 이 있 습 니까?env
와 source
는 어떤 차이 가 있 습 니까?본 고 는 유 닉 스 프로 세 스, 환경 변수 등 개념 을 보급 하여 독자 로 하여 금 이러한 셸 명령 의 본질 을 진정 으로 이해 하 게 하고 이러한 명령 의 사용 장 소 를 알 게 하려 고 한다.
우선, 먼저 이 명령 들 에 대해 설명 을 하고 독자 가 완전히 이해 할 수 있다 면 본 고 는 당신 에 게 큰 도움 이 되 지 않 을 것 입 니 다.
exec
현재 셸 프로 세 스 set
를 설 정 했 습 니 다. 로 컬 변 수 는 현재 셸 프로 세 스 에서 만 유효 하 며 하위 프로 세 스 에 의 해 계승 되 고 전달 되 지 않 습 니 다.
실행 할 하위 프로 세 스 만 설정 합 니 다 env
.
셸 로 컬 변 수 를 현재 셸 프로 세 스 export
로 올 려 서 하위 프로 세 스 가 자동 으로 계승 하지만 export 변 수 는 부모 프로 세 스 의 환경 변 수 를 바 꿀 수 없습니다.
스 크 립 트 를 실행 할 때 새 셸 프로 세 스 를 사용 하지 않 고 현재 셸 프로 세 스 환경 에서 스 크 립 트 를 실행 합 니 다.source
스 크 립 트 나 명령 을 실행 할 때 새로운 셸 프로 세 스 를 사용 하지 않 고 exec 후속 스 크 립 트 내용 이 실행 되 지 않 습 니 다. 즉, 현재 셸 프로 세 스 가 끝 났 습 니 다.이런 표현 에서
exec
과
의 개념 을 반복 적 으로 언급 했다.그 의 미 를 깊이 이해 하려 면 프로 세 스 의 관련 개념 도 이해 해 야 한다.프로 세 스 와 환경 변수
프로 세 스 는 프로그램 이 실행 하 는 문맥 집합 입 니 다. 이 집합 은 프로그램 코드, 데이터 세그먼트, 스 택, 환경 변수, 커 널 표지 프로 세 스 의 데이터 구조 등 을 포함 합 니 다.하나의 프로 세 스 는 다른 프로 세 스 를 생 성 할 수 있 습 니 다. 생 성 된 프로 세 스 를
라 고 부 르 면 해당 하 는 것 은
이 있 습 니 다. 이른바 자손 이 무궁무진 합 니 다.
에서 일부 유전 적 요 소 를 계승 하 는데 그 중에서 본 고의 주제
를 포함한다.환경 변 수 는 특수 한 문자 형 변수 로 계승 성 을 가지 기 때문에 환경 변 수 는 부자 프로 세 스 가 매개 변 수 를 전달 하 는 데 자주 사용 된다 는 점 은 셸 프로 그래 밍 에서 특히 두드러진다.fork 와 exec
유 닉 스 시스템 에서 프로 세 스 는 순서대로 호출
과 fork()
시스템 호출 을 통 해 하위 프로 세 스 를 만 듭 니 다.exec()
사실은 fork
인 데 왜 github 이 다른 사람의 프로젝트 를 포크 라 고 부 릅 니까?이렇게 왔 습 니 다. '클론' 이란 현재 프로 세 스 의 모든 메모리 미 러 를 메모리 에 복사 하 는 것 입 니 다. 모든 것 이 똑 같 습 니 다. 새 프로 세 스 의 프로 세 스 번호 (PID) 만 수정 하 는 것 입 니 다.세포 분열 과 비슷 하 다. 세포 가 분 단 된 후 생 성 된 세 포 는 원 세포 와 똑 같은 유전 적 요인 을 가지 고 있다.
프로 세 스 가 어떤 코드 로 실행 되 는 지 를 포함 하여 전체 프로 세 스 를 복사 하기 때문에 새로운 프로 세 스 가 fork()
뒤의 코드 를 계속 실행 하고 부모 프로 세 스 도 fork()
뒤의 코드 를 실행 하 며 fork()
부터 부자 프로 세 스 가 갈 라 집 니 다.포크 가 > 0 으로 돌아 가면 부모 프로 세 스에 서, 포크 가 = = 0 으로 돌아 가면 하위 프로 세 스에 서 설명 합 니 다:pid = fork();
if(pid == 0) {
//
} else if(pid > 0) {
//
}
정확하게 말 하면
fork()
은 함수 의 통칭 이 고 exec
의 정확 한 정 의 는 디스크 에 있 는 새로운 프로그램 으로 현재 프로 세 스 의 본문 세그먼트, 데이터 세그먼트, 스 택 세그먼트 를 교체 하 는 것 이다.그래서 exec 는 새로운 프로 세 스 를 만 들 지 않 고 교체 합 니 다.이렇게 되면 프로 세 스 는 새 코드 의 main 에서 실 행 됩 니 다. 완전히 다른 프로그램 을 실행 하 는 것 과 같 지만 원래 환경 변 수 를 유지 합 니 다.본 논문 의 주제 에 따라
exec
함 수 를 두 가지 로 나 눌 수 있다. 하 나 는 새로운 환경 변 수 를 설정 하고 전달 할 수 있 고 하 나 는 새로운 환경 변 수 를 전달 할 수 없 으 며 원래 환경 변 수 를 계승 할 수 밖 에 없다.새로운 프로그램 을 실행 할 때 계승 만 이 아니 라 새로운 프로그램의 환경 변 수 를 바 꿀 수 있 는 기회 가 있다 는 얘 기다.아래 의 이 변종 과 같이 exec
매개 변 수 를 통 해 환경 변 수 를 설정 할 수 있 습 니 다.int execve(const char * filename,char * const argv[ ],char * const envp[ ]);
부모 프로 세 스 의 경우
envp
함 수 를 통 해 하위 프로 세 스 가 종료 되 기 를 기다 리 고 종료 상 태 를 얻 을 수 있 습 니 다.프로 세 스 는
waitpid()
또는 setenv
을 통 해 자신의 환경 변 수 를 변경 할 수 있 지만 환경 변수의 계승 은 단 방향, 즉 부모 프로 세 스 에서 putenv
나 온 하위 프로 세 스 에 만 계승 할 수 있 습 니 다.하위 프로 세 스 는 자신의 환경 변 수 를 수정 하 더 라 도 부모 프로 세 스 의 환경 변 수 를 흔 들 수 없습니다.shell
셸 은 특별한 프로 세 스 가 아 닙 니 다. 명령 행 에 명령 을 입력 하고
fork
을 누 르 면 셸 프로 세 스 는 fork 와 exec 를 통 해 하위 프로 세 스 를 만 듭 니 다.그러면 프로 세 스 의 메모리 미 러 는 분명히 본 고의 주제 Enter
를 포함한다.예 를 들 어 만약 에 우리 가 셸 명령 행 에서 build-in
을 실행한다 면 셸 은 실제 적 으로 다음 과 같은 위조 코드 를 실행한다.pid = fork();
if(pid == 0) {
// , exec
exec("ls -al");
} else if(pid > 0) {
// ,waitpid
waitpid(pid);
}
셸 이 명령 을 수행 하 는 상황 에 대해 논 의 했 습 니 다. 명령 행 에서 셸 스 크 립 트 를 실행 하면 요?기본적으로 셸 프로 세 스 는 셸 스 크 립 트 를 실행 하기 위해 sub - shell 하위 프로 세 스 를 만 들 고 이 하위 프로 세 스 가 끝 날 때 까지 기 다 립 니 다.
마지막 으로 본문의 주 제 를 다시 한 번 살 펴 보 자.우선 set, source, export 는 셸 의 build - in 명령 으로 명령 자체 에 새 프로 세 스 를 만 들 지 않 습 니 다.
사실은 프로 세 스 생 성과 상 관 없 이 환경 변수 와 상 관 없 이 현재 셸 프로 세 스 내부 유지 변수 (로 컬 변수) 일 뿐 변수의 인용 과 전개 에 사용 되 며 유전 과 계승 이 불가능 합 니 다.그러나 셸 의
ls -al
명령 은 호출 set
을 통 해 로 컬 변 수 를 현재 셸 의 환경 변수 로 향상 시 킬 수 있 습 니 다.그러나 환경 변수의 계승 은 단 방향 일 뿐 export
에서 putenv
의 변 수 는 부모 셸 에서 볼 수 없다 는 것 을 기억 하 라.스 크 립 트 의 export 를 부모 프로 세 스 의 환경 변 수 를 인상 할 수 있 는 방법 은 무엇 입 니까?정 답 은 source 를 사용 하여 스 크 립 트 를 실행 하 는 것 입 니 다.
sub-shell
의 용법 은 다음 과 같 습 니 다.source ./test.sh
스 크 립 트 를
export
로 실행 하면 fork 와 exec 가 호출 되 지 않 음 을 의미 합 니 다. 현재 셸 은 test. sh 에 대해 직접 설명 합 니 다.이 경우 test. sh 에 export (즉 puutenv) 가 있 으 면 현재 셸 의 환경 변 수 를 바 꿉 니 다.source
이렇게 좋 은 데 문 제 는 그 후의 모든 명령 에 영향 을 줄 수 있다 는 것 이다. 어떤 명령 을 실행 할 때 환경 변 수 를 임시로 사용 하고 뒤의 명령 에 영향 을 주지 않 을 수 있 는 방법 이 없 을 까?정 답 은 사용
source
, export
의 용법 은 다음 과 같다.env GOTRACEBACK=crash ./test.sh
env 는 셸 의 build - in 명령 이 아니 므 로 셸 이 env 를 실행 할 때 하위 프로 세 스 를 만들어 야 합 니 다.
env 의 역할 은 본질 적 으로 셸 이 먼저 fork 를 한 다음 에 하위 프로 세 스에 서 env 를 실행 하 는 것 과 같 습 니 다. 하위 프로 세 스 env 호출
env
이 실 행 될 때 env
환경 변 수 를 하나 더 전 달 했 습 니 다.부모 셸 의 환경 변 수 를 바 꾸 기 때문에 후속 으로 시작 하 는 프로 세 스 는 계승 되 지 않 습 니 다 execve
.test.sh
포크 를 호출 하지 않 고 exec 를 직접 호출 하여 실행 하 는 것 을 의미 합 니 다!이것 은 현재 셸 의 코드 가 exec 에 실 행 된 후에 코드 가 exec 가 실행 할 프로그램 으로 바 뀌 었 음 을 의미 합 니 다. 자 연 스 럽 게 후속 셸 스 크 립 트 는 실행 되 지 않 습 니 다. 셸 자체 가 바 뀌 었 기 때 문 입 니 다.위의 그림 의 env 는 실제 적 으로 정확 하지 않다. 왜냐하면 env 는 build - in 명령 이 아니 기 때문에 독자 가 스스로 뇌 보 할 수 있다.
응, 이론 적 으로 만 이해 하면 소화 가 잘 안 될 수도 있어. 차라리 '실습 + 사고' 를 하 는 게 인상적 이 야.
문제 1: 간단 한 script 두 개 를 쓰 고 각각 1. sh 와 2. sh 라 고 명명 합 니 다.
1.sh
#!/bin/bash
A=B
echo "PID for 1.sh before exec/source/fork:$$"
export A
echo "1.sh: \$A is $A"
case $1 in
exec)
echo "using exec…"
exec ./2.sh;;
source)
echo "using source…"
../2.sh;;
*)
echo "using fork by default…"
./2.sh;;
esac
echo "PID for 1.sh after exec/source/fork:$$"
echo "1.sh: \$A is $A"
2.sh
#!/bin/bash
echo "PID for 2.sh: $$"
echo "2.sh get \$A=$A from 1.sh"
A=C
export A
echo "2.sh: \$A is $A"
그 다음 에 다음 과 같은 매개 변 수 를 달 려 결 과 를 관찰 합 니 다.
$ ./1.sh fork
$ ./1.sh source
$ ./1.sh exec
문제 2: env 로 환경 변 수 를 설정 한 후에 실 행 된 스 크 립 트 에서 다른 스 크 립 트 를 호출 했 습 니 다. 이 환경 변 수 는 계승 할 수 있 습 니까?
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
용감한 바로 가기 및 우분투 응용 프로그램안녕하세요 여러분, 이 기사에서는 모든 사이트에서 pwa를 생성하고 실행기 응용 프로그램으로 추가하는 방법을 설명하고 싶습니다. 일부 웹사이트는 PWA로 설치를 허용하지 않지만 유사한 애플리케이션을 원합니다. 1. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.