본문 바로가기
리눅스/Part 1 - Learning The Shell

리눅스 기초 | 6. 리디렉션

by 객잔주인 2024. 5. 23.

 

해당 포스팅은 William E. Shotts, Jr.의 오픈소스 저서 The Linux Command Line(링크)를 번역한 내용입니다


이번 강의에서는 커맨드 라인에서 아마 가장 멋진 기능에 대해 알아볼 것입니다. 바로 I/O 리디렉션(redirection)입니다. "I/O"는 input/output의 약자이고 이 기능을 이용하면 파일에 대한 명령의 입력과 출력을 리디렉션하거나 명령을 연결하여 강력한 명령 파이프라인(pipeline)을 만들 수 있습니다. 이 기능을 사용하기 위해서 다음과 같은 명령어들을 알아보겠습니다:

  • $\texttt{cat}$ - 파일들을 연결
  • $\texttt{sort}$ - 텍스트를 정렬
  • $\texttt{uniq}$ - 중복되는 항목 제거
  • $\texttt{grep}$ - 패턴과 일치하는 부분 출력
  • $\texttt{wc}$ - 파일의 줄 수, 단어 수, 바이트 수를 출력
  • $\texttt{head}$ - 파일의 첫 부분을 출력
  • $\texttt{tail}$ - 파일의 마지막 부분을 출력
  • $\texttt{tee}$ - 표준 입력을 읽어 표준 출력과 파일에 동시에 쓰는 역할

표준 입력, 출력, 에러

우리가 지금까지 사용한 많은 프로그램들은 어떤 종류의 출력을 생성합니다. 이 출력은 주로 두 가지 타입으로 구성됩니다:

  • 프로그램이 만들어내는 데이터
  • 상태 혹은 에러 메시지

$\texttt{ls}$ 명령어를 보면 명령의 실행 결과나 에러 메시지를 화면에 출력합니다.

 

유닉스의 "모든 것은 파일이다"의 관점을 고수하자면, $\texttt{ls}$와 같은 프로그램은 특수한 파일인 표준 출력(standard output)(종종 stdout으로 쓰이기도 함)으로 실행 결과를 전송하고, 상태 메시지는 또 다른 파일 표준 에러(standard error)(또는 stderr)으로 전송합니다. 기본적으로 표준 출력과 표준 에러는 화면과 연결되어있고 디스크 파일에 저장되지 않습니다.

 

또한 많은 프로그램은 기본적으로 키보드와 연결되어 있는 표준 입력(standard input)(또는 stdin)으로부터 입력을 받습니다.

 

I/O 리디렉션은 입력 위치와 출력 위치를 변경할 수 있도록 해줍니다. 일반적으로 출력은 화면으로 가고, 입력은 키보드로부터 받습니다. 그러나 I/O 리디렉션을 사용하면 그것을 바꿀 수 있습니다.

표준 출력 리디렉션

I/O 리디렉션은 표준 출력의 목적지를 바꿀 수 있습니다. 표준 출력의 목적지를 화면 대신 다른 파일로 바꾸고 싶다면 리디렉션 연산자 $\texttt{>}$뒤에 파일 이름을 붙입니다. 리디렉션을 왜 하냐구요? 종종 출력된 결과를 파일에 저장해두는게 유용할 때가 있습니다. 예를 들어, 쉘에게 $\texttt{ls}$ 명령의 결과를 화면에 띄우는 대신 "ls-output.txt" 파일에 저장하라고 명령하려면 다음과 같이 입력합니다:

여기서 우리는 /usr/bin 디렉토리의 내용 목록을 ls-output.txt 파일로 전송했습니다. 리디렉션된 출력을 살펴보겠습니다:

좋습니다, 큰 텍스트파일이군요. $\texttt{less}$를 이용해 파일을 살펴보면 ls-output.txt가 $\texttt{ls}$ 명령어의 결과를 저장하고 있는 것을 볼 수 있습니다.

리디렉션 실험을 또 한 번 해보겠습니다. 이번엔 조금 꼬아보겠습니다. 디렉토리 이름을 존재하지 않는 디렉토리로 입력해보겠습니다:

