Skip to main content

Command Palette

Search for a command to run...

Linux Programming Environment Setup

Published
38 min read
Linux Programming Environment Setup
H
Hi there, I'm a full time software engineering student, and full time mum based in Brisbane, QLD, Australia. Korean is my native language and English is my second, but I love learning software in English. My posts are a mix of both Korean and English, so there's something for everyone! All my posts come straight from my lecture notes, so follow along my study journey with me <3

In this session, we'll take a brief look at what needs to be installed and what to keep in mind when programming on Linux.

We'll explore how to use C, C++, Python, and Java on Linux. By the end of this lesson, you'll be able to set up a programming environment on Linux and know how to proceed after installation. Finally, we'll write some simple code and verify that it runs correctly on Linux.

리눅스에서 프로그래밍을 할 때 기본적으로 설치해야 할 것들과 무엇을 신경 써야 할지 간략하게 알아본다.

C, C++, Python, Java를 리눅스에서 사용하려면 어떻게 해야 하는지 살펴볼 예정이다. 이 수업을 마치고 나면 리눅스에서 프로그래밍 환경을 구성할 수 있게 될 것이고, 설치 후에는 어떻게 진행해야 할지도 알게 될 것이다. 마지막으로 아주 간단한 코드를 작성해 리눅스에서도 정상적으로 동작하는 것을 직접 확인해 볼 것이다.


1️⃣ Programming Environment
2️⃣ Programming (C, C++, Python, Java)


1️⃣ Programming Environment

The program development process generally follows these steps:

  1. Requirements definition & analysis — Define and analyze what needs to be built.

  2. Design — Determine how the solution will be implemented.

  3. Implementation — Write the actual code based on the design.

  4. Verification — Test whether the program behaves as intended.

  5. Deployment — Install and release the completed program in a real environment.

  6. Maintenance — An ongoing phase where issues are identified and improvements are made through actual use.


기본적으로 프로그램을 개발할 때는 아래와 같은 순서로 이루어진다.

  1. 요구사항 정의 및 분석 — 무엇을 만들어야 할지 요구사항을 정하고 분석한다.

  2. 설계 — 어떻게 구현할지 방향을 정하는 단계이다.

  3. 구현 — 설계에 맞춰 실제 코드를 작성한다.

  4. 검증 — 의도한 대로 동작하는지 확인하는 테스트 단계이다.

  5. 배포 — 완성된 프로그램을 실제 환경에 설치하고 배포한다.

  6. 유지보수 — 실제로 사용하면서 발생하는 문제를 보완하고 개선해 나가는 지속적인 단계이다.


Software Development Tools on Ubuntu

Linux distributions can be broadly divided into two families: Red Hat-based and Debian-based. Red Hat-based distributions are widely used in enterprise environments due to their commercial polish, while developers tend to prefer Debian-based distributions — Ubuntu in particular. While this is difficult to quantify precisely, it can be observed indirectly by the fact that installation guides for new open-source tools are often written with Ubuntu as the reference platform.

On Ubuntu, packages are installed using the apt package manager. The sudo apt install command makes it straightforward to install any desired package. To set up a complete C/C++ development environment in one step, use the following command:

sudo apt install build-essential

This meta-package includes everything needed for C/C++ development: the C compiler gcc, the C++ compiler g++, the build automation tool make, the C standard library headers libc6-dev, and the Debian package development tool dpkg-dev.

The reason Python and Java are not included in build-essential comes down to history and philosophy. The Linux kernel itself is written in C, and C has traditionally been the foundation of system-level development. In other words, "essential" is defined with C at its core. Python and Java must be installed separately as needed.

우분투 기반 소프트웨어 개발 도구

리눅스 배포판은 크게 레드햇 계열과 데비안 계열로 나눌 수 있다. 레드햇 계열은 상업적 완성도가 높아 기업 서비스 환경에서 많이 사용되는 반면, 개발자들 사이에서는 데비안 계열, 그 중에서도 우분투를 선호하는 경향이 있다. 이를 수치로 정확히 확인하기는 어렵지만, 새로운 오픈소스 도구들의 설치 가이드를 보면 우분투를 기준으로 작성된 경우가 많다는 점에서 이런 경향을 간접적으로 확인할 수 있다.

우분투에서 패키지를 설치할 때는 apt 패키지 관리자를 사용하며, sudo apt install 명령어를 통해 원하는 패키지를 간편하게 설치할 수 있다. C/C++ 개발 환경을 한 번에 구성할 때는 sudo apt install build-essential 명령어를 사용한다. 이 메타 패키지는 C 컴파일러인 gcc, C++ 컴파일러인 g++, 빌드 자동화 도구인 make, C 표준 라이브러리 헤더인 libc6-dev, 데비안 패키지 개발 도구인 dpkg-dev 등을 포함하고 있다.

build-essential에 Python이나 Java가 포함되지 않는 이유는 리눅스 커널 자체가 C로 작성되어 있고, 전통적으로 시스템 개발의 근간이 C이기 때문이다. 즉, "에센셜"의 기준이 C 중심으로 정의되어 있으며, Python이나 Java는 필요에 따라 별도로 설치해야 한다.


GDB Debugger

The use of debuggers has declined significantly compared to the past. In earlier days, hardware performance was limited and development machines were scarce, meaning that simply compiling and running code could take a considerable amount of time. In that environment, debuggers were an essential tool — stepping through code line by line was far more practical than restarting from scratch every time something went wrong. Today, however, hardware performance has improved dramatically, and it is often sufficient to trace issues by inserting print statements at key points in the code. That said, there are still situations where a debugger proves invaluable, so it is worth knowing the basics.

To use GDB, first install it, then compile your code with the -g flag. This option embeds symbol information and debugging data directly into the binary, giving the debugger the context it needs to trace execution. It also means that information irrelevant to the end user ends up inside the file. As debugging data accumulates, file size grows and performance can be affected — so the -g flag should be used strictly for debugging purposes and must be removed before a production release. It is not uncommon for developers to overlook this in a rush, resulting in a release binary that is unnecessarily large and underperforming, so this is a point worth keeping in mind.

Once compilation is complete, pass the resulting binary to GDB as a parameter to launch it. This drops you into a GDB-specific shell environment, where you can step through the code and trace execution flow using GDB commands.

GDB 디버거

