LHJ

I'm a FE developer.

20.6 process

04 Jun 2020 » js_lj

20.6 process

실행 중인 노드 프로그램은 모두 process 변수에 접근할 수 있습니다.
이 변수는 해당 프로그램에 관한 정보를 담고 있으며 실행 자체를 컨트롤할 수도 있습니다.
예를 들어 애플리케이션이 치명적인 에러를 만나서, 계속 실행하지 않는 편이 좋거나 더 실행해도 의미가 없는 상황이라면(이런 에러를 fatal error라고 합니다) process.exit를 호출해 즉시 실행을 멈출 수 있습니다.

숫자형 종료 코드(exit code)를 쓰면 프로그램이 성공적으로 종료됐는지 에러가 있었는지 외부 스크립트에서도 알 수 있습니다.
보통 에러 없이 프로그램을 끝냈을 때는 종료 코드 0을 사용합니다.
종료 코드가 0이 아니라면 에러가 있었다는 뜻입니다.
data 서브디렉터리에 들어있는 .txt 파일을 모두 처리하는 프로그램이 있다고 합시다.
data 서브디렉터리에 .txt 파일이 없다면 프로그램을 즉시 멈춰야겠지만, 이건 에러가 아닙니다.
반면 data 서브디렉터리 자체가 존재하지 않으면 그건 더 진지하게 다뤄야 할 문제라고 판단하고, 에러와 함께 프로그램을 종료하려 합니다.
프로그램은 대략 다음과 같은 형태가 될 겁니다.

const fs = require('fs');

fs.readdir('data', function(err, files) {
    if (err) {
        console.error("Fatal error: couldn't read data directory.");
        process.exit(1);
    }
    const txtFiles = files.filter(f => /\.txt$/i.test(f));
    if (txtFiles.length === 0) {
        console.log("No .txt files to process.");
        process.exit(0);
    }
    // .txt 파일 처리
})

process 객체를 통해 프로그램에 전달된 명령줄 매개변수 배열에 접근할 수도 있습니다.
노드 애플리케이션을 실행할 때 명령줄에서 매개변수를 지정할 수 있습니다.
예를 들어 텍스트 파일을 처리하는 프로그램에 파일 이름을 매개변수로 넘기고 각 파일이 몇 행인지 출력한다고 합시다.
그런 프로그램이라면 다음과 같이 호출할 수 있을 겁니다.

node linecount.js file1.txt file2.txt file3.txt

명령줄 매개변수process.argv 배열에 저장됩니다.

argv라는 이름은 C언어에서 따왔습니다.
v는 배열과 비슷한 백터(vector)를 의미합니다.

파일이 몇 행인지 세기 전에 process.argv를 출력해서 어떤 형태인지 알아봅시다.

console.log(process.argv);

file1.txt, file2.txt, file3.txt 외에도 배열의 시작 부분에 몇 가지 다른 정보를 볼 수 있습니다.

['node', 
'/home/jdoe/linecount.js',
'file1.txt',
'file2.txt',
'file3.txt']

첫 번째 요소는 인터프리터, 즉 소스 파일을 해석한 프로그램입니다.
여기서는 node가 쓰였습니다.
두 번째 요소는 실행 중인 프로그램의 전체 경로이며, 나머지 요소는 프로그램에 전달된 매개변수입니다.
추가 정보는 필요 없으므로 Array.slice를 써서 걸러내겠습니다.

const fs = require('fs');

const filenames = process.argv.slice(2);

let counts = filenames.map(f => {
    try {
        const data = fs.readFileSync(f, {encoding: 'utf8'});
        return `${f}: ${data.split('\n').length}`;
    } catch(err) {
        return `${f}: couldn't read file`;
    }
});

console.log(counts.join('\n'));

process.env를 통해 환경 변수에 접근할 수도 있습니다.
환경 변수는 시스템 변수이며 주로 명령줄 프로그램에서 사용합니다.
대부분의 유닉스 시스템에서 export VAR_NAME=value 명령으로 환경 변수를 설정할 수 있습니다.
환경 변수는 보통 전부 대문자로 표기합니다.
윈도우에서는 set VAR_NAME=value 명령을 사용합니다.
환경 변수를 활용하면 프로그램을 실행할 때마다 명령줄에서 매개변수로 지정할 필요가 없습니다.

예를 들어 프로그램에서 디버그 정보를 기록할지 아닌지를 환경 변수로 컨트롤하려 한다고 합시다.
환경 변수 DEBUG를 1로 설정하면 디버그 정보를 기록하고, 다른 값은 무엇이든 디버깅 정보를 기록하지 않게 하려 합니다.

const debug = process.env.DEBUG === "1" ?
    console.log :
    function() {};

debug("Visible only if environment variable DEBUG is set!");

(위 사진처럼 process.env.DEBUG를 미리 1로 설정하고 그 후에 위 소스를 실행시키는 것일까?)

이 예제에서 debug 함수는 환경 변수 DEBUG가 1이면 console.log의 별칭이 되고, 그렇지 않다면 null 함수가 됩니다.
null 함수를 만들지 않으면 debug가 정의되지 않은 경우가 생기고 에러가 일어날 겁니다.

이전 섹션에서 현재 작업 디렉터리에 관해 언급했습니다.
현재 작업 디렉터리의 기본값은 프로그램을 실행한 디렉터리입니다(프로그램이 존재하는 디렉터리가 아닙니다).
process.cwd에는 현재 작업 디렉터리가 저장되며, process.chdir로 현재 작업 디렉터리를 바꿀 수 있습니다.
예를 들어 프로그램에서 현재 작업 디렉터리를 출력한 다음, 프로그램이 저장된 디렉터리로 현재 작업 디렉터리를 바꾸려면 다음과 같이 할 수 있습니다.

console.log(`Current directory: ${process.cwd()}`);
process.chdir(__dirname);
console.log(`New current directory: ${process.cwd()}`);