set, env, export, source, exec 바보 구분 못 해?

6933 단어 linuxshell
당신 은 아래 의 몇 가지 문제 에 시 달 린 적 이 있 습 니까? 심지어 지금까지 진정 으로 이해 할 수 없 습 니까?
  • 무엇이 export 입 니까? export 를 언제 사용 합 니까? 왜 가끔 export 를 사용 합 니까?
  • 환경 변 수 를 왜 source 로 설정 하고 export 를 사용 하지 않 으 면 무슨 좋 은 점 이 있 습 니까?
  • envsource 는 어떤 차이 가 있 습 니까?

  • 본 고 는 유 닉 스 프로 세 스, 환경 변수 등 개념 을 보급 하여 독자 로 하여 금 이러한 셸 명령 의 본질 을 진정 으로 이해 하 게 하고 이러한 명령 의 사용 장 소 를 알 게 하려 고 한다.
    우선, 먼저 이 명령 들 에 대해 설명 을 하고 독자 가 완전히 이해 할 수 있다 면 본 고 는 당신 에 게 큰 도움 이 되 지 않 을 것 입 니 다.
  • 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 로 환경 변 수 를 설정 한 후에 실 행 된 스 크 립 트 에서 다른 스 크 립 트 를 호출 했 습 니 다. 이 환경 변 수 는 계승 할 수 있 습 니까?

    좋은 웹페이지 즐겨찾기