에러 메시지를 받았군요. 존재하지 않는 디렉토리 /bin/usr를 입력했기 때문에 당연합니다. 그런데 왜 에러 메시지가 ls-output.txt에 저장되는 대신 화면에 출력이 되었을까요? 답은, $\texttt{ls}$ 프로그램이 표준 출력으로 에러 메시지를 전송하지 않기 때문입니다. 대신 다른 유닉스 프로그램들 처럼 에러 메시지를 표준 에러로 전송합니다. 우리가 표준 출력만들 리디렉션 했기 때문에 에러 메시지는 화면으로 전송되는 것입니다. 표준 에러를 리디렉션 하는 방법에 대해서는 잠시 후에 알아보도록 하고, 지금은 출력 파일에 어떤 일이 생겼는지 확인해보겠습니다:

이제 파일에 아무것도 없네요! 이는 ">"을 이용해 출력을 리디렉션하면 목적 파일이 처음부서 새로 쓰여지기 때문입니다. $\texttt{ls}$ 명령어가 아무 결과 없이 에러만 출력했기 때문에 리디렉션 연산자는 파일을 새로 쓰기 시작했고 에러 메시지를 받고 멈췄기 때문에 모든 내용이 잘려나간 것입니다. 파일을 잘라내야하거나 비어있는 파일을 새로 만들어야 할 때 다음과 같은 트릭을 쓸 수 있습니다:

앞에 아무런 명령어 없이 리디렉션 연산자만 사용하면 기존 파일의 내용을 지우거나 새로운 파일을 생성합니다.

 

그러면 새로운 결과를 덮어쓰지 않고 기존 내용에 이어서 쓰려면 어떻게 해야할까요? 그건 ">>" 연산자를 사용하면 됩니다:

">>" 연산자는 출력이 파일에 추가되도록 해줍니다. 파일이 존재하지 않는다면 ">"를 사용한 것처럼 새로 만들어냅니다. 한 번 실험을 해보죠:

명령을 세 번 반복했더니 세 배 큰 파일이 만들어졌습니다.

표준 에러 리디렉션

표준 에러 리디렉션은 전용 연산자가 없어 편의성이 조금 떨어집니다. 표준 에러의 리디렉션을 위해서는 파일 디스크립터(file descriptor)를 명시해주어야합니다. 프로그램은 여러 개의 번호가 매겨진 파일 스트림을 통해 출력을 생성할 수 있습니다. 이 파일 스트림의 첫 세 개를 표준 입력, 출력, 에러라고 하고 쉘은 이들을 내부적으로 파일 디스크립터 0, 1, 2로 참조합니다. 쉘은 파일 디스크립터 번호로 파일을 리디렉션 할 수 있도록 해줍니다. 표준 에러는 파일 디스크립터 번호 2번 이므로 다음과 같이 표준 에러를 리다이렉트 할 수 있습니다:

파일 디스크립터 "2"가 리디렉션 연산자 바로 앞에 놓이면 ls-error.txt로의 표준 에러 리디렉션이 일어납니다.

표준 출력과 표준 입력을 하나의 파일에 리디렉션

명령의 모든 출력을 하나의 파일에 담고 싶은 경우가 있습니다. 이를 위해 우리는 표준 출력과 표준 에러를 동시에 리다이렉트 해야합니다. 동시에 리다이렉트 하는 것은 두 가지 방법이 있습니다. 다음은 구 버전 쉘에서 동작하는 전통적인 방법입니다.

이 방법을 사용하면 두 개의 리디렉션이 일어납니다. 먼저 표준 출력을 ls-output.txt로 리다이렉트 하고, 그 다음으로 2>&1 표기를 통해 파일 디스크립터 2(표준 에러)를 파일 디스크립터 1(표준 출력)로 리다이렉트 합니다.

리디렉션의 순서가 중요함을 알아두세요. 표준 에러의 리디렉션은 항상 표준 출력 리디렉션 뒤에 일어나야합니다. 그렇지 않으면 동작하지 않습니다. 다음 예시는 표준 에러를 ls-output.txt 파일로 리다이렉트 합니다:

$\texttt{>ls-output.txt 2>&1}$

그러나 다음 명령은 동작하지 않습니다:

$\texttt{2>&1 >ls-output.txt}$

 

최신 버전의 $\texttt{bash}$는 다음과 같이 보다 간소한 리디렉션 방법을 제공합니다:

위 예시에서는 $\texttt{&>}$ 표기를 사용해 표준 출력과 표준 에러를 $\texttt{ls-output.txt}$ 파일에 리다이렉트 합니다. $\texttt{&>>}$를 사용하면 표준 출력과 표준 에러를 한 파일에 추가 할 수 있습니다:

원치 않는 출력 처리