요즘은 디버거를 사용하는 경우가 예전에 비해 많이 줄었다. 과거에는 하드웨어 성능이 낮고 개발 장비도 충분하지 않았기 때문에, 코드를 컴파일하고 실행하는 데만도 상당한 시간이 소요됐다. 그런 환경에서는 문제가 생겼을 때 처음부터 다시 실행하는 것보다 단계별로 흐름을 추적할 수 있는 디버거가 필수적인 도구였다. 하지만 현재는 하드웨어 성능이 크게 향상되어 코드를 빠르게 실행할 수 있고, 중간중간 출력문을 삽입하는 방식으로도 충분히 문제를 확인할 수 있게 되었다. 그런 이유로 디버거의 사용 빈도는 줄었지만, 상황에 따라 필요한 순간이 올 수 있으므로 기본적인 사용법은 알아두는 것이 좋다.

GDB를 사용하려면 먼저 설치 후, 컴파일 시 -g 옵션을 추가해야 한다. 이 옵션을 붙이면 디버거가 활용할 수 있는 심볼 정보와 디버깅 데이터가 바이너리에 함께 포함되어 컴파일된다. 이는 곧 실제 서비스에서는 불필요한 정보가 파일에 포함된다는 의미이기도 하다. 디버깅 정보가 누적되면 파일 크기가 커지고 성능에도 영향을 미치기 때문에, -g 옵션은 디버깅 목적으로만 사용하고 최종 배포 시에는 반드시 제외해야 한다. 간혹 급하게 작업하다가 이 부분을 놓쳐 배포 버전의 파일이 불필요하게 크고 성능이 저하되는 경우가 드물게 발생하기도 하므로 주의가 필요하다.

컴파일이 완료되면 생성된 바이너리 파일을 GDB의 파라미터로 전달하여 실행한다. 그러면 GDB 전용 셸 환경으로 진입하게 되며, 이후 명령어를 통해 코드를 단계별로 실행하며 흐름을 추적할 수 있다.


Valgrind

Like GDB, Valgrind is a tool used for debugging. After installation, it requires a specific compile option to be used effectively. The option used when compiling for Valgrind is -O0. Here, O stands for Optimization, and the number that follows indicates the level of optimization. 0 means that no optimization will be applied at all.

When optimization is enabled, the compiler restructures the code to improve runtime performance and reduce file size. However, in a debugging context, optimization can actually get in the way. During the optimization process, the execution flow may be reordered and certain variables may be eliminated, creating a gap between the code as written by the developer and the code as it actually runs. For this reason, when debugging with Valgrind, the -O0 option is used to disable optimization entirely, allowing the tool to analyze the code exactly as it was written.

Valgrind

Valgrind는 GDB와 마찬가지로 디버깅에 활용되는 도구로, 설치 후 컴파일 시 별도의 옵션을 지정하여 사용한다. Valgrind에서 사용하는 컴파일 옵션은 -O0이다. 여기서 O는 최적화(Optimization)를 의미하며, 뒤에 붙는 숫자가 최적화 수준을 나타낸다. 0은 최적화를 전혀 수행하지 않겠다는 의미이다.

최적화를 적용하면 컴파일러가 코드를 재구성하여 실행 성능이 향상되고 파일 크기도 줄어드는 이점이 있다. 그러나 디버깅 상황에서는 최적화가 오히려 방해가 된다. 최적화 과정에서 코드의 실행 흐름이 변경되거나 일부 변수가 제거될 수 있어, 개발자가 작성한 코드와 실제 실행 흐름 사이에 차이가 생기기 때문이다. 따라서 Valgrind로 디버깅할 때는 -O0 옵션을 통해 최적화를 비활성화한 상태로 컴파일하여 코드 본래의 흐름을 그대로 분석할 수 있도록 하는 것이다.

  • -g — GDB 디버깅 정보 포함

  • -O0 — 최적화 비활성화 (Valgrind 분석용)

  • -std=gnu99 — C99 표준에 GNU 확장 기능을 포함한 규격으로 컴파일

-std=gnu99를 명시하는 이유는 컴파일러가 어떤 C 표준을 기준으로 코드를 해석할지 명확하게 지정하기 위함이다. 지정하지 않으면 컴파일러 버전에 따라 기본 표준이 달라질 수 있어, 환경에 따른 동작 차이가 생길 수 있다. 특히 Valgrind로 정확한 분석을 하려면 이처럼 컴파일 옵션을 명확하게 지정하는 것이 좋다.


2️⃣ Programming (C, C++, Python, Java)

To install C and C++ compilers on Linux, use the following commands:

sudo apt install gcc
sudo apt install g++

g++, the C++ compiler, is installed in the same way. The two compilers share a number of similarities — it is possible to compile C code using g++. However, when using gcc to compile C++ code, the C++ standard library is not linked automatically, which requires additional options to be specified manually. For this reason, g++ is the recommended compiler for C++ code.

It is also worth understanding the fundamental difference between a compiler and an interpreter. An interpreter executes code directly, whereas a compiler goes through an intermediate stage. In C, compiling the source code first produces an object file as an intermediate output, which is then linked to produce the final executable binary. While this appears to happen in a single step, there is an underlying process taking place behind the scenes.

Why is this intermediate stage necessary? A program is essentially a sequence of functions, but when writing code, there is no requirement to define functions in the exact order they are called. Organizing code by functionality rather than by execution order is far easier to manage. As a result, a function may be called before its definition appears in the source — the compiler handles this by first taking in the full picture before processing everything together.

The same principle applies to #include and header files in C. A header file simply contains declarations — it states that a function or variable with a given name exists — while the actual implementation lives in a library. In other words, the header confirms what is available, and the library provides the functionality at runtime.

Installation itself is straightforward and can be done with the sudo apt install command.

컴파일러

리눅스에서 C 컴파일러를 설치할 때는 아래 명령어를 사용한다.

sudo apt install gcc
sudo apt install g++

마찬가지로 C++의 컴파일러인 g++도 동일한 방식으로 설치할 수 있다. 두 컴파일러는 서로 비슷한 면이 있는데, g++로 C 코드를 컴파일하는 것은 가능하다. 단, gcc로 C++ 코드를 컴파일하는 경우에는 C++ 표준 라이브러리를 자동으로 링크해 주지 않기 때문에 별도의 옵션이 필요하다. 따라서 C++을 컴파일할 때는 g++를 사용하는 것이 권장된다.

