심볼릭 링크(Symbolic link)

 

컴퓨팅에서 심볼릭 링크(symbolic link) 또는 기호화된 링크는 절대 경로 또는 상대 경로의 형태로 된 다른 파일이나 디렉터리에 대한 참조를 포함하고 있는 특별한 종류의 파일이다.

심볼릭 링크는 대부분의 작업에 투명하게 동작한다. 심볼릭 링크로 이름이 지정된 파일에 읽고 쓰는 프로그램들은 마치 운영 체제가 직접 대상 파일에 작용하는 것처럼 수행한다. 그러나 심볼릭 링크들을 특별하게 다루어야 하는 프로그램들(이를테면 백업 유틸리티)은 이들을 직접 식별하고 조작할 수도 있다.

심볼릭 링크는 다른 파일이나 디렉터리에 대한 경로로서 운영 체제가 자동으로 해석하고 추적하는 텍스트 문자열을 포함한다. 이러한 다른 파일이나 디렉터리를 대상(target)으로 부른다. 심볼릭 링크는 대상으로부터 독립적으로 존재하는 두 번째 파일이다. 심볼릭 링크가 삭제되면 대상은 영향을 받지 않는다. 심볼릭 링크가 대상을 지시하면 나중에 대상이 이동되거나 이름이 바뀌거나 지워지더라도 심볼릭 링크는 자동으로 업데이트되거나 삭제되지는 않지만 지속적으로 오래된 대상(현재는 존재하지 않는 위치나 파일)을 가리킨 채로 존재한다. 이동되었거나 존재하지 않는 대상을 가리키는 심볼릭 링크들은 broken, orphaned, dead, dangling 등의 용어로 불리기도 한다.

심볼릭 링크는 하드 링크와는 차이가 있다. 하드 링크는 다른 볼륨이나 파일 시스템 상의 경로를 연결하지 않지만 심볼릭 링크는 링크와 대상이 존재하는 볼륨의 어느 파일이나 디렉터리라도 가리킬 수 있다. 하드 링크는 무조건 기존의 파일만을 가리키는 반면 심볼릭 링크는 어느 것을 가리키지 않는 임의의 경로를 포함할 수도 있다.

파일 시스템 계층을 재정렬하려는 노력에 따라 일부 유닉스와 리눅스 배포판들은 심볼릭 링크를 널리 사용한다. 이는 변종의 콘텍스트 의존 심볼릭 링크들과 같은 일부 매커니즘을 통해 수행할 수 있다. 또, 더 직관적이거나 응용 프로그램에 특화된 디렉터리 트리를 만들고, 핵심이 되는 시스템 명령 및 유틸리티들을 다시 설계하는 일 없이 시스템을 다시 정리하는 기회를 제공한다.

 

 

참고 :

https://ko.wikipedia.org/wiki/%EC%8B%AC%EB%B3%BC%EB%A6%AD_%EB%A7%81%ED%81%AC

운영체제의 접근 모드는 두 개가 있다

이렇게 나누는 것은

유저 프로그램의 치명적인 운영체제 데이터 접근 및 수정을 방지하는 역할을 하기 때문이다

유저 프로그램 코드유저 모드에서 실행,

운영체제 코드커널 모드에서 실행 된다

1)유저 모드

유저 프로그램에서 뭔가 중요한 작업(직접적인 하드웨어 접근, 중요한 시스템 요청)이 있을때 커널 모드로 전환하게 된다

◈인터럽트를 통해 시스템 요청이 커널로 전달된다

시스템 호출 SystemCall 이 소프트웨어 인터럽트를 통해 커널 모드로 진입한다는 의미이다

시스템 콜 이라는 것 자체가,

사용자 프로그램이 디스크 파일에 접근하거나 수행결과를 화면에 출력하는 등의 특권 명령이 수행할 필요가 있을때, 운영체제에 인터럽트를 걸어서 특권명령을 대행해줄 것을 요청하는 것을 말한다.