때로는 '침묵이 금'일 때가 있는데, 명령의 출력을 원하지 않고 그냥 버리고 싶을 때가 있습니다. 특히 에러 메시지와 상태 메시지가 이에 해당합니다. 이를 위해서 시스템은 특수한 파일인 "/dev/null"에 출력을 리다이렉트합니다. 이 파일은 빗버킷(bit bucket)이라고 불리며 입력을 받고 아무것도 하지 않는 시스템 장치 입니다. 명령에 대한 에러 메시지를 감추고 싶을 때 다음과 같이 입력합니다:

유닉스 문화에서의 /dev/null

빗버킷은 고대 유닉스 개념으로, 그 보편성 때문에 유닉스 문화의 많은 부분에서 등장했습니다. 누군가 당신의 의견을 $\texttt{/dev/null}$로 보냈다고 말한다면... 무슨 뜻인지 아시겠죠? 더 많은 예시를 보고 싶다면 여기를 방문하세요

표준 입력 리디렉션

아직까지 표준 입력을 사용하는 명령어에 대해 만나보지 못했습니다(사실 만나긴 했는데 이 서프라이즈는 잠시 후에 공개하겠습니다). 그러니 이제 하나를 배워보겠습니다.

$\texttt{cat}$ - 파일 이어붙이기

$\texttt{cat}$ 명령어는 하나 이상의 파일을 읽어 표준 출력에 복사합니다:

대부분의 상황에서 $\texttt{cat}$이 DOS에서의 $\texttt{TYPE}$ 명령어와 유사하게 작동합니다. 이 명령어를 사용하면 페이징(paging, 내용을 전부 표시하지 않고 한 페이지씩 보여주는 방식) 없이 파일 내용을 볼 수 있습니다. 예를 들어, 다음 명령을 입력하면 $\texttt{ls-output.txt}$ 파일의 내용을 볼 수 있습니다:

$\texttt{cat}$은 주로 내용이 짧은 파일을 읽을 때 사용됩니다. $\texttt{cat}$은 두 개 이상의 파일을 인자로 받을 수 있으므로 파일들을 합칠 때에도 사용할 수 있습니다. 여러 파트로 나뉜 큰 파일을 다운로드 받았는데 이 파일을 다시 하나로 합치고 싶다고 가정해보겠습니다. 파일들의 이름이 다음과 같다면:

다시 이 파일들을 하나로 합치기 위해 아래 명령을 입력할 수 있습니다:

와일드카드는 항상 정렬된 상태로 결과를 반환하기 때문에 인자들이 알맞는 순서로 배열될 것입니다.

 

모든 것이 순조롭습니다. 하지만 이것이 표준 입력과 어떤 상관이 있을까요? 아직은 없습니다. 그러니 이제 다른 것을 시도해보죠. 만약 $\texttt{cat}$을 아무런 인자 없이 입력하면 어떻게 될까요?

아무 것도 하지 않는 것처럼 보입니다. 하지만 사실은 해야할 일을 완벽하게 수행하고 있습니다.

 

$\texttt{cat}$이 인자 없이 입력되면 표준 입력을 읽습니다. 그런데 표준 입력이 기본적으로 키보드와 연결되어있기 때문에 우리의 입력을 기다리고 있는 것입니다! 아래 텍스트를 입력하고 엔터를 친 다음 어떤 일이 일어나는지 보세요:

다음으로 $\texttt{Ctrl-d}$를 입력해서 $\texttt{cat}$이 표준 입력의 EOF(end of file)에 도달했다고 알려줍니다:

파일명 인자가 주어지지 않았을 때 $\texttt{cat}$은 표준 입력을 표준 출력으로 복사하기 때문에 우리가 입력한 텍스트를 그대로 반복한 것을 볼 수 있는 것입니다. 이 동작을 이용해서 짧은 텍스트 파일을 만들 수 있습니다. 위에서 작성한 텍스트가 저장된 $\texttt{lazy_dog.txt}$라는 파일을 만들고 싶다고 가정할 때 다음과 같이 작성할 수 있습니다:

명령을 입력한 뒤에 우리가 파일에 저장하고자 하는 텍스트를 입력합니다. 마지막에 $\texttt{Ctrl-d}$를 입력하는 것을 잊지 마세요. 방금 우리는 커맨드 라인을 사용해서 세상에서 가장 멍춍한 워드 프로세서를 이용해보았습니다! 결과를 보기 위해서 다시 한 번 $\texttt{cat}$을 사용해서 파일을 stdout으로 복사하면 됩니다.