컴파일러와 인터프리터의 차이도 기본적으로 알아두면 좋다. 인터프리터는 코드를 바로 실행하는 반면, 컴파일러는 중간 단계를 거친다. C의 경우 소스 코드를 컴파일하면 오브젝트 파일이라는 중간 단계의 파일이 생성되고, 이를 링킹하여 최종 실행 가능한 바이너리 파일이 만들어진다. 눈에는 한 번에 진행되는 것처럼 보이지만, 내부적으로는 이러한 과정을 거친다.

이 중간 단계가 필요한 이유는 무엇일까? 프로그램은 함수들의 순서적 나열로 이루어져 있지만, 실제 코드를 작성할 때 반드시 실행 순서대로 함수를 정의할 필요는 없다. 시간적 순서보다 기능별로 분류하는 것이 관리하기 훨씬 편리하기 때문이다. 따라서 어떤 함수가 호출되더라도 그 정의가 뒤에 있을 수 있는데, 컴파일러는 이를 일단 무시하고 전체를 파악한 뒤 처리한다.

C에서 #include로 헤더 파일을 가져오는 것도 같은 맥락이다. 헤더 파일은 단순히 "이런 이름의 함수나 변수가 존재한다"는 선언을 담고 있으며, 실제 구현 코드는 라이브러리에 저장되어 있다. 즉, 헤더로 선언을 확인하고 실제 동작은 라이브러리에서 가져와 사용하는 구조이다.

설치 자체는 간단하다. sudo apt install 명령어로 손쉽게 진행할 수 있다.


Editor Settings

vi is an editor that is well worth learning — it will prove useful down the line. Unlike the typical environment where a mouse and keyboard are used together, vi is a text-based editor where every operation is performed using the keyboard alone.

First impressions of vi are rarely positive. There is no syntax highlighting, cursor movement requires keyboard input at every step, and indentation means pressing the space bar multiple times. Fortunately, all of these inconveniences can be resolved through configuration.

Adding the following to ~/.vimrc will apply the settings. Here is what each option does.

  • filetype on — Automatically detects the file type based on its extension, identifying whether it is C, Python, or another language, and prepares to distinguish language-specific keywords and function names accordingly.

  • filetype plugin on — Loads the appropriate plugin for the detected file type by referencing files in the .vim/ftplugin directory, automatically applying the relevant settings on startup.

  • filetype indent on — Applies indentation rules specific to the file type. In C, indentation has no effect on how the code runs, but in Python it is part of the syntax — incorrect indentation will cause the interpreter to throw an error and halt execution.

  • syntax on — Applies color to the code so that syntax elements can be distinguished visually.

  • set title — Displays the name of the file currently being edited in the terminal window's title bar.

  • set tabstop — Specifies how many spaces wide a tab character appears. Since tab width can vary across environments, setting this value ensures a consistent tab size within vi.

  • set softtabstop — Defines the width of whitespace inserted when the tab key is pressed. set shiftwidth sets the width applied during indentation commands such as >> and <<, or during auto-indentation. set noexpandtab ensures that pressing the tab key inserts an actual tab character rather than spaces. For automatic indentation after pressing Enter, the autoindent or smartindent option must also be enabled alongside these settings.

One important point to keep in mind: setting tabs to 4 spaces wide on your machine does not mean they will appear 4 spaces wide in every environment. A tab character is stored as a single character, and its visual width is determined by the tab width setting of whichever environment is rendering it. This means that a file using tab characters may look different depending on where it is opened — and this is precisely why mixing tabs and spaces can cause problems in collaborative development.

편집기 설정

vi는 익혀두면 나중에 분명히 도움이 되는 편집기이다. 마우스와 키보드를 함께 사용하는 일반적인 환경과 달리, vi는 키보드 하나만으로 모든 작업을 처리하는 텍스트 기반 편집기이다.

처음 vi를 접하면 불편한 점이 한두 가지가 아니다. 문법 색상 구분도 없고, 커서 이동도 키보드로 일일이 해야 하며, 들여쓰기를 하려면 스페이스바를 여러 번 눌러야 하는 번거로움이 있다. 하지만 이러한 문제들은 환경 설정으로 해결할 수 있다.

~/.vimrc 파일 안에 아래 내용을 추가하면 적용된다.

filetype plugin indent on
syntax on
set title
set tabstop=8
set softtabstop=8
set shiftwidth=8
set noexpandtab

각 항목의 의미는 다음과 같다.

  • filetype on; 파일의 확장자를 통해 C인지 Python인지 등을 자동으로 인식한다. 이를 통해 언어별 예약어나 함수 이름을 구분할 준비를 한다.

  • filetype plugin on; 파일 타입에 맞는 플러그인을 불러온다. .vim/ftplugin 디렉토리 안에 있는 파일을 참조하여, 시작 시 해당 파일 타입에 맞는 설정을 자동으로 로드한다.

  • filetype indent on; 파일 타입에 맞는 들여쓰기 규칙을 적용한다. C는 들여쓰기가 없어도 동작에는 문제가 없지만, Python은 들여쓰기가 문법의 일부이기 때문에 맞지 않으면 인터프리터가 에러를 발생시키며 실행을 멈춘다.

  • syntax on; 코드에 색상을 입혀 문법 요소를 시각적으로 구분할 수 있게 해준다.

  • set title은 현재 편집 중인 파일 이름을 터미널 창의 제목 표시줄에 보여주는 옵션이다.

  • set tabstop은 탭 키를 눌렀을 때 몇 칸을 띄울지 지정하는 옵션이다. 원래 탭의 폭은 환경마다 다를 수 있는데, 이 값을 설정해두면 vi에서 탭 간격을 일정하게 유지할 수 있다.

  • set softtabstop은 탭 키를 눌렀을 때 삽입되는 공백의 폭을 지정하고, set shiftwidth>>, << 등의 들여쓰기 명령이나 자동 들여쓰기 시 적용되는 폭을 설정한다. set noexpandtab은 탭 키를 눌렀을 때 스페이스 대신 실제 탭 문자가 입력되도록 한다. 엔터 후 자동 들여쓰기는 이 옵션들과 함께 autoindent 또는 smartindent 옵션이 함께 동작해야 적용된다.