그러니깐, "하던거 그만 두고 내 명령좀 실행해줘!!" 쯤 되는 것 같다

애초에 인터럽트가 함수 호출이랑 비슷해서,

어떤 프로그램이 CPU를 할당 받아 명령을 수행하고 있는데, 인터럽트가 발생하면 그 프로그램은 수행중이던 명령어의 위치를 PCB(하드웨어 제어 블록)에 저장한다

인터럽트가 영어로 뜻이 Interrupt 인데, 실제로 그 "방해하다"의 뜻이 맞다!!

2)커널 모드 (이름만 들어도 중요할거같은 느낌... 팍... 커널에 대해서는 지난 번에 공부했으니)

모든 시스템 자원에 접근이 허가된 모드

유저모드, 커널 모드 개념도 정리

시스템 호출이란?

프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스

- 사용자 모드에 있는 유저 프로그램이 커널 기능을 요청할 수 있도록 함

- 시스템 호출을 하면 유저 모드에서 커널 모드로 전환

- 시스템 호출이 모두 처리 되면 다시 커널 모드에서 유저 모드로 돌아온다

시스템 호출 유형

프로세스 제어(Process Control) - fork, exit, wait

파일 조작(File Manipulation) - open, read, write, close

장치 관리(Device Management) - ioctl, read, write

정보 유지(Information Maintenance) - getpid, alarm, sleep

통신(Communication) - pipe, shm_open, mmap

보호(Protection) - chmod, unmask, chown

scanf 함수의 read시스템 호출 과정

#include <studio.h> //전처리기, 헤더파일 추가, 헤더파일 int main(void) //메인 함수, 프로그램의 시작점이며 프로젝트에 하나만 존재한다 { //함수의 시작 int num; scanf("%d", &num); //num에 입력받은 d값을 넣는다, &는 그값의 주소를 알려줌 return 0; //반환값 } //함수의 끝


※ 참고))

printf는 그냥 변수 값만 받는데 scanf는 변수의 주소가 필요한 이유

- scanf는 num이라는 변수 자체를 이용하지 않는다. scanf 내부에 다른 변수를 선언하여 그 변수에 num값을 대입하고, 대입한 값을 이용해 변수를 출력하기 때문에, num 값을 바꾸다 보면 문제가 될 수 있어서!

예를 들어))

int num = 3; int result = add(num); printf("num = %d, result = %d", num, result);

1) add함수가 변수 값을 받아 사용할때 → num = 3, result =4

2) add함수가 변수를 직접 사용하는 경우 결과 → num = 4, result = 4

작성하는 사람 입장에서는 1)을 생각하지만

add()함수의 경우 내부에서 어떻게 변할지를 모른다

그렇지만, 경우에 따라서 num값을 실제 받은 값으로 바꿔야 하는 경우라면

(필요한 경우)변수의 주소를 값으로 넘겨주어 처리하여 직접 변수에 접근해서 변수의 실제 값을 바꾸는 것!!

그래서 scanf는 변수 주소값을 인자로 받는다

정리))

특정 함수에 변수들이 들어가서 값이 이리저리 바뀌다 보면 어떤 값이 튀어나올지 모르는데,

사용자 입장에서는 내가 넣어준 "그 값"으로 계산하고 싶을 때가 있을거다

그럴때!!! 변수의 주소를 불러와서 이용하게 되므로,,,,,

scanf는 변수 주소값을 인자로 받는다!

scanf 자체가 주어진 문자열 스트림 소스에서 지정된 형식으로 데이터를 읽어내는 기능임!!


scanf에 대해 더 알아보자

scanf는 c표준 라이브러리에서 제공하는 함수이다

참고로 헤서에 있는 <studio.h>는 표준 입출력 라이브러리의 약어인데,

C언어의 표준 라이브러리 함수의 매크로 정의, 상수, 여러 입출력 함수가 포함된다