$\texttt{cat}$이 어떻게 표준 입력과 파일명 인자를 받는지 알았으니, 이제 표준 입력을 리다이렉트 해보겠습니다.

$\texttt{<}$ 리디렉션 연산자를 사용하면 표준 입력의 소스(source)를 키보드에서 $\texttt{lazy_dog.txt}$ 파일로 변경할 수 있습니다. 결과가 파일명을 인자로 넣을 것과 똑같은 것을 확인할 수 있습니다. 파일명을 인자로 전달하는 것에 비해 이점은 없지만 파일을 표준 입력의 소스로 사용하는 방법을 잘 보여줍니다. 곧 설명하겠지만 표준 입력을 더 잘 활용하는 다른 명령어들이 존재합니다.

 

다음으로 넘어가기 전에 $\texttt{cat}$의 매뉴얼 페이지를 열어 흥미로운 옵션들을 살펴보세요.

파이프라인

명령어들이 표준 입력으로부터 데이터를 읽고 표준 출력으로 전송하는 것이 가능한 것은 파이프라인(pipelines)이라는 쉘의 기능 덕분입니다. 파이프 연산자 $\texttt{|}$ (수직 바)를 사용하면 한 명령어의 표준 출력이 다른 명령어의 표준 입력으로 수송됩니다.

이것을 완전하게 실행하기 위해서 몇 가지 명령어들이 필요합니다. 이전에 표준 입력을 사용하는 명령어를 이미 한 번 만나보았다는 이야기를 기억하시나요? 그것은 바로 $\texttt{less}$입니다. $\texttt{less}$를 사용하면 표준 출력으로 결과를 전송하는 모든 명령어의 출력을 페이지 단위로 화면에 띄울 수 있습니다:

굉장히 편리한 기능입니다! 이 테크닉을 활용하면 표준 출력을 생성하는 모든 명령어의 출력을 아주 쉽게 볼 수 있습니다.

$\texttt{>}$와 $\texttt{|}$의 차이

처음엔 리디렉션 연산자 $\texttt{>}$와 파이프라인 연산자 $\texttt{|}$의 리디렉션에 어떤 차이가 있는지 알기 어렵습니다. 쉽게 말해서, 리디렉션 연산자 $\texttt{>}$는 명령어와 파일을 연결하고, 파이프라인 연산자 $\texttt{|}$는 명령어의 출력을 다음 명령어와 연결합니다.
$\texttt{command1 > file1}$
$\texttt{command1 | command2}$
많은 사람들이 파이프라인을 배우는 과정에서 $\texttt{command1 > command2}$를 시도하면서 "무슨 결과가 나올까?" 궁금해합니다

정답: 아주 안좋은 일이 일어날 수 있습니다.