여기서 한 가지 주의할 점이 있다. 내가 탭을 4칸으로 설정해두었다고 해서 다른 환경에서도 똑같이 4칸으로 보이는 것은 아니다. 탭 문자는 실제로 "탭"이라는 하나의 문자로 저장되며, 화면에 보이는 폭은 각 환경에서 설정한 탭 폭에 따라 달라진다. 따라서 탭 문자를 사용한 파일은 환경에 따라 들여쓰기가 다르게 보일 수 있다. 이것이 바로 협업 시 탭과 스페이스의 혼용이 문제가 되는 이유이기도 하다.


Default Editor Configuration

The following command allows you to select which editor the system uses by default.

sudo update-alternatives --config editor

Running this command brings up a list of available editors, as shown in the example. In this case, five editors are listed from 0 to 4, with vim.basic and vim.tiny among the options. The current default is marked with * at option 0, and entering the corresponding number sets that editor as the default.

The reason this configuration matters is as follows. When an editor is explicitly specified — such as nano filename or vim filename — there is no issue. However, there are situations where the system internally invokes an editor automatically, and in those cases, whichever editor has been set as the default is the one that will be launched. It works on the same principle as a smartphone: even if multiple browsers or media players are installed, the one set as the default app is what opens automatically.

기본 편집기 설정

아래 명령어를 사용하면 시스템에서 기본으로 사용할 편집기를 직접 선택할 수 있다.

sudo update-alternatives --config editor

명령을 실행하면 사진과 같이 선택 가능한 편집기 목록이 나타난다. 현재 예시에서는 0번부터 4번까지 총 5가지 편집기가 표시되며, 그 중 vim.basicvim.tiny도 확인할 수 있다. 현재 기본값은 * 표시가 된 0번이며, 원하는 번호를 입력하면 해당 편집기가 기본으로 설정된다.

이 설정이 필요한 이유는 다음과 같다. nano 파일명, vim 파일명처럼 편집기를 명시적으로 지정해서 실행하는 경우에는 문제가 없다. 하지만 시스템 내부에서 편집기가 자동으로 호출되는 경우에는 기본 편집기로 지정된 프로그램이 실행된다. 스마트폰에서 여러 브라우저나 미디어 플레이어가 설치되어 있어도 기본 앱으로 지정된 것이 자동으로 실행되는 것과 같은 원리이다.


Build Automation with make

As a project grows in size, it becomes increasingly difficult to manage everything within a single file. While a project may start out as a single source file, additional files are introduced and organized by functionality as the codebase expands. At that point, running gcc manually for each file becomes tedious and inefficient. make is a build automation tool designed to solve exactly this problem, allowing multiple files to be managed and built together in a single step.

Makefile Rule Basics

make operates using rules defined in a file called Makefile. Each rule follows this structure:

target ... : prerequisites ...
	recipe
	...
  • target The output to be produced, such as an executable or object file.

  • prerequisites The files that must exist before the target can be built.

  • recipe The command to run in order to produce the target.

One critical rule to remember: every recipe line must begin with a tab character. Using spaces instead will cause make to fail to recognize the line as a recipe and produce an error.

make also only re-runs a recipe when a prerequisite file has been modified more recently than the target. If nothing has changed, the build step is skipped. This is one of the key advantages of make — it avoids unnecessary recompilation and saves time as projects grow larger.

자동화 도구 make

프로젝트 규모가 커지면 하나의 파일로 프로그램을 완성하기 어려워진다. 초기에는 단일 파일로 작성하더라도 기능이 늘어날수록 파일을 여러 개로 나누어 관리하게 된다. 이때 파일마다 일일이 gcc를 실행하는 것은 번거롭고 비효율적이다. make는 이러한 문제를 해결해 주는 자동화 도구로, 여러 파일을 한 번에 관리하고 빌드할 수 있게 해준다.

Makefile rule 기초

make는 기본적으로 아래와 같은 형식의 rule을 사용한다.

target ... : prerequisites ...
	recipe
	...
  • target 만들고자 하는 결과물(실행 파일 또는 오브젝트 파일 등)이다.

  • prerequisites target을 만들기 위해 필요한 선행 파일들이다.

  • recipe target을 만들기 위해 실행할 명령어이다.

여기서 반드시 주의해야 할 점이 있다. recipe 줄은 반드시 탭(Tab) 문자로 시작해야 한다. 스페이스바로 맞춰 쓰면 make가 이를 recipe로 인식하지 못하고 오류가 발생한다.


Makefile Example

To look at a real example, open the following Makefile:

vi /usr/share/vim/vim91/macros/maze/Makefile

Note that vim91 in the path may vary depending on the version of vim installed. If you have installed it yourself, you should be able to find it at a similar path.

The numbers on the left side of the screen are line numbers — the same kind commonly seen in an IDE, displayed to make it easy to identify where in the code you are. Line numbers can be configured to appear automatically in vi's settings.

Looking at the content, line 1 contains # It's simple..., which is a comment. Line 3 shows maze: mazeansi.c, and line 4 contains cc -o maze mazeansi.c, indented with a single tab. This tells make to compile mazeansi.c and produce an executable named maze.

There is an important concept to understand here. make only runs the recipe when a file listed in the prerequisites has been modified more recently than the target. In other words, mazeansi.c will only be recompiled if it has changed since the last build — if nothing has been modified, the compilation step is skipped entirely. This is one of the core strengths of make.

It may feel somewhat complex at first, but the more you write and use Makefiles yourself, the more natural and convenient the tool becomes.

Makefile 예제

실제 예제를 살펴보기 위해 아래 경로의 Makefile을 열어본다.

vi /usr/share/vim/vim91/macros/maze/Makefile

경로 중 vim91 부분은 설치된 vim 버전에 따라 다를 수 있다. 직접 설치했다면 비슷한 경로에서 찾을 수 있을 것이다.

예제 화면에서 보이는 좌측의 숫자는 코드의 줄 번호이다. 통합 개발 환경(IDE)에서 흔히 볼 수 있는 것처럼, 코드의 위치를 쉽게 파악하기 위해 표시된다. vi 환경 설정에서 줄 번호가 자동으로 표시되도록 설정할 수 있다.

예제 내용을 살펴보면, 1번 줄의 # It's simple...은 주석이다. 3번 줄에는 maze: mazeansi.c가 있고, 4번 줄은 탭 키로 한 번 들여쓴 후 cc -o maze mazeansi.c 명령이 작성되어 있다. 이는 mazeansi.c 파일을 컴파일하여 maze라는 실행 파일을 만들라는 의미이다.