그러니, scanf도 여기에 포함되는 함수 중 하나인 것!

리눅스에서는 GNU C library(glibc)가 C 표준 라이브러리를 구현한다

전에 알아보았던 glibc로 알려진 GNU프로젝트가 구현한 표준 라이브러리이다

GNU 시스템과 리눅스 시스템에서 사용하는 대표적인 c 라이브러리라고 보면 된다

키보드, 텍스트 파일 등 각종 파일들로부터 데이터를 읽어오기 위해서 read()함수를 호출한다

strace 도구를 사용하면, 프로그램에서 요청(Call)하는 시스템 호출 목록을 볼 수 있는데

scanf 호출 시에는 read()함수가 불리는 것을 볼 수 있다

read()함수read 시스템 호출의 wrapper함수read 시스템 호출 콜이다

다시 말하지만, 시스템 콜의 종류는 크게 6가지이고 해당 종류들은 아래와 같이 있으니, read()도 그 중의 일부라고 보면 된다

프로세스 제어(Process Control)

fork()

exit()

wait()

파일 조작(File Manipulation)

open()

read()

write()

close()

장지 조작(Device Manipulation)

ioctl()

read()

write()

정보 유지(Information Maintenance)

getpid()

alarm()

sleep()

통신(Commnication)

pipe()

shm_open()

mmap()

보호(Protection)

chmod()

umask()

chown()

wrapper 함수라는 것은,

말그대로 뭔가를 wrapping 해주는 함수이다. 감싼다는 말인데,

예를 들어, C언어로 만들어진 라이브러리를 C++과 같은 클래스 형태로 사용하고자 할때,

한번 감싸주는 것이 wrapper 함수이다.

그러니, 다른 함수를 자신으로 감싸는 녀석이라고 보면 된다.

그리고 당연하게도, 본래 함수의 기능 잃지 않은 상태여야 하는 것이다

그렇기 때문에

read() 함수는 read 시스템 호출의 wrapper 함수로써 read 시스템 호출 콜

이 말은,

read()함수는 read 시스템 콜을 감싸는 녀석으로 read시스템 콜의 기능을 하는 것이다

1)warpper를 통한 시스템 호출

시스템 호출과 일대일로 대응되는 wrapper 함수가 존재한다.

② 어셈블리로 소프트웨어 인터럽트를(0x80)를 발생시켜야 시스템 호출이 발생하는데, wrapper함수가 이를 대신한다

인터럽트 함수의 특징 => 인터럽트가 발생했을 때 커널이 호출하고, 인터럽트 컨텍스트 (interrupt context)라는 특별한 컨텍스트에서 실행된다


※ 참고))

이쯤되면 인터럽트와 시스템 콜이 굉장히 헷갈린다

둘이 뭐가 다르고, 공통점은 뭐고, 뭐가 다른데??

실제로 이 질문을 하는 사람이 굉장히 많은 것을 볼 수 있었다

나도 정리하여 모아봤다

일단 기본적으로, 프로세서는 명령어를 하나씩 실행하게 되는데

가끔씩 프로세스가 일시적으로 멈추고, 현재 명령어를 미루고

다른 프로그램이나 코드 세그먼트(다른 곳에 상주)를 실행해야 하는 경우가 있다

이런 경우 프로세스는 정상 실행으로 돌아가고 중단된 부분부터 계속 된다

맥락이 끊긴다고 봐야하나...하던걸 멈췄다가 다시 실행하는 거다

시스템 호출과 인터럽트가 그런 경우이다

시스템 호출 = 시스템에 내장 된 서브 루틴 호출, 운영체제(커널)의 서비스를 호출하여 사용

또 모르는 용어가 나왔는데, 서브 루틴이다

프로그래밍 시 매크로(macro)가 자주 쓰이는데, 매크로는 자주 반복되는 명령어를 묶어서 하나의 이름으로 만드는 것이다