여기 리눅스 기반의 서버 설비를 관리하던 독자의 실제 사례를 보겠습니다. 슈퍼유저 권한에서 그는 다음과 같은 명령을 실행했습니다:
$\texttt{# cd /usr/bin}$
$\texttt{# ls > less}$
첫 번째 명령은 대부분의 프로그램이 저장된 디렉토리로 작업 디렉토리를 옮기고, 두 번째 명령은 쉘에게 파일 $\texttt{less}$를 $\texttt{ls}$ 명령어의 출력으로 덮어쓰라고 지시합니다. $\texttt{/usr/bin}$ 디렉토리에는 이미 $\texttt{less}$ 프로그램 파일이 있었기 때문에 두 번째 명령어는 $\texttt{less}$ 프로그램 파일을 $\texttt{ls}$의 출력으로 덮어썼고 $\texttt{less}$는 망가져버렸습니다.

여기서 얻을 수 있는 교훈은 리디렉션 연산자는 조용히 파일을 생성하거나 기존 파일을 덮어쓰기 때문에 사용에 신중을 기해야 한다는 것입니다.

필터

파이프라인은 데이터에 복잡한 조작을 할 때 종종 사용됩니다. 여러 개의 명령어를 파이프라인에 넣는 것도 가능합니다. 이렇게 사용하는 명령을 필터(filters)라고 부릅니다. 필터는 입력을 받아 변환을 한 뒤에 출력합니다. 처음 사용해볼 것은 $\texttt{sort}$입니다. $\texttt{/bin}$과 $\texttt{/usr/bin}$에 있는 모든 실행 가능한 프로그램들의 목록을 종합하여 정렬한 결과를 보고 싶다고 할 때 이렇게 입력할 수 있습니다.

두 개의 디렉토리($\texttt{/bin}$과 $\texttt{/usr/bin}$)를 명시했기 때문에 $\texttt{ls}$의 출력은 각 디렉토리에서 리스트 한 개씩, 총 두 개의 정렬된 리스트를 얻을 수 있습니다. 파이프라인에 $\texttt{sort}$를 넣어주었기 때문에 리스트는 하나의 정렬된 리스트가 됩니다.

 

$\texttt{uniq}$ - 중복되는 항목 제거

$\texttt{uniq}$ 명령어는 $\texttt{sort}$와 연결되어 사용되는 경우가 잦습니다. $\texttt{uniq}$는 표준 입력 또는 단일 파일명 인자로부터 정렬된 데이터 리스트를 입력받아 리스트에 중복되는 항목을 제거합니다. 리스트에서 중복되는 항목($\texttt{/bin}$과 $\texttt{/usr/bin}$ 양쪽에 존재하는 프로그램)을 제거하기 위해서 위에서 정의한 파이프라인에 $\texttt{uniq}$를 추가하겠습니다.

이 예시에서 $\texttt{sort}$ 명령어의 출력에 존재하는 중복을 제거하기 위해 $\texttt{uniq}$를 사용했습니다. 만약 중복되는 항목들을 보고싶은 경우라면 $\texttt{uniq}$ 명령어에 $\texttt{-d}$ 옵션을 추가하면 됩니다:

$\texttt{wc}$ - 줄, 단어, 바이트(Byte) 수를 출력

$\texttt{wc}$ (word count) 명령어는 줄, 단어, 그리고 바이트 수를 볼 때 사용합니다.

이 경우는 $\texttt{ls-output.txt}$의 내용의 줄, 단어, 그리고 바이트 수를 표시합니다. 이전에 배운 명령어들 처럼 $\texttt{wc}$를 인자 없이 사용하면 표준 입력을 입력받습니다. "$\texttt{-l}$" 옵션은 출력 결과를 줄 수로 제한합니다. 파이프라인에 이를 추가하면 수를 편리하게 셀 수 있습니다. 목록에 있는 항목의 수를 보기위해 다음과 같이 입력합니다:

$\texttt{grep}$ - 패턴과 일치하는 줄 출력

$\texttt{grep}$은 파일내의 텍스트 패턴을 찾아주는 강력한 프로그램입니다. 이는 다음과 같이 사용됩니다:

$\texttt{grep}$이 파일안에서 "pattern"을 만나면, 그 패턴을 포함하는 줄을 출력합니다. $\texttt{grep}$는 복잡한 패턴도 매칭시킬 수 있지만 지금은 간단한 예들만 보겠습니다. 챕터 19에서 정규 표현식(regualr expressions)이라고 하는 더 진보된 패턴도 살펴볼 것입니다.

 

프로그램 리스트에서 $\texttt{zip}$이라는 단어가 파일명에 포함된 모든 파일들을 찾고 싶다고 가정하겠습니다. 이는 시스템에 상의 파일 압축과 관련된 프로그램을 찾는 데 유용할 수 있습니다.

$\texttt{grep}$에는 유용한 옵션이 두 가지 있습니다:

  • $\texttt{-i}$: $\texttt{grep}$이 대소문자를 구분하지 않고 검색하도록 합니다. 이 옵션을 사용하지 않으면 대소문자를 구분하여 검색합니다
  • $\texttt{-v}$: $\texttt{grep}$이 패턴과 일치하지 않는 줄만 출력하도록 합니다.

$\texttt{head / tail}$ - 파일의 첫 부분과 마지막 부분을 출력

어떤 경우에 우리는 명령의 출력된 결과가 모두 필요하지 않을 수 있습니다. 첫 몇 줄이나 마지막 몇 줄만 필요할 수도 있죠. $\texttt{head}$는 처음 열 줄만 출력하고, $\texttt{tail}$은 마지막 열 줄만 출력합니다. 기본적으로 두 명령어는 열 줄씩 출력하지만 $\texttt{-n}$ 옵션을 이용하면 이를 조정할 수 있습니다.

파이프라인에도 이 명령어들을 추가할 수 있습니다:

$\texttt{tail}$에는 우리가 실시간으로 파일을 볼 수 있도록 하는 옵션이 있습니다. 이는 로그 파일이 쓰여지는 중에 모니터링 할 때 유용합니다. 다음 예제에서는 $\texttt{/var/log}$ 디렉토리에 있는 $\texttt{messages}$ 파일($\texttt{messages}$ 파일이 없다면 $\texttt{/var/log/syslog}$ 파일)을 살펴보겠습니다. $\texttt{/var/log/messages}$는 보안 정보를 가지고 있을 수 있으므로 몇몇 리눅스 배포판에서 해당 파일을 보기 위해서는 슈퍼유저 권한이 필요합니다.

"$\texttt{-f}$" 옵션을 사용하면 $\texttt{tail}$은 파일을 계속 모니터링하고, 새로운 내용이 추가되면 즉시 화면에 출력합니다. $\texttt{Ctrl-c}$를 누르면 중지할 수 있습니다.

$\texttt{tee}$ - Stdin을 읽고 Stdout과 파일에 출력

배관 비유를 계속 사용하여 설명하자면, $\texttt{tee}$ 명령어는 우리의 파이프에 "tee"(실제 배관 시스템에서 세 갈래로 나뉘는 연결부품. 이미지 참고)를 추가합니다. $\texttt{tee}$ 프로그램은 표준 입력을 읽은 다음 표준 출력(데이터가 파이프라인을 따라 계속 이동할 수 있게)과 파일에 복사합니다. 이는 파이프라인 중간에서 내용을 살펴보고자 할 때 유용합니다. 이전에 사용했던 예시에 이번에는 $\texttt{tee}$를 추가해서 $\texttt{grep}$이 필터링을 하기 전에 전체 디렉토리 리스트를 $\texttt{ls.txt}$에 저장하도록 파이프라인을 수정해보겠습니다:

요약

전과 마찬가지로 이번장에서 다룬 명령어들의 문서를 읽어보세요. 우리가 본 것은 이 명령어들의 가장 간단한 사용 예시들일 뿐입니다. 각 명령어는 여러개의 흥미로운 옵션들이 있습니다. 리눅스 경험이 쌓일수록 커맨드 라인의 리디렉션 기능이 특수한 문제를 해결하기 위해 매우 유용하다는 것을 알게될 것입니다. 이 밖에도 표준 입력과 출력을 사용하는 명령어가 많고, 대부분의 커맨드 라인 프로그램들은 중요한 메시지를 출력하기 위해 표준 에러를 사용합니다.

리눅스는 상상력이다

윈도우 운영체제와 리눅스 운영체제의 차이점을 설명해달라는 요청을 받으면 저는 종종 장난감에 비유하여 설명합니다.

윈도우는 게임보이와 같습니다. 당신은 게임 스토어에 가서 박스에 들어있는 새 제품을 구입합니다. 당신은 집에 와서, 전원을 키고, 그것을 가지고 놉니다. 예쁜 그래픽, 귀여운 음향효과도 나오죠. 그러나 얼마 지나면 함께 구매한 게임에 질리게 되고 다시 게임 스토어로 가서 점원에게 "이런 게임을 사고 싶어요!"라고 말하지만 수요가 없기 때문에 그런 게임은 존재하지 않는다는 대답을 듣게됩니다. 그러면 당신은 "하지만 이것 딱 하나만 바꾸면 된다구요!"라고 합니다. 점원은 그것은 불가능하다고 합니다. 게임은 카트리지 안에 봉인되어있습니다. 당신은 당신의 즐길 수 있는 게임이 다른 사람들이 결정해놓은 게임들에 국한된다는 것을 깨닫게 됩니다.

반면 리눅스는 세계 최대 규모의 건설 세트와 같습니다. 상자를 열면 그저 커다란 파츠 컬렉션을 마주하게됩니다. 무엇을 지으면 좋을지에 대한 제안과 함께 철근, 나사, 기어, 도르레, 모터가 잔뜩있습니다. 그래서 당신은 그걸 가지고 놀기 시작하죠. 제안에 있는 것을 하나 만들어보고 또 다른 것도 만들어봅니다. 얼마 지나면 뭘 만들지 스스로 아이디어가 떠오르게 됩니다. 이미 모든 부품이 있기 때문에 장난감 가게에 돌아갈 필요도 없습니다. 건설 세트는 당신이 원하는대로 당신의 상상을 실현합니다.

물론 선택은 당신의 몫입니다. 어떤 장난감이 당신에게 더 맞나요?