여기서 중요한 개념이 하나 있다. make는 prerequisites에 명시된 파일이 target보다 더 최근에 수정되었을 때만 recipe를 실행한다. 즉, mazeansi.c가 수정된 경우에만 다시 컴파일하고, 변경이 없다면 불필요한 컴파일을 건너뛴다. 이것이 make의 핵심 장점 중 하나이다.

처음에는 다소 복잡하게 느껴질 수 있지만, Makefile을 직접 작성하고 사용해 보다 보면 얼마나 편리한 도구인지 자연스럽게 체감하게 될 것이다.


C Compilation Practice

The teacher recommended installing Linux in a server environment. With a server installation, the monitor displays nothing but text on a black screen — there are no windows to open side by side, and the kind of zooming and resizing familiar from graphical environments is not available. When vi is launched, it fills the entire screen, which means the typical workflow involves exiting vi, running the compiler from the command line, then returning to vi once the check is done — a repetitive back-and-forth that quickly becomes inconvenient.

There are a few ways to work around this. In a Linux server environment, pressing Alt + number at the login screen after booting switches between virtual terminals such as tty1 and tty2. Up to six independent login sessions can be used simultaneously, so this is a handy option when the single-screen constraint feels limiting.

That said, there is an even more convenient approach that allows compilation without ever leaving vi. In vi's command mode, typing : opens an internal command prompt, and adding ! before a command executes it directly in the shell without exiting vi.

This leads to the following command:

:!gcc % -o %<

Here, % represents the full name of the file currently being edited, and %< represents the filename without its extension. So if helloWorld.c is open, the command above is equivalent to:

gcc helloWorld.c -o helloWorld

If compilation succeeds, only Press ENTER or type command to continue appears with no error messages. Pressing Enter returns to the vi screen.

The resulting executable can then be run immediately with:

:!./helloWorld

This outputs Hello, World., followed again by Press ENTER or type command to continue. Pressing Enter brings you back to the vi editing screen.

As a side note, if line numbers are not visible in vi, entering the following in command mode will enable them:

:set number

Line numbers are purely a visual aid for navigating the code and have no effect on the actual file content.

C 컴파일 실습

교수님은 서버 환경으로 리눅스를 설치하는 것을 권장했다. 서버 버전을 설치하면 모니터에는 검은 화면에 글자만 표시된다. 윈도우처럼 여러 창을 띄워 선택적으로 확대·축소하는 것이 불가능하다. vi를 실행하면 그 내용이 화면 전체를 채우기 때문에, 일반적으로는 vi를 종료한 후 명령창에서 컴파일하고, 확인이 끝나면 다시 vi로 돌아와야 하는 번거로움이 있다.

이에 대한 해결 방법이 몇 가지 있다. 먼저 리눅스 서버 환경에서는 부팅 후 로그인 화면에서 Alt + 숫자를 누르면 tty1, tty2와 같이 가상 터미널이 전환된다. 최대 6개까지 독립적인 로그인 세션을 사용할 수 있으므로, 답답하게 느껴질 때 이 방법을 활용하면 된다.

그러나 하나의 터미널 안에서 vi를 벗어나지 않고 컴파일까지 처리하는 더 편리한 방법이 있다. vi의 명령 모드에서 :을 입력하면 내부 명령을 실행할 수 있는데, 여기서 !를 붙이면 vi 환경을 벗어나 셸 명령을 직접 실행할 수 있다.

이를 활용한 명령어가 바로 아래와 같다.

:!gcc % -o %<

여기서 %는 현재 편집 중인 파일의 이름 전체를, %<는 확장자를 제외한 파일 이름을 의미한다. 즉, helloWorld.c를 편집 중이라면 위 명령은 다음과 동일하다.

gcc helloWorld.c -o helloWorld

컴파일이 성공하면 Press ENTER or type command to continue만 표시되고 오류 메시지가 없다. 엔터를 누르면 vi 화면으로 돌아온다.

이후 아래 명령으로 실행 파일을 바로 실행할 수 있다.

:!./helloWorld

실행하면 Hello, World.가 출력되고, 다시 Press ENTER or type command to continue가 나타난다. 엔터를 누르면 vi 편집 화면으로 복귀한다.

참고로 vi에서 줄 번호가 보이지 않는다면 명령 모드에서 아래와 같이 입력하면 줄 번호가 표시된다.

:set number

줄 번호는 코드 위치를 파악하기 위한 시각적 요소일 뿐, 실제 파일 내용에는 영향을 주지 않는다.


Compilation with a Single File

This section covers a more convenient way to compile when there is only one file involved. Add the following to ~/.vimrc:

autocmd FileType c setlocal makeprg=gcc\ -Wall\ -g\ %\ -o\ %
autocmd FileType cpp setlocal makeprg=g++\ -Wall\ -g\ %\ -o\ %

autocmd FileType automatically runs a command based on the file type. Files with a .c extension will use gcc, while .cpp files will use g++. setlocal means the setting applies only to the current file. As covered earlier, % refers to the full filename and %< refers to the filename without its extension.

With this configuration in place, there is no need to type :!gcc % -o %< every time. Compilation can be triggered from within vi using just:

:make

If compilation succeeds, Press ENTER or type command to continue is displayed, and pressing Enter returns to vi. The resulting executable can then be run with:

:!./helloWorld

This is a practical setup that eliminates the repetitive typing of lengthy compile commands when working with a single file.

컴파일 2; 파일이 하나일 때

이번에는 파일이 하나만 있을 때 더 간편하게 컴파일하는 방법이다. ~/.vimrc에 아래 내용을 추가한다.

autocmd FileType c setlocal makeprg=gcc\ -Wall\ -g\ %\ -o\ %
autocmd FileType cpp setlocal makeprg=g++\ -Wall\ -g\ %\ -o\ %

autocmd FileType은 파일 타입에 따라 자동으로 명령을 실행하는 설정이다. 확장자가 .c이면 gcc를, .cpp이면 g++를 사용하도록 각각 지정한다. setlocal은 해당 설정을 현재 파일에만 적용한다는 의미이다. %%<는 앞서 배운 것처럼 각각 현재 파일 이름과 확장자를 제외한 파일 이름을 의미한다.

이 설정을 해두면 이전처럼 :!gcc % -o %<를 매번 입력할 필요 없이, vi 안에서 아래 명령만으로 컴파일이 가능하다.

:make