프로그래밍 시 매크로를 사용하는 부분은 매크로의 원문으로 모두 대체되어 소스코드의 크기가 커지고, 메모리 점유율이 높아진다.

그래서, 이러한 매크로의 단점을 극복하고 반복되는 것을 한번만 써서 메모리 사용을 최대한 줄이도록 한 것서브 루틴이다.

반복되는 특정 기능을 모아서 이름을 붙인 기능은 매크로와 같지만, 프로그램의 흐름이 메인 루틴에 있지 않고 별도의 공간에 한번만 생긴 것이 다르다

따로 빼서 기능을 모아둔거...... 라고 생각하려고 한다

인터럽트 = 외부(CPU 외부) 하드웨어 이벤트로 인한 프로그램 제어 인터럽트

컴퓨터가 정상적으로 실행되는 동안 CPU가 일시적으로 중단되는 이벤트가 발생할 수 있는데, 이것이 인터럽트이다.

1) 하드웨어 인터럽트 = 인터럽트

2) 소프트웨어 인터럽트 = 예외 또는 트랩

인터럽트 발생 시 ISR (인터럽트 서비스 루틴)이라는 특수 서브 루틴으로 전송

ISR (인터럽트 서비스 루틴) : 인터럽트 핸들러와 마찬가지로

인터럽트를 처리하기 위해 커널이 실행하는 함수

그래서, 시스템 호출과 인터럽트의 차이점은?

시스템 호출 = 시스템에 내장된 서브 루틴 호출

인터럽트 = 프로세서가 일시적으로 현재 실행을 보류하게 하는 이벤트

이므로

시스템 호출은 프로그래머에 의해 고정된 시간에서 발생하지만

인터럽트는 사용자가 키보드를 누르는 것과 같은 예기치 않은 이벤트로 인해 발생

말그대로 인터럽트는 의도치 않게 interrupt 받는거고

시스템 호출은 의도적으로 특정 시간동안 호출 하는것

시스템 호출은 프로세서는 어디로 돌아갈 지만 기억 하면 되지만

인터럽트는 프로세서가 시스템을 되돌릴 장소와 시스템의 상태를 기억해야하고,

현재 프로그램과 관련이 없다 (의도치 않은거니깐!!!!)

그러면, 서브루틴을 호출하기 전에 메인루틴에서 어떻게 서브 루틴 종료 후 다시 돌아올 주소값을 저장할 수 있을까?

CALL 명령어를 이용해 서브 루틴(func 함수)을 호출할 시에

CALL 명령어 다음에 메모리 주소를 스택에 저장한다

이 후 서브 루틴의 기능을 수행하고 RETN 명령어를 만나면 현재 ESP레지스터가 가르키고 있는 스택값을 읽는다(ESP가 가르키는 곳에 메인루틴의 CALL 명령어 다음의 주소가 저장 되어 있다)

1. 프로그램에 함수 호출이 발생한다.

2. 스택 프레임이 생성되고 콜 스택에 푸시된다. 스택 프레임은 다음과 같이 구성된다:

1) 함수가 종료되면 복귀할 주소

2) 함수의 모든 매개 변수

3) 지역 변수

4) 함수가 반환할 때 복원해야 하는 수정된 레지스터의 복사본

여기서 스택 프레임은, 스택에 차례대로 저장되는 함수 호출 정보를 말한다.

3. CPU가 함수의 시작점으로 점프한다.

4. 함수 내부의 명령어를 실행한다.

5. 그 이후엔

1) 레지스터가 콜 스택에서 복원된다.

2) 스택 프레임이 콜 스택에서 튀어나온다. 이렇게 하면 모든 지역 변수와 매개 변수에 대한 메모리가 해제된다.

3) 반환 값이 처리된다.

4) CPU는 반환 주소에서 실행을 재개한다.


2)syscall 함수를 통한 시스템 호출

insyscall(int number, ...);

② number는 호출하려는 시스템 호출 번호이며 그 뒤는 가변 인자를 뜻한다

