Shell(Kernel과 User간의 Interface) : 사용자가 명령을 입력하면 해석해서 Kernel에 전달하는 프로그램이나 환경
Terminal(사용자와 Shell간의 Interface) : 사용자가 Shell에 명령을 전달하거나 Shell으로부터 결과를 반환받아
사용자에게 보여주는 도구로, 하드웨어적인 의미에서 보면 키보드와 모니터이고, 소프트웨어적인 의미에서 보면,
명령프롬프트와 같은 프로그램을 의미
2. Shell Script
Shell에서 특정한 명령어들을 순차적으로 실행하도록한 스크립트 파일
2-1) Ubuntu Linux환경에서, nano editor 사용
2-2) shellscript 작성
#! /bin/bash :
shellscript를 사용할 때 사용할 shell 선택(shell의 경로를 알려줌) // 여기서는 bash shell 사용
echo hello :
hello 출력
Linux에서는 확장자 없이도 내부적으로 파일을 식별할 수 있음, 다만 파일 명에 붙이는 확장자는 사용자가 이해하기 쉽게 관습적으로 붙임
2-3) shellscript 실행 및 Permission denied
3. Shell Script 작성
Up & Down game
1) shell script 작성
#! /bin/bash
#01 game에 대한 설명
echo "Up & Down Game!"
echo -n "Random number range(max : 32768) : "
read number_range
echo "Number Range : 1 - $number_range"
#02 변수 설정
# 1~ number_range까지 중에서 rand_num 설정
rand_num=$(($RANDOM%$(($number_range+1))))
count=0
#03 for문을 돌면서 Up & Down
for i in $(seq 100);do
# 입력 값 받기
echo -n "Enter the number : "
read input
# 입력 횟수 카운트
count=$(($count+1))
if [ $input -eq $rand_num ];then
echo "Congratuation! Answer is $rand_num"
break
elif [ $input -gt $rand_num ];then
echo "answer is less than $input"
elif [ $input -lt $rand_num ];then
echo "answer is greater than $input"
fi
done
- 변수를 초기화 할 떄는 대입연산자와 변수명과 초기화값을 붙여서 작성해야 함.
- 조건문 안에 [] 조건을 작성할 때는 공백을 두고 작성해야 함.
2) Permission 설정
----------- 의 의미
첫 번째 - 는 directory를 의미
뒤로 9개의 -는 user, group, other의 read, write, execute 권한을 의미
GNU 프로젝트의 일환으로 개발되어 널리 쓰이고 있는 컴파일러로, 원래는 GNU C Compiler를 의미했지만, Java, C++ 등 여러 언어를 지원하면서 GNU Compiler Collection으로 명칭이 바뀌게 되었다.
2. Build 방식에 따른 프로그램 언어 분류
1. Compile 언어 : compiler를 사용하여 소스 코드를 기계어로 변환, build 과정을 거쳐서 실행 파일 생성
ex) C언어, C++
2. Interpreter 언어 : source file을 한번에 번역하는 게 아니라 한 줄씩 해석하면서 즉시 실행
ex) JavaScript, Python
3. Hybird 언어 : Compile 방식과 Interpreter 방식을 모두 사용, Java의 경우 Source file(.java)을 바이트 코드(.class)로 변환하고, JVM(Java Virtual Machine)이라는 프로그램에 의해 운영체제 별로 Byte Code를 한 줄씩 운영체제에 맞는 명령어로
4. Compile 방식에서 실행 파일 빌드 과정(Building an executable file)
1) preprocessor : 전처리 과정으로 C언어의 #define이나 #include 같은 구문들을 처리 해줌.
2) compile : source file(.c)를 어셈블리 코드로 변환
3) assembler : 어셈블리 코드를 cpu가 이해할 수 있는 기계어로 번역 (object 파일 생성)
4) linker : object 파일들과 library를 묶어서 하나의 실행 파일을 생성
5. Visual Studio Code 실행
1) Visual Studio Code 실행
6. object 파일 생성
## 파일 directory 생성
$ mkdir src bin obj include lib
## file 생성
$ touch include/funcs.h src/func1.c src/func2.c src/main.c
## object 파일 생성
$ gcc -c src/funcs1.c -o obj/funcs1.o -I./include
$ gcc -c src/funcs2.c -o obj/funcs2.o -I./include
1) 명령어 설명
-c : link는 따로 하지 않고, object 파일까지만 생성
-o : 생성된 파일의 경로 및 이름 지정
-I (대문자 I): 컴파일러에게 헤더 파일이 위치한 디렉터리를 알려주는 역
7. Library 생성
1) 정적 라이브러리(Static Library)와 동적 라이브러리(Dynamic Library) 차이
정적 라이브러리 : .lib(Windows) 또는 .a(Unix/Linux)의 확장자를 가지며, 컴파일시에 실행 파일에 포함되고, 그에 따라 실행파일의 크기가 커짐, 런타임에 외부 라이브러리에 대한 의존성이 없음.
동적 라이브러리 : .dll(Windows) 또는 .so(Unix/Linux)의 확장자를 가지며, 런타임시에 프로그램이 필요할 떄 로드가 되고, 실행 파일의 크기가 작아지고, 메모리를 효율적으로 사용할 수 있다는 장점이 있지만, 런타임에 외부 라이브러리에 대한 의존성이 있음.
2) 정적 라이브러리 파일 생성
2-1) 정적 라이브러리 생성
ar rv lib/lib(library이름).a (obj 파일들)
2-2) link (정적 라이브러리 + main.obj)
-o : 만들고자하는 파일 이름
-I(대문자) : 컴파일러에게 헤더파일 경로를 알려줌
-l(소문자) : 컴파일러에게 라이브러리 이름을 알려줌
-L: 컴파일러에게 라이브러리 경로를 알려줌
3) 동적 라이브러리 생성
3-1) 동적 라이브러리 생성
## -fPIC를 이용해서 object 파일 생성
$ gcc -fPIC -c src/funcs1.c -I./include -o obj/funcs1.o
$ gcc -fPIC -c src/funcs2.c -I./include -o obj/funcs2.o
## 환경 변수설정 (export는 껐다키면 사라짐)
$ export LD_LIBRARY_PATH=$HOME/opensw/studylibrary/lib
## 환경 변수 확인
$ echo $LD_LIBRARY_PATH
## 동적 library 생성
$ gcc -fPIC -shared -Wl,-soname=libmyfuncs.so.1 obj/*.o -o lib/libmyfuncs.so.1.0 -lc
## softlink
$ ln -s libmyfuncs.so.1.0 lib/libmyfuncs.so.1
$ ln -s libmyfuncs.so.1.0 lib/libmyfuncs.so
$ tree
-fPIC : 메모리에 로딩되는 위치에 상관없이 실행될 수 있는 코드를 의미, 동적 라이브러리나 공유 라이브러리 생성할 때 사용