컴파일이 성공하면 Press ENTER or type command to continue가 표시되고, 엔터를 누르면 vi로 돌아온다. 이후 실행은 동일하게 아래 명령으로 할 수 있다.

:!./helloWorld

파일이 하나일 때 매번 긴 컴파일 명령을 입력하는 번거로움을 줄여주는 유용한 설정이다.


Compilation Errors

The following example demonstrates what happens when an error occurs during compilation. In the code shown, line 4 contains std::count, when the correct expression should be std::cout. Running :make produces the error message below:

shell

helloError.cpp:4:10: error: 'count' is not a member of 'std'; did you mean 'cout'?

When an error occurs, the fix must be made at the location indicated. The following vi commands are useful for navigating between errors

  • :clist Displays the full list of errors produced during compilation.
  • :cfirst Jumps to the location of the first error.
  • :clast Jumps to the location of the last error.
  • :cn Moves to the next error in sequence.

When multiple errors are present, an efficient approach is to start at the first error with :cfirst and work through them one by one using :cn. The key advantage of this method is that error locations can be navigated and fixed without ever leaving vi.

컴파일 에러

컴파일 중 에러가 발생했을 때의 예제이다. 첨부된 코드를 보면 4번 줄에 std::count라고 작성되어 있는데, 실제로는 std::cout이 올바른 표현이다. :make를 실행하면 두 번째 사진과 같이 아래 에러 메시지가 출력된다.

helloError.cpp:4:10: error: 'count' is not a member of 'std'; did you mean 'cout'?

에러가 발생하면 해당 위치로 이동하여 수정해야 한다. 이때 유용하게 사용할 수 있는 vi 명령어들이 있다.

  • :clist 컴파일 중 발생한 에러 목록 전체를 표시한다.

  • :cfirst 첫 번째 에러 위치로 이동한다.

  • :clast 마지막 에러 위치로 이동한다.

  • :cn 다음 에러 위치로 순서대로 이동한다.

에러가 여러 개일 때 :cfirst로 첫 번째 에러부터 시작하여 :cn으로 하나씩 이동하며 순서대로 수정하는 방식이 효율적이다. vi를 종료하지 않고도 에러 위치를 바로 찾아갈 수 있다는 것이 이 방법의 장점이다.


Changing vim Color Theme

After launching vi, enter the following in NORMAL mode:

:colorscheme [space] <TAB>

Pressing the Tab key cycles through available color themes one by one, such as blue, evening, and more. Each press of Tab moves to the next theme, and pressing Enter on the desired theme applies it immediately.

To see all available themes at once, press Ctrl + D instead of Tab. As shown in the screenshot, themes such as blue, darkblue, desert, and evening are listed all at once, allowing you to choose and type the one you want.

vim 색상 변경

vi를 실행한 후 명령 모드에서 아래와 같이 입력한다.

:colorscheme [스페이스] <TAB>

탭 키를 누르면 blue, evening 등 사용 가능한 색상 테마가 하나씩 순서대로 나타나며, 계속 누를 때마다 다음 테마로 전환된다. 원하는 테마에서 엔터를 누르면 해당 색상이 즉시 적용된다.

목록을 한눈에 보고 싶다면 탭 대신 Ctrl + D를 누르면 된다. 사진에서 볼 수 있듯이 blue, darkblue, desert, evening 등 다양한 테마가 한 번에 나열되어 원하는 것을 골라 입력할 수 있다.


Interpreter

Python is one of the most widely used programming languages and comes pre-installed on Ubuntu by default. The installation status and version can be checked with the following command:

shell

python3 --version

The lecture example shows Python 3.12.3, but the version may differ depending on the user's environment.

mine is the same.


Editor Configuration

Just as filetype plugin was configured for C and C++ earlier, a separate configuration file can be created for Python as well. If tab settings have been applied globally in ~/.vimrc, a separate file can be created at the path below to apply different settings specifically for Python files:

vi ~/.vim/after/ftplugin/python.vim
setlocal expandtab      " Use spaces instead of tab characters
setlocal tabstop=8      " Size of a tab character in spaces
setlocal shiftwidth=4   " Number of spaces for indent/unindent
setlocal softtabstop=4  " Number of spaces inserted when Tab 

Here, " is vim's comment symbol. Anything after it on the same line is treated as a human-readable note and is not executed by vim.


Inline Configuration in Source Code

There is also a way to include settings directly in the source code without creating a separate configuration file. Adding the following line to the first or last line of hello.py will do the job:

python

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

When the file is opened with vi, the specified settings will be applied automatically. Note that this feature requires set modeline to be enabled and only applies to that specific file.


Checking set modeline Status

:set modeline?

If the result shows modeline, it is enabled. If it shows nomodeline, it is disabled. To enable it, add the following line to ~/.vimrc:

set modeline

인터프리터

Python은 Ubuntu에 기본적으로 설치되어 있을 만큼 널리 사용되는 언어이다. 설치 여부와 버전은 아래 명령어로 확인할 수 있다.

python3 --version

강의 예제에서는 Python 3.12.3으로 표시되지만, 사용자 환경에 따라 버전이 다를 수 있다.

편집기 설정

앞서 C, C++에서 filetype plugin을 설정했던 것처럼, Python에 대해서도 별도의 설정 파일을 만들 수 있다. ~/.vimrc에서 전체 파일에 공통으로 적용되는 탭 설정을 했다면, Python 파일에만 다른 설정을 적용하고 싶을 때는 아래 경로에 별도 파일을 생성하면 된다.

vi ~/.vim/after/ftplugin/python.vim 
setlocal expandtab " 탭 문자 대신 공백 사용 
setlocal tabstop=8 " 탭 문자 공백 크기 
setlocal shiftwidth=4 " 들여쓰기/내어쓰기 공백 개수 
setlocal softtabstop=4 " 탭 키 눌렀을 때 공백 개수 

여기서 "는 vim의 주석 기호로, 해당 줄에서 그 이후 내용은 사람이 읽기 위한 설명으로만 사용되며 vim이 실행하지 않는다. 별도 설정 파일을 만들지 않아도 소스코드 자체에 설정을 포함시키는 방법도 있다. hello.py 파일의 첫 줄 또는 마지막 줄에 아래와 같이 작성하면 된다.

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

이렇게 하면 해당 파일을 vi로 열 때 자동으로 지정된 설정이 적용된다. 단, 이 기능은 set modeline이 활성화되어 있어야 동작하며, 해당 파일에만 적용된다.