③ wrapper 함수와 마찬가지로 시스템 호출을 대신해주는 역할을 가짐

- 차이점은 모든 시스템 호출을 syscall이란 한 함수로 가능하게 함

- Wrapper 함수가 등록되지 않은 시스템 호출 역시 syscall 함수로 호출 가능

- 시스템 호출 번호는 매크로로 등록되어 있으며 Read 호출 번호 매크로SYS_read

인터럽트 함수의 특징 => 인터럽트가 발생했을 때 커널이 호출하고, 인터럽트 컨텍스트 (interrupt context)라는 특별한 컨텍스트에서 실행된다

원본 출처: http://bit.ly/305e006

시작) 사용자 프로세스에서 fork() systemcall()을 호출한다고 가정하자. (우리가 파일로 작성해준 부분임)

1) C라이브러리 (libac.a)에서 fork()시스템 콜의 고유 번호인 2를 eax레지스터에 저장하고

0x80인터럽트를 발생한다

(int 0x80자체가 소프트웨어 인터럽트 명령이다. int인터럽트 명령이다 <int> == <opcode> )

리눅스 커널에서 제공하는 모든 시스템 콜은 고유한 번호를 가진다

(~/arch/x86/syscalls/syscall_64.tbl 또는 syscall_32.tbl에 정의)

2) IDTR을 이용해 IDT를 찾는다

IDTR은 크기가 48 비트인 레지스터고

상위 32비트IDT가 시작되는 곳의 베이스 어드레스 값,

하위 16비트IDT Entry의 인덱스 값 이다

오른쪽에 숫자가 0,8,16,24,32 씩 올라가는 것은 한개의 크기가 8바이트이기 때문

그래서, 1인터럽트의 시작주소가 0이면, 2인터럽트의 주소는 9이다

IDT는 총 256개의 엔트리를 가짐

각 엔트리가 8바이트이므로

256(IDT 갯수)*8 = 2048바이트 크기

위의 그림에서,

IDTR레지스터Base AddressInterrupt Vector를 오프셋으로

(인터럽트 서비스 = 인터럽트가 걸리고 정해진 내용을 처리하는 과정)

(인터럽트 서비스 루틴 = 만들어진 내용)

(인터럽트 벡터 = 해당 인터럽트 발생 시 루틴의 주소를 담고 있는 테이블)

테스크(task), 인터럽트(interrupt), 트랩 (trap) 게이트 디스크립터(gate descriptor)를 지정한다

(= IDT의 구조에는 인텔의 아키텍쳐인 "게이트"라는 것이 들어갈 수 있는데

총 3종류의 디스크립터가 들어갈 수 있다. 라는 말)

그리고 저 Gate for Interrupt #n 한부분을 확대해서 보면,

이렇게 생겼다. 이 세가지 중 한 개가 들어갈 수 있고

이 세개의 공통된 부분은

이 부분이라고 할 수 있다.

이렇게 하여 찾은 IDT 테이블

IDT(Interrupt Descriptor Table) 인터럽트 디스크립터 테이블

인터럽트가 발생했을 때 처리해주는 함수의 루틴을 포함하고 있는 테이블

총 256개의 엔트리로 구성되고 OffsetLow필드(15~0)와 OffsetHigh필드(31~16)로 나누어진다

두 필드가 합쳐진 32비트 값이 실제 인터럽트 처리 루틴(ISR Interrupt Service Routine)의 주소를 가지고 있는 인터럽트 오브젝트의 주소이다

프로세서는 자신만의 IDT를 가지고 있다. IDT는 메모리 위에 존재하고, 이 위치를 가지키는 레지스터는 IDTR이다

인터럽트 발생 → IDTR을 통해 IDT를 알아냄 → 인터럽트 번호에 대응되는 테이블 엔트리에서 핸들러를 찾아 이 루틴에 정의된 내용을 처리

3) 0x80인자 시스템콜로 int명령을 통해 트랩을 발생시킴