set modeline 설정 여부 확인

:set modeline?

결과가 modeline이면 활성화된 상태이고, nomodeline이면 비활성화된 상태이다.

비활성화되어 있다면 ~/.vimrc에 아래 한 줄을 추가하면 된다.

set modeline

Running a Simple Python Script

A Python source file is written as follows:

#!/usr/bin/env python

print("hello, Python")

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

The first line #!/usr/bin/env python is called a shebang, and it tells the operating system which interpreter to use when the file is executed directly.

Once the file is written, it can be run immediately from vim's NORMAL mode by entering:

:!python3 %

When : is followed by !, it means execute a command in the shell. python3 is the command to run the Python interpreter, and % refers to the name of the file currently being edited. In other words, the above command is equivalent to running the following in the shell:

python3 hello.py

After execution, hello, Python will be printed, followed by Press ENTER or type command to continue. Pressing Enter returns to the vim editing screen.

⚠️ Note that the shebang on the first line is written as #!/usr/bin/env python, but in most modern Linux environments, the python command may point to Python 2 or may not exist at all. If you are using a Python 3 environment, it is recommended to write #!/usr/bin/env python3 instead.


Python 간단한 실행

Python 소스 파일은 아래와 같이 작성한다.

python

#!/usr/bin/env python

print("hello, Python")

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

첫 줄의 #!/usr/bin/env python은 셔뱅(shebang)이라고 하며, 이 파일을 직접 실행할 때 어떤 인터프리터를 사용할지 운영체제에 알려주는 역할을 한다.

작성이 끝나면 vi 명령 모드에서 아래와 같이 입력하여 바로 실행할 수 있다.

:!python3 %

:에 이어 !가 오면 셸에서 명령을 실행하라는 의미이다. python3는 Python 인터프리터를 실행하는 명령이고, %는 현재 편집 중인 파일 이름을 의미한다. 즉, 위 명령은 셸에서 아래를 실행하는 것과 동일하다.

python3 hello.py

실행하면 hello, Python이 출력되고, Press ENTER or type command to continue가 표시된다. 엔터를 누르면 vi 편집 화면으로 돌아온다.

⚠️ 참고로 첫 줄의 #!/usr/bin/env pythonpython으로 작성되어 있는데, 현재 대부분의 리눅스 환경에서는 python 명령이 Python 2를 가리키거나 아예 존재하지 않는 경우가 있다. Python 3를 사용하는 환경이라면 #!/usr/bin/env python3로 작성하는 것이 권장된다고 한다.


Useful Tools - Installing Python Packages (pip)

Just as apt install is used to install general packages on Ubuntu, pip is used to install Python packages. pip is a package management tool dedicated to Python. It can be installed with the following command:

sudo apt install python3-pip

After installation, Python packages can be installed as follows:

pip3 install package-name

The 3 in pip3 indicates that it is the pip version for Python 3.

Ubuntu 23.04 이후의 제한 때문에 발생하는 에러


venv Python Virtual Environment

venv is a tool for setting up a Python virtual environment.

sudo apt install python3-venv

Python has many versions, and compatibility issues between versions can arise. This is why code written over the course of a month may not work in a different environment. venv allows you to create an isolated Python environment for each project, separating and managing version and package dependencies independently.

It is also recommended to document which Python version and packages were used in a README file, so that other users can reproduce the same environment.

⚠️ Starting from Ubuntu 23.04, directly installing packages system-wide using pip may be restricted. In this case, the recommended approach is to create a virtual environment using venv and then use pip within it.

유용한 도구 - 파이썬 패키지 설치 (pip)

Ubuntu에서 일반 패키지를 설치할 때 apt install을 사용하듯이, Python 패키지를 설치할 때는 pip를 사용한다. pip는 Python 전용 패키지 관리 도구이다. 아래 명령어로 설치할 수 있다.

sudo apt install python3-pip

설치 후 Python 패키지는 아래와 같이 설치한다.

pip3 install 설치할패키지이름

pip3에서 3은 Python 3 버전용 pip임을 의미한다.

다음으로 venv는 Python 가상 환경을 구성하는 도구이다.

sudo apt install python3-venv

Python은 버전이 매우 다양하고 버전 간 호환성 문제가 발생할 수 있다. 한 달 동안 작성한 코드가 다른 환경에서 동작하지 않는 경우가 생길 수 있는 것도 이 때문이다. venv는 프로젝트별로 독립된 Python 환경을 만들어 버전과 패키지 의존성을 분리하여 관리할 수 있게 해준다. 또한 어떤 Python 버전과 패키지를 사용했는지 README 파일에 명시해두면, 다른 사용자가 동일한 환경을 재현하는 데 도움이 된다.

⚠️Ubuntu 23.04 이후부터는 pip로 시스템 전역에 패키지를 직접 설치하는 것이 제한될 수 있다고 한다. 이 경우 venv로 가상 환경을 생성한 후 그 안에서 pip를 사용하는 것이 권장되는 방법이다.


파이썬 가상 환경 venv

venv 사용 순서는 아래와 같다.

sudo apt install python3-venv   # venv 설치
mkdir proj ; cd proj            # 프로젝트 디렉토리 생성 후 이동
python3 -m venv .venv           # 가상 환경 생성
source .venv/bin/activate       # 가상 환경 활성화

가상 환경이 활성화되면 프롬프트 앞에 (.venv)가 표시된다. 이 상태에서 설치하는 패키지는 시스템 전체가 아닌 해당 가상 환경 안에만 적용된다. 가상 환경을 종료할 때는 아래 명령어를 입력한다.

deactivate

종료되면 프롬프트에서 (.venv) 표시가 사라지고 일반 환경으로 돌아온다.

venv의 세부적인 활용법은 Python을 전문적으로 학습하거나, 다른 사람이 만든 Python 코드를 사용할 때 더 깊이 살펴보면 도움이 될 것이다.


Types of Java

Java has a somewhat more complex installation process compared to C or Python. To understand why, it helps to briefly look at the history of Java.

Java was first developed by Sun Microsystems in the late 20th century and was initially distributed for free with the goal of widespread adoption. However, enterprise-level environments required paid license agreements. After Sun Microsystems was acquired by Oracle, the licensing policy changed multiple times. As a result, open source implementations that could be used freely began to emerge.