eax레지스터에 fork()함수에 할당되어 있는 고유번호 2를 넣고 0x80을 인자로 하여 트랩을 건다

이렇게 트랩이 걸리면 제어권이 커널로 넘어가게 되고 CPU 모드가 사용자 수준에서 커널 수준으로 변화하게 됩니다.

트랩은 인터럽트와 달리 현재 수행되는 명령어와 직접 연관되어 그 원인 발생

트랩이란, 프로그램이 자동적으로 특정 번지로 점프하여 그곳의 명령을 실행하는 것

커널은 IDT에서 0x80 주소에 있는 system_call()을 찾는다

4) 트랩 발생 후 커널로 제어 이동

CPU의 수행 모드가 커널 레벨로 변화한다

5) 문맥 저장 후 트랩 번호에 대응되는 엔트리에 등록되어 있는 함수를 호출

현재 실행 중이던 task의 context를 저장(하던거 저장)하고 trap 번호에 대응되는 entry에 등록된 함수 호출

여기서 trap 번호는 system_call() 이다.

6) sys_call()에서 eax값을 인덱스(여기서는 2)로 sys_call_table을 탐색하여 sys_fork()함수의 포인터를 얻어옴

※system_call()는 arch/sparc/kernel/entry.S에 구현되어 있다

- system_call() 함수에서는 호출된 시스템콜 번호와 모든 레지스트리를 스택에 저장하고 올바른 번호인지 검사 후, sys_call_table[시스템콜 테이블] 에서 시스템 콜 번호에 해당하는 함수를 호출한다

- system_call()함수는 eax값을 인덱스로 하여 sys_call_table을 탐색한다

결국 sys_fork()포인터를 얻어올 수 있다

(사용자 수준 운용이 fork()라는 systemcall을 요청했고, IDT table과 sys_call_table을 이용해 커널에서 구현된 sys_fork()의 포인터를 얻어올 수 있다)

sys_call_table의 각 entry에는 system call 처리 함수의 시작점 주소가 들어있다.

7) fork() 시스템 콜 호출 후 IDT테이블과 sys_call_table을 이용해 커널에서 구현된 sys_fork()함수 호출

 

 

 

 

출처 :

blog.naver.com/emmaeunji/221765646503

'Linux' 카테고리의 다른 글

Linux) 심볼릭 링크(Symbolic link)  (0) 2021.06.16
리눅스) gcc 명령어  (0) 2020.11.20
Vim Vi ) 복사, 붙이기, 합치기  (0) 2020.11.20
링킹  (0) 2020.10.05

gcc는 C와 C++ 컴파일러이다. 이는 컴파일 뿐만 아니라 전처리, 컴파일, 어셈블리, 링킹의 과정을 모두 진행할 수 있으며, 옵션을 이용하여 그 중간과정만을 이행할 수도 있다.

사용 방식은 다음과 같다.

gcc [option] [filename]

이때, filename은 컴파일의 대상이 되는 파일명이지, 컴파일의 결과에 해당하는 파일의 이름이 아님을 명심한다.

<option>

옵션의 경우 사용 목적에 따라 여러가지로 분류된다.

**옵션을 겹쳐쓰지 않는다! 두 글자 이상의 옵션도 존재하므로 모든 옵션을 따로따로 사용하는 것이 좋다!**

<Overall option>

* -c : 컴파일과 어셈블은 하되, 링킹은 하지 않는다. (각 파일의 오브젝트 파일이 결과물이 된다.)

* -S : 컴파일은 하되, 어셈블은 하지 않는다. (어셈블러 코드가 결과물이 된다.)

* -E : 전처리만 한다. (전처리가 필요없는 파일은 이 옵션을 무시한다.)

* -o [file] : [file]의 이름을 가진 파일로 출력한다. (확장자에 상관 없이 출력하며, 하지 않을 시 자동으로 [filename].out형태로 출력한다.)

* -x [language] : 특별히 파일의 확장자명을 명시한다. (이후 파일들에 한꺼번에 적용이 가능하다.)

* -x : 확장자 명시를 해제한다.

* -v : vervose의 약자로 컴파일 과정 보고, 컴파일러 드라이버, 전처리기 버전 출력을 한다.

* -pass-exit-codes : 프로그램의 비정상 종료시 1이 아닌 4를 출력한다.

* -pipe : 프로그램을 동시에 실행한다. (임시로 몇 단계 프로그램 만들지 말고 이걸 쓰면 된다.)

* -static : 정적 링크 라이브러리를 사용하도록 한다.(공유 라이브러리를 사용하지 않는다.)

* --save-temps : 컴파일 과정에서 생성되는 중간 파일인 전처리 파일(*.i)과 어셈블리 파일(*.s)을 지우지 않고, 현재 디렉토리에 저장한다. (오류 분석에 사용된다.)

* -fPIC : so파일의 속도 개선을 위한 옵션이다.

* -shared : so파일을 컴파일하기 위한 옵션이다.

* -fno-stack-protector : SSP를 끈다.

* -fstack-protector-all : SSP를 모든 함수에 설치한다.(SSP는 로컬변수 재배치, 로컬변수 전에 포인터 설치, canary 삽입을 담당한다.)

* -m32 : 32비트로 프로그램을 만든다.

* -m64 : 64비트로 프로그램을 만든다.

* -no-pie : 메모리 보호기법인 PIE를 사용하지 않는다.

* -fpie –pie : PIE를 사용한다. --enable-default-pie 와 같은 기능을 한다.

* -mpreferred-stack-boundary(=[number]) : main함수에 스택을 정렬하는 이상한 인스트럭션을 제거한다.

* -z relro : RELRO (Relocation Read-Only) 를 적용한다.

* -z execstack : DEP (Data Execution Prevention)을 실행한다.

* -z stack-protector : CANARY를 사용한다.

* -z stack-boundary : 스택 더미를 활성화한다.

<Warning option>

코딩의 모호함에 대해 경고를 보내는 정도에 대한 옵션이다.

* -Wall : 모든 모호한 코딩에 대해서 경고를 보낸다.

* -W : 합법적이지만 모호한 코딩에 대해서 경고를 보낸다.

* -w : 모든 경고메시지를 제거한다.

* -Werror : 모든 경고를 컴파일을 중단하는 오류로 취급한다.

<Optimization option>

프로그램의 최적화를 얼마만큼 할 지를 명시하는 옵션이다.

*-O0 : 최적화를 수행하지 않는다.

*-O1 : 조금 최적화한다.

*-O2 : 가장 많이 사용하는 최적화이다. 일반 응용프로그램이나 커널을 컴파일할 때 사용한다.(거의 대부분의 최적화를 수행한다.)

*-O3 : 가장 높은 레벨의 최적화이다. 모든 함수를 인라인 함수와 같이 취급한다.(왜곡 발생 가능성이 높다.)

*-O5 : 사이즈 최적화를 실행한다. (임베디드 시스템에서 사용한다.)

<Debugging option>

디버깅 용도를 위해 추가하는 옵션이다.

*-g : gdb에게 제공하는 정보를 바이너리에 삽입한다.

*-pg : 프로파일을 위한 코드 삽입을 담당한다.

 

다음은 확장자명 별 의미이다. 리눅스는 윈도우와 달리 확장자명이 프로그램의 실행에 영향을 미치지 않는다. 따라서 리눅스에서는 사용자의 참고용으로서 의미를 가진다.

<확장자명>

*[file].c : C 소스코드 (전처리가 필요하다.)

*[file].i : 전처리 금지 C 소스코드

*[file].cc, [file].cp, [file].cxx, [file].cpp, [file].c++, [file].C : C++ 소스코드 (전처리가 필요하다.)

*[file].ii : 전처리 금지 C++ 소스코드