The main types of Java currently available are as follows:

  • OpenJDK An open source implementation of Java, most widely used in Linux environments.

  • Oracle Java Downloaded and installed directly from the Oracle website.

  • IBM Java Downloaded and installed from the IBM website.

  • GNU Compiler (GCJ) A Java compiler created by the GNU project, though it is not fully compatible with Java from Sun Microsystems or Oracle.

Each distribution has different installation methods and environment configurations. After installation, the path to the Java compiler (javac) and the path to the JVM (Java Virtual Machine) that runs Java bytecode must be separately configured as environment variables.

Java 종류

Java는 C나 Python에 비해 설치 과정이 다소 복잡하다. 그 이유를 이해하려면 Java의 역사를 간략히 살펴볼 필요가 있다.

Java는 20세기 후반 Sun Microsystems에서 처음 개발되었으며, 초기에는 보급을 목적으로 무료로 배포되었다. 그러나 엔터프라이즈급 환경에서는 유료 라이선스 계약이 필요했고, 이후 Sun Microsystems가 Oracle에 인수되면서 라이선스 정책이 여러 차례 변경되었다. 이에 따라 자유롭게 사용할 수 있는 오픈 소스 구현체들이 등장하기 시작했다.

현재 사용할 수 있는 Java의 종류는 크게 아래와 같다.

  • OpenJDK — 오픈 소스로 구현된 Java로, 리눅스 환경에서 가장 널리 사용된다.

  • Oracle Java — Oracle 홈페이지에서 직접 다운로드하여 설치한다.

  • IBM Java — IBM 홈페이지에서 다운로드하여 설치한다.

  • GNU Compiler (GCJ) — GNU 프로젝트에서 만든 Java 컴파일러로, Sun Microsystems 및 Oracle의 Java와 완전히 호환되지는 않는다.

각 배포판마다 설치 방법과 환경 설정이 다르며, 설치 후에는 Java 컴파일러(javac)의 경로와 Java 바이트코드를 실행하는 JVM(Java Virtual Machine)의 경로를 환경 변수에 별도로 설정해 주어야 한다.


Installing Java OpenJDK

The simplest method is to install OpenJDK using apt.

sudo apt install openjdk-25-jdk

After installation, the versions of the compiler and JVM can be checked with the following commands:

javac --version
java --version

JDK vs JRE

There is an important distinction to make here. Java comes in two forms: JDK (Java Development Kit) and JRE (Java Runtime Environment). The JDK is for development and includes the javac compiler, allowing you to write and compile code. The JRE only supports running (runtime) Java programs and does not include a compiler. Therefore, if you intend to write and compile code yourself, you must install the JDK.


Practice — hello.java

Write a Java source file as follows:

java

public class hello{
    public static void main(String[] args){
        System.out.println("Hello, KoreaCU!");
    }
}

After writing the file, compile and run it in the following order:

javac hello.java   # Compile — generates hello.class (bytecode)
java hello         # Run the bytecode using the JVM

Just like the :!gcc % -o %< method learned earlier, the same approach can be applied to Java — compiling and running without leaving the vi editor.


Important Note for First-Time Java Users

One key rule to keep in mind when using Java for the first time is the relationship between the file name and the class name. In Java, the file name and the public class name must always match. For example, if the class name is hello, the file name must also be hello.java. Just as indentation is part of Python's syntax, matching the file name with the class name is a fundamental rule in Java.

Java 설치 OpenJDK

가장 간단한 방법은 OpenJDK를 apt로 설치하는 것이다.

sudo apt install openjdk-25-jdk

설치 후 아래 명령어로 컴파일러와 JVM의 버전을 각각 확인할 수 있다.

javac --version
java --version

여기서 한 가지 구분해야 할 점이 있다. Java에는 JDK(Java Development Kit)와 JRE(Java Runtime Environment)가 있다. JDK는 개발(Development)용으로 javac 컴파일러가 포함되어 있어 코드를 작성하고 컴파일할 수 있다. JRE는 실행(Runtime)만 가능하며 컴파일러는 포함되어 있지 않다. 따라서 코드를 직접 작성하고 컴파일하려면 반드시 JDK를 설치해야 한다.

hello.java 실습

아래와 같이 Java 소스 파일을 작성한다.

public class hello{
    public static void main(String[] args){
        System.out.println("Hello, KoreaCU!");
    }
}

작성 후 아래 순서로 컴파일하고 실행한다.

javac hello.java   # 컴파일 — hello.class(바이트코드) 생성
java hello         # JVM으로 바이트코드 실행

앞서 배운 :!gcc % -o %< 방식처럼, vi 안에서 셸을 벗어나지 않고 컴파일과 실행을 처리하는 방법을 Java에도 동일하게 응용할 수 있다.

Java를 처음 사용할 때 주의해야 할 점은 파일 이름과 클래스 이름의 관계이다. Java에서는 파일 이름과 public class의 이름이 반드시 일치해야 한다. 예를 들어 클래스 이름이 hello라면 파일 이름도 반드시 hello.java여야 한다. Python에서 들여쓰기가 문법의 일부이듯, Java에서는 이 파일명과 클래스명의 일치 여부가 핵심적인 규칙이다.


Note: Difference Between Compiler and Interpreter

A compiler converts the entire source code into machine language all at once before executing it. C, C++, and Java fall into this category. An interpreter reads and executes code line by line in real time, with Python being the most representative example.

In terms of actual usage, the differences can be summarized as follows:

  • C / C++ — Compile with gcc or g++, then execute

  • Java — Compile with javac, then run on the JVM using the java command

  • Python — Run directly with the python3 command without a separate compilation step

Understanding this difference will make it much easier to set up the execution environment for each language.

참고: 컴파일러와 인터프리터의 차이와 각각의 사용법 정도는 기억해두자.

컴파일러는 소스 코드를 한 번에 기계어로 변환한 후 실행하는 방식으로, C와 C++, Java가 이에 해당한다. 인터프리터는 코드를 한 줄씩 읽으며 바로 실행하는 방식으로, Python이 대표적인 예이다.

실제 사용 측면에서 정리하면, C와 C++는 gcc 또는 g++로 컴파일하고, Java는 javac로 컴파일한 뒤 java 명령으로 JVM에서 실행한다. Python은 별도의 컴파일 없이 python3 명령으로 바로 실행할 수 있다. 이 차이를 이해해두면 각 언어의 실행 환경을 구성할 때 어렵지 않게 적용할 수 있을 것이다.