*[file].h : 헤더파일

*[file].s : 어셈블리 코드

 

 

 

출처 : 

blog.naver.com/apple8718/222038588396

Vim - Vi복사하기, vi 붙이기, vi 합치기

 

복사


- y (Yank) : 복사하기
- yy : 한 줄 전체의 내용을 복사한다
- 2yy : 두줄복사
- nyy : 현재 줄 이하로 n개의 줄을 복사한다 (n은 임의의 숫자, 2yy는 2줄 복사)
- ynw : n개의 단어를 복사한다(y2w는 두 개의 단어를 복사)
- yw : 한단어 복사
- y2w : 두단어 복사
- y$ : 현재 위치에서 그 줄의 끝까지 복사한다
- y0(y^) : 현재 위치에서 그 줄의 처음까지 복사한다
- yG : 현재 위치에서 파일의 끝까지 복사한다(G는 파일의 마지막 줄)
- Y : 한 줄 전체의 내용을 복사한다 (yy 와 동일)
※ 마지막 명령어의 반복 - . : 마지막에 수행한 명령어를 반복한다.
-2. : 명령어를 2번 반복한다.

붙이기

- p (Put or Paste) : 붙이기
- p : 버퍼에 저장된 내용을 커서의 오른쪽으로 붙여 넣는다.
- 2p : 아래로(오른쪽으로) 두번 붙이기
- np : n번만큼 p 명령을 반복. 2p라면 버퍼의 내용을 두 번 붙여넣는다
- P : 위로(왼쪽으로) 붙이기
- 2P : 위로(왼쪽으로) 두번 붙이기
- nP : 버퍼에 저장된 내용을 커서의 왼쪽으로 붙여넣는다. 사용법은 p와 같다

합치기

- J(Join) : 여러 줄의 내용을 한 줄로 합친다
- J : 현재줄을 윗줄에 붙인다. (두줄 합치기)
- nJ : n개의 줄을 합쳐 한 줄로 만든다. 커서는 원본 문서의 마지막 줄의 첫번째 위치(합쳐진 줄에서는 중간)에 놓인다. 5J는 5줄로 이루어진 내용을 한 줄로 만든다

다른파일 삽입|병합|하기: Insert merge file

 

- r test.txt

- r /경로/test.txt

 

복구하기

- u (Undo) : 되살리기 명령으로 버퍼에 저장되어 있는 원래의 내용을 복구
- u : 한번복구하기
- 'nu' : (n은 임의의 숫자) 형식으로 사용하며, n 단계까지의 명령을 복구할 수 있다
- 2u : 두번복구하기
-Ctrl +r == REDO

 



출처 :

https://booolean.tistory.com/346 [Boolean]

윈도우 cmd, 리눅스, 유닉스 명령어

 

 

netstat -na 명령어
 


-a’옵션은 연결된 혹은 연결을 기다리고 있는 모든 포트를 보여주는 옵션

 

-n’은 컴퓨터 이름 대신 IP 주소가 보이도록 하는 옵션

'Linux > Linux 명령어' 카테고리의 다른 글

리눅스에서 붙여넣기 ctrl + v 사용  (0) 2020.10.20
strings 명령어  (0) 2020.10.06
man 명령어  (0) 2020.10.05
objdump 명령어  (0) 2020.10.05
Linux) file 명령어  (0) 2020.10.05

리눅스 환경에서는 ctrl + v를 사용하면 다른 명령이 수행되는 경우가 많다.

 

shift + ctrl + v 를 사용하면 윈도우 환경에서의 붙여넣기처럼 사용가능하다.

'Linux > Linux 명령어' 카테고리의 다른 글

netstat 명령어  (0) 2020.10.23
strings 명령어  (0) 2020.10.06
man 명령어  (0) 2020.10.05
objdump 명령어  (0) 2020.10.05
Linux) file 명령어  (0) 2020.10.05

+ Recent posts