GCC 빌드하기
Ubuntu 18.04 64 비트 GCC 8.2 버전 컴파일
업데이트
sudo apt-get update
sudo apt-get upgrade
코드 다운로드
cd ~
wget https://ftpmirror.gnu.org/gcc/gcc-8.2.0/gcc-8.2.0.tar.gz
tar xf gcc-8.2.0.tar.gz
cd gcc-8.2.0
contrib/download_prerequisites
환경 구성
cd ~
mkdir build && cd build
../gcc-8.2.0/configure -v --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --prefix=/usr/local/gcc-8.2 --enable-checking=release --enable-languages=c,c++,fortran --disable-multilib --program-suffix=-8.2
적용 -j 8 cpu 코어 확인
make -j 8
설치
sudo make install
실행 경로 추가
export export PATH=/usr/local/gcc-8.2/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/gcc-8.2/lib64:$LD_LIBRARY_PATH
.bashrc 추가
cd ~
vi .bashrc
export export PATH=/usr/local/gcc-8.2/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/gcc-8.2/lib64:$LD_LIBRARY_PATH
// C++14 일반화 된 람다(매개변수 유형 auto 사용)
// https://solarianprogrammer.com/2014/08/21/cpp-14-auto-tutorial/
#include <iostream>
int main() {
std::cout << [](auto a, auto b) { return a + b; } (5, 6) << std::endl;
std::cout << [](auto a, auto b) { return a + b; } (5.23, 6.45) << std::endl;
return 0;
}
컴파일
g++-8.2 -Wall -pedantic test_lambda.cpp -o test_lambda
./test_lambda
static_assert 수정 예제 테스트
// https://solarianprogrammer.com/2014/08/21/cpp-14-auto-tutorial/
#include <type_traits>
#include <iostream>
struct A {
int foo;
};
struct B {
int foo = 0;
};
template <typename T>
void print(const T& a){
static_assert(std::is_pod<T>::value);
std::cout << a.foo << '\n';
}
int main() {
A x{1};
B y{2};
B z;
print<A>(x);
print<B>(y);
print<B>(z);
return 0;
}
컴파일
g++-8.2 -std=c++17 -Wall -pedantic test_assert.cpp -o test_assert
test_assert.cpp: In instantiation of ‘void print(const T&) [with T = B]’:
test_assert.cpp:24:15: required from here
test_assert.cpp:14:5: error: static assertion failed
static_assert(std::is_pod<T>::value);
^~~~~~~~~~~~~
Fortran 프로그래머라면 gfortran-8.2와 병행 하여 다음과 같은 Fortran 2008 기능 중 일부를 사용할 수 있음.
integer,parameter::mm=100000
real::a(mm), b(mm)
real::fact=0.5
! initialize the arrays
! ...
do concurrent (i = 1 : mm)
a(i) = a(i) + b(i)
enddo
end
컴파일 테스트
gfortran-8.2 test_concurrent_do.f90 -o test_concurrent_do
./test_concurrent_do
카테고리
asm
(27)
bootloader_x86_grub
(1)
C
(92)
compile
(11)
config
(76)
CPP
(13)
CSS
(1)
debugging
(7)
gimp
(1)
Go
(1)
html
(1)
Java
(1)
JavaScript
(1)
kernel
(19)
LibreOffice
(3)
Linux system progamming
(21)
MFC
(1)
opencv
(4)
OpenGL
(1)
PHP
(1)
Python
(4)
qemu
(29)
shell
(3)
socket
(7)
troubleshooting
(2)
ubuntu18.04
(2)
windows
(1)
2019/01/03
전처리기
전처리기
#define 전 처리기 지시문으로 프로그램에서 상수 값을 정의하는데 사용된다.
#pragma -> 컴파일 옵션 조절 키워드.
#pragma pack -> 메모리 패킹(펜딩) 처리.
#pragma once -> 헤더 중복 방지.
지시문 구문
#define macro_name value
기본 사용 예
#include<stdio.h>
#define PI 3.14 // 3.14 PI 정의
void main()
{
int r;
float area;
printf("Enter radius : ");
scanf("%d",&r);
area = PI * r * r;
printf("\nArea of circle is : %f",area);
}
Output :
Enter radius : 5
Area of circle is : 78.5
기본 사용 예
#include<stdio.h>
#define SIZE 5 // 5를 SIZE
void main()
{
int arr[SIZE];
for(int i=0;i<SIZE;i++)
{
printf("Enter any number : ");
scanf("%d",&arr[i]);
}
for(i=0;i<SIZE;i++)
printf("%d, ",arr[i]);
}
Output :
Enter any number : 78
Enter any number : 45
Enter any number : 12
Enter any number : 89
Enter any number : 56
78, 45, 12, 89, 56,
기본 사용 예
#include<stdio.h>
#define SQUARE(x) x*x // 가로 * 세로 = 넓이, 함수와 사용시 연산자 우선 순위 확인
void main()
{
int num;
printf("Enter any number : ");
scanf("%d",&num);
printf("\nThe square is : %d",SQUARE(num));
}
Output :
Enter any number : 5
The square is : 25
#include 전 처리기 지시문의 구문
#include "filename.h"
or
#include <filename.h>
# if- # else- # endif 전처리 지시문
조건이 true이면 #if와 #else 사이에 제공된 명령문이 실행.
조건이 거짓이면 #else와 #endif 사이에 주어진 명령문이 실행
#if(condition)
- - - - - - - - - -
- - - - - - - - - -
#else
- - - - - - - - - -
- - - - - - - - - -
#endif
# if- # else- # endif 전처리 지시문의 예
#include<stdio.h>
#define MAX 45
void main()
{
#if MAX > 40
printf("Yes, MAX is greater then 40.");
#else
printf("No, MAX is not greater then 40.");
#endif
}
Output :
Yes, MAX is Greater then 40.
#elif 전 처리기 지시문
여러 조건을 검사하는 데 사용
첫 번째 조건이 만족스럽지 않으면 컴파일러는 #else 블록으로 건너 뛰고 다른 조건이 참인지 여부 등을 확인
# if- # elif- # else- # endif 전 처리기 지시문의 구문
#if(condition)
- - - - - - - - - -
- - - - - - - - - -
#elif(condition)
- - - - - - - - - -
- - - - - - - - - -
#elif(condition)
- - - - - - - - - -
- - - - - - - - - -
#else
- - - - - - - - - -
- - - - - - - - - -
#endif
# if- # elif- # else- # endif 전처리 지시문의 예
#include<stdio.h>
#define MKS 65
void main()
{
#if MKS>=78
printf("\nGrade A");
#elif MKS>=50
printf("\nGrade B");
#elif MKS>=25
printf("\nGrade C");
#else
printf("\nGrade D");
#endif
}
Output :
Grade B
#ifdef 전처리 지시문
매크로 이름이 이전에 정의되었는지 여부를 확인하는 데 사용
정의 된 경우 #ifdef와 #else 사이에 제공된 명령문이 실행
#ifdef 전 처리기 지시문의 구문
#ifdef macro-name
- - - - - - - - - -
- - - - - - - - - -
#else
- - - - - - - - - -
- - - - - - - - - -
#endif
#ifdef 전 처리기 지시문의 예
#include<stdio.h>
#define MKS 65
void main()
{
#ifdef MONTH
printf("\nMONTH is defined.");
#else
printf("\nMONTH is not defined.");
#endif
}
Output :
MONTH is not defined.
#ifndef 전처리 지시문
매크로 이름이 이전에 정의되었는지 여부를 확인하는 데 사용되며 정의되지 않은 경우 #ifndef와 #else 사이에 제공된 명령문이 실행
#ifndef 전처리 지시문의 구문
#ifndef macro-name
- - - - - - - - - -
- - - - - - - - - -
#else
- - - - - - - - - -
- - - - - - - - - -
#endif
#ifndef 전 처리기 지시문의 예
#include<stdio.h>
#define MKS 65
void main()
{
#ifndef MAX
printf("\nMAX is not defined.");
#else
printf("\nMAX is defined.");
#endif
}
Output :
MAX is not defined.
#line 전처리 지시문
#line 전처리 지시문은 사전 정의 된 매크로 이름 __LINE__ 및 __FILE__의 기본값을 덮어 쓰는 데 사용
defalut으로 __LINE__은 현재 줄 번호를 표시하고 __FILE__은 현재 파일 이름을 표시
#line 전 처리기 지시어 1의 예 :
#include<stdio.h>
void main()
{
printf("\nLine number %d",__LINE__);
printf("\nFile name %s",__FILE__);
}
Output :
Line number : 4
File name : LineDemo.c
#line 전 처리기 지시어 2의 예 :
#include<stdio.h>
#line 25 Demo.c
void main()
{
printf("\nLine number %d",__LINE__);
printf("\nFile name %s",__FILE__);
}
Output :
Line number : 25
File name : Demo.c
#error 전 처리기 지시문
컴파일러가 컴파일을 중지하고 치명적인 오류를 발생하게 함.
#error 전 처리기 지시어 1의 예 :
#include<stdio.h>
void main()
{
#ifndef MAX
printf("\nMAX is not defined."); //Statement 1
#else
printf("\nMAX is defined."); //Statement 2
#endif
printf("\nEnd of program."); //Statement 3
}
Output :
MAX is not defined.
End of program.
#error 전처리 지시어 2의 예 :
#include<stdio.h>
void main()
{
#ifndef MAX
#error MAX is not defined. //Statement 1
#else
printf("\nMAX is defined."); //Statement 2
#endif
printf("\nEnd of program."); //Statement 3
}
예제 1과 2의 유일한 차이는 문장 하나다.
예제 1에서 문장 1은 메시지를 표시하고 나머지 코드를 계속 컴파일합니다.
예제 2에서, 문장 1은 컴파일러에게 치명적인 에러를 주게하고 나머지 코드의 컴파일을 중단합니다.
#define 전 처리기 지시문으로 프로그램에서 상수 값을 정의하는데 사용된다.
#pragma -> 컴파일 옵션 조절 키워드.
#pragma pack -> 메모리 패킹(펜딩) 처리.
#pragma once -> 헤더 중복 방지.
지시문 구문
#define macro_name value
기본 사용 예
#include<stdio.h>
#define PI 3.14 // 3.14 PI 정의
void main()
{
int r;
float area;
printf("Enter radius : ");
scanf("%d",&r);
area = PI * r * r;
printf("\nArea of circle is : %f",area);
}
Output :
Enter radius : 5
Area of circle is : 78.5
기본 사용 예
#include<stdio.h>
#define SIZE 5 // 5를 SIZE
void main()
{
int arr[SIZE];
for(int i=0;i<SIZE;i++)
{
printf("Enter any number : ");
scanf("%d",&arr[i]);
}
for(i=0;i<SIZE;i++)
printf("%d, ",arr[i]);
}
Output :
Enter any number : 78
Enter any number : 45
Enter any number : 12
Enter any number : 89
Enter any number : 56
78, 45, 12, 89, 56,
기본 사용 예
#include<stdio.h>
#define SQUARE(x) x*x // 가로 * 세로 = 넓이, 함수와 사용시 연산자 우선 순위 확인
void main()
{
int num;
printf("Enter any number : ");
scanf("%d",&num);
printf("\nThe square is : %d",SQUARE(num));
}
Output :
Enter any number : 5
The square is : 25
#include 전 처리기 지시문의 구문
#include "filename.h"
or
#include <filename.h>
# if- # else- # endif 전처리 지시문
조건이 true이면 #if와 #else 사이에 제공된 명령문이 실행.
조건이 거짓이면 #else와 #endif 사이에 주어진 명령문이 실행
#if(condition)
- - - - - - - - - -
- - - - - - - - - -
#else
- - - - - - - - - -
- - - - - - - - - -
#endif
# if- # else- # endif 전처리 지시문의 예
#include<stdio.h>
#define MAX 45
void main()
{
#if MAX > 40
printf("Yes, MAX is greater then 40.");
#else
printf("No, MAX is not greater then 40.");
#endif
}
Output :
Yes, MAX is Greater then 40.
#elif 전 처리기 지시문
여러 조건을 검사하는 데 사용
첫 번째 조건이 만족스럽지 않으면 컴파일러는 #else 블록으로 건너 뛰고 다른 조건이 참인지 여부 등을 확인
# if- # elif- # else- # endif 전 처리기 지시문의 구문
#if(condition)
- - - - - - - - - -
- - - - - - - - - -
#elif(condition)
- - - - - - - - - -
- - - - - - - - - -
#elif(condition)
- - - - - - - - - -
- - - - - - - - - -
#else
- - - - - - - - - -
- - - - - - - - - -
#endif
# if- # elif- # else- # endif 전처리 지시문의 예
#include<stdio.h>
#define MKS 65
void main()
{
#if MKS>=78
printf("\nGrade A");
#elif MKS>=50
printf("\nGrade B");
#elif MKS>=25
printf("\nGrade C");
#else
printf("\nGrade D");
#endif
}
Output :
Grade B
#ifdef 전처리 지시문
매크로 이름이 이전에 정의되었는지 여부를 확인하는 데 사용
정의 된 경우 #ifdef와 #else 사이에 제공된 명령문이 실행
#ifdef 전 처리기 지시문의 구문
#ifdef macro-name
- - - - - - - - - -
- - - - - - - - - -
#else
- - - - - - - - - -
- - - - - - - - - -
#endif
#ifdef 전 처리기 지시문의 예
#include<stdio.h>
#define MKS 65
void main()
{
#ifdef MONTH
printf("\nMONTH is defined.");
#else
printf("\nMONTH is not defined.");
#endif
}
Output :
MONTH is not defined.
#ifndef 전처리 지시문
매크로 이름이 이전에 정의되었는지 여부를 확인하는 데 사용되며 정의되지 않은 경우 #ifndef와 #else 사이에 제공된 명령문이 실행
#ifndef 전처리 지시문의 구문
#ifndef macro-name
- - - - - - - - - -
- - - - - - - - - -
#else
- - - - - - - - - -
- - - - - - - - - -
#endif
#ifndef 전 처리기 지시문의 예
#include<stdio.h>
#define MKS 65
void main()
{
#ifndef MAX
printf("\nMAX is not defined.");
#else
printf("\nMAX is defined.");
#endif
}
Output :
MAX is not defined.
#line 전처리 지시문
#line 전처리 지시문은 사전 정의 된 매크로 이름 __LINE__ 및 __FILE__의 기본값을 덮어 쓰는 데 사용
defalut으로 __LINE__은 현재 줄 번호를 표시하고 __FILE__은 현재 파일 이름을 표시
#line 전 처리기 지시어 1의 예 :
#include<stdio.h>
void main()
{
printf("\nLine number %d",__LINE__);
printf("\nFile name %s",__FILE__);
}
Output :
Line number : 4
File name : LineDemo.c
#line 전 처리기 지시어 2의 예 :
#include<stdio.h>
#line 25 Demo.c
void main()
{
printf("\nLine number %d",__LINE__);
printf("\nFile name %s",__FILE__);
}
Output :
Line number : 25
File name : Demo.c
#error 전 처리기 지시문
컴파일러가 컴파일을 중지하고 치명적인 오류를 발생하게 함.
#error 전 처리기 지시어 1의 예 :
#include<stdio.h>
void main()
{
#ifndef MAX
printf("\nMAX is not defined."); //Statement 1
#else
printf("\nMAX is defined."); //Statement 2
#endif
printf("\nEnd of program."); //Statement 3
}
Output :
MAX is not defined.
End of program.
#error 전처리 지시어 2의 예 :
#include<stdio.h>
void main()
{
#ifndef MAX
#error MAX is not defined. //Statement 1
#else
printf("\nMAX is defined."); //Statement 2
#endif
printf("\nEnd of program."); //Statement 3
}
예제 1과 2의 유일한 차이는 문장 하나다.
예제 1에서 문장 1은 메시지를 표시하고 나머지 코드를 계속 컴파일합니다.
예제 2에서, 문장 1은 컴파일러에게 치명적인 에러를 주게하고 나머지 코드의 컴파일을 중단합니다.
파입 입출력
파일 입출력
모든 프로그램은 실행시 메모리에 올라간다.
주 메모리는 휘발성이므로 프로그램이 종료되면 데이터가 사라지게 된다.
만얀 동일한 데이터가 필요하면 디스크에 파일을 저장해 손실을 막는다
C에서 지원하는 파일 형식:
- 텍스트 파: 사람이 확인 읽을 수 있는 내용.(아스키, 유니코드)
- 이진 파일: 사람이 직관적으로 확인 할 수 없는 내용.
파일 포인터
FILE * fp;
파일 접근 방법.
fp = fopen(char *filename,char *mode);
void main()
{
FILE *fp;
fp = fopen("file1.txt","r"); //Statement 1
if(fp == NULL)
{
printf("\nCan't open file or file doesn't exist.");
exit(0);
}
}
int fclose( FILE* );
void main()
{
FILE *fp;
fp = fopen("file1.txt","r");
if(fp == NULL)
{
printf("\nCan't open file or file doesn't exist.");
exit(0);
}
- - - - - - - - - -
- - - - - - - - - -
fclose(fp);
}
모든 프로그램은 실행시 메모리에 올라간다.
주 메모리는 휘발성이므로 프로그램이 종료되면 데이터가 사라지게 된다.
만얀 동일한 데이터가 필요하면 디스크에 파일을 저장해 손실을 막는다
C에서 지원하는 파일 형식:
- 텍스트 파: 사람이 확인 읽을 수 있는 내용.(아스키, 유니코드)
- 이진 파일: 사람이 직관적으로 확인 할 수 없는 내용.
파일 포인터
FILE * fp;
파일 접근 방법.
fp = fopen(char *filename,char *mode);
void main()
{
FILE *fp;
fp = fopen("file1.txt","r"); //Statement 1
if(fp == NULL)
{
printf("\nCan't open file or file doesn't exist.");
exit(0);
}
}
int fclose( FILE* );
void main()
{
FILE *fp;
fp = fopen("file1.txt","r");
if(fp == NULL)
{
printf("\nCan't open file or file doesn't exist.");
exit(0);
}
- - - - - - - - - -
- - - - - - - - - -
fclose(fp);
}
자료구죠 키워드 정리.
나열 방법 -> 탐색 및 검색을 잘 하게 하는 알고리즘 구조
선형: 연결 리스트, stack, queue, dequeu
비선형: Tree
stack
push: pop == 입력 방향, 출력방향이 하나임. 입출구가 하나인 박스공간.
Queue: 줄서기
Push:Pop == 단방향
Dequeu: 상호작용
Push:Pop == 양방향
a) 선택 정렬
->선택 정렬은 비교는 많지만, 교환은 적은 알고리즘이다.
장점: 정렬된 상태를 역순으로 정렬시 효율적이다.
단점: 정렬된 데이터에 소수의 데이터 추가시 이를 다시 정렬하기 위해서는 최악이다.
$ cat ages.txt
Bob 12
Jane 48
Mark 3
Tashi 54
$ sort -k2 -n ages.txt
Mark 3
Bob 12
Jane 48
Tashi 54
sort -n -k 7 /path/to/input
find . -type f -iname "pattern*" -ls |sort -n -k 7
find . -type f -iname "pattern*" -ls |sort -r -n -k 7
-r -정렬 결과를 반대.
-n -숫자 정렬
-k 7 -POS1에서 키 시작 즉, 7 번에서 정렬 키 시작
-s 정렬 안정화
b) 버블 정렬
시간복잡도: O(N^2)
->데이터를 하나씩 비교할 수 있어서 정밀하게 비교 가능하나 비교횟수가 많아지므로
성능면에서 좋은 방법이 아니다. 첫번째 원소부터 마지막 원소까지 비교가 끝나면 가장 큰 원소를 마지막 자리로 정렬한다.
# Bash 배열 정렬
# Bubble 정렬 사용
# 정적 배열 입력
arr = (10 8 20 100 12)
echo "Array in original order"
echo ${arr[*]}
# 버블 정렬 수행
for ((i = 0; i<5; i++))
do
for((j = i; j<5-i-1; j++))
do
if ((${arr[j]} > ${arr[$((j+1))]}))
then
# swap
temp = ${arr[$j]}
arr[$j] = ${arr[$((j+1))]}
arr[$((j+1))] = $temp
fi
done
done
echo "Array in sorted order :"
echo ${arr[*]}
출력 :
Array in sorted order :
8 10 12 20 100
c) 퀵정렬 >
시간복잡도
최악- O(N^2)
평균- O(NlogN)
->캐시라는 지역적 특성에 의해 실제적으로 NlogN보다 좋은 성능을 보여 가장 많이 사용하는 정렬이다. 단점으로는 안정성이없다. 안정성이 없다는 것은 정렬되기 이전의 데이터 동일한 데이터끼리의 순서를 정렬 후에도 유지하고 있는가이다.
d) 삽입정렬 >
시간복잡도 : O(N^2)
버블정렬이 조금 비효율적인 면이 있기에 비교횟수를 효율적으로 줄이기 위해 고안된 삽입정렬이다. 버블정렬은 비교대상의 메모리 값이 정렬되어 있음에도 불구하고 비교연산을 하는 부분이 있는데 삽입정렬은 비교적 비교횟수를 줄이고 , 정렬된 값은 한번도 교환이 일어나지 않고 N-1의 비교만 일어난다.
e) 쉘 정렬 >
시간복잡도: O(N^1.25)
삽입정렬의 개념을 확대하여 일반화한 정렬방법이다. 알고리즘이 간단하여 간단히 구현할 수 있다. 수행능력도 삽입정렬보다 우수하다. 멀리있는 레코드들 끼리 비교 및 교환 될 수 있으므로, 어떤 데이터가 제 위치에서 멀리 떨어져 있다면 여러 번의 교환이 발생하는 버블정렬의 단점을 해결 할 수 있다.
f) 병합 정렬>
시간복잡도: O(NlogN)
작은 단위부터 정렬해서 정렬된 단위들을 계속 병합해가면서 정렬하는 방식이다. 알고리즘 중에 가장 간단하고 쉽게 떠올릴 수 있는 방법이다. 안정성이 있으며 상당히 좋은 성능을 나타낸다. 큰 결점은 데이터 크기만한 메모리가 더 필요하다는 것이다.
g) 버킷정렬>
버킷정렬은 정렬대상의 키들을 일정한 범위로 구분해 버킷(통)에 넣고 그 버킷을 각각 정렬하는 방법이다.
특징: 키가 어떤 범위내에서 키값이 확률적으로 균등하게 분포되어 있을 때 적용하면 효과가 좋다.
실행시간: 버켓에 넣는 시간 O(n)+정렬시간
사용하기 좋은 예: "Person 객체를 담은 아주 큰 배열이 있다고 하자. 이 배열에 담긴 객체들을 나이순으로 정렬하라"
여기서 두 힌트를 얻을 수 있다.
1. 큰 배열이므로 효율성이 중요하다.
2. 나이에 따라 정렬하는 것이므로, 그 값의 범위가 좁게 제한되어 있음을 이용할 수 있다.
정렬 알고리즘들을 살펴보면, 아마 버킷정렬 또는 기수 정렬이 가장 적합하리라는 것을 눈치 챌 수 있을 것이다. 버킷을 작게 만들 수 있고(각 버킷에 1년)O(n)으 실행시간을 달성할 수 있다. 그렇다면 값의 범위가 작을 때 사용하기 좋은 정렬?
선형: 연결 리스트, stack, queue, dequeu
비선형: Tree
stack
push: pop == 입력 방향, 출력방향이 하나임. 입출구가 하나인 박스공간.
Queue: 줄서기
Push:Pop == 단방향
Dequeu: 상호작용
Push:Pop == 양방향
a) 선택 정렬
->선택 정렬은 비교는 많지만, 교환은 적은 알고리즘이다.
장점: 정렬된 상태를 역순으로 정렬시 효율적이다.
단점: 정렬된 데이터에 소수의 데이터 추가시 이를 다시 정렬하기 위해서는 최악이다.
$ cat ages.txt
Bob 12
Jane 48
Mark 3
Tashi 54
$ sort -k2 -n ages.txt
Mark 3
Bob 12
Jane 48
Tashi 54
sort -n -k 7 /path/to/input
find . -type f -iname "pattern*" -ls |sort -n -k 7
find . -type f -iname "pattern*" -ls |sort -r -n -k 7
-r -정렬 결과를 반대.
-n -숫자 정렬
-k 7 -POS1에서 키 시작 즉, 7 번에서 정렬 키 시작
-s 정렬 안정화
b) 버블 정렬
시간복잡도: O(N^2)
->데이터를 하나씩 비교할 수 있어서 정밀하게 비교 가능하나 비교횟수가 많아지므로
성능면에서 좋은 방법이 아니다. 첫번째 원소부터 마지막 원소까지 비교가 끝나면 가장 큰 원소를 마지막 자리로 정렬한다.
# Bash 배열 정렬
# Bubble 정렬 사용
# 정적 배열 입력
arr = (10 8 20 100 12)
echo "Array in original order"
echo ${arr[*]}
# 버블 정렬 수행
for ((i = 0; i<5; i++))
do
for((j = i; j<5-i-1; j++))
do
if ((${arr[j]} > ${arr[$((j+1))]}))
then
# swap
temp = ${arr[$j]}
arr[$j] = ${arr[$((j+1))]}
arr[$((j+1))] = $temp
fi
done
done
echo "Array in sorted order :"
echo ${arr[*]}
출력 :
Array in sorted order :
8 10 12 20 100
c) 퀵정렬 >
시간복잡도
최악- O(N^2)
평균- O(NlogN)
->캐시라는 지역적 특성에 의해 실제적으로 NlogN보다 좋은 성능을 보여 가장 많이 사용하는 정렬이다. 단점으로는 안정성이없다. 안정성이 없다는 것은 정렬되기 이전의 데이터 동일한 데이터끼리의 순서를 정렬 후에도 유지하고 있는가이다.
d) 삽입정렬 >
시간복잡도 : O(N^2)
버블정렬이 조금 비효율적인 면이 있기에 비교횟수를 효율적으로 줄이기 위해 고안된 삽입정렬이다. 버블정렬은 비교대상의 메모리 값이 정렬되어 있음에도 불구하고 비교연산을 하는 부분이 있는데 삽입정렬은 비교적 비교횟수를 줄이고 , 정렬된 값은 한번도 교환이 일어나지 않고 N-1의 비교만 일어난다.
e) 쉘 정렬 >
시간복잡도: O(N^1.25)
삽입정렬의 개념을 확대하여 일반화한 정렬방법이다. 알고리즘이 간단하여 간단히 구현할 수 있다. 수행능력도 삽입정렬보다 우수하다. 멀리있는 레코드들 끼리 비교 및 교환 될 수 있으므로, 어떤 데이터가 제 위치에서 멀리 떨어져 있다면 여러 번의 교환이 발생하는 버블정렬의 단점을 해결 할 수 있다.
f) 병합 정렬>
시간복잡도: O(NlogN)
작은 단위부터 정렬해서 정렬된 단위들을 계속 병합해가면서 정렬하는 방식이다. 알고리즘 중에 가장 간단하고 쉽게 떠올릴 수 있는 방법이다. 안정성이 있으며 상당히 좋은 성능을 나타낸다. 큰 결점은 데이터 크기만한 메모리가 더 필요하다는 것이다.
g) 버킷정렬>
버킷정렬은 정렬대상의 키들을 일정한 범위로 구분해 버킷(통)에 넣고 그 버킷을 각각 정렬하는 방법이다.
특징: 키가 어떤 범위내에서 키값이 확률적으로 균등하게 분포되어 있을 때 적용하면 효과가 좋다.
실행시간: 버켓에 넣는 시간 O(n)+정렬시간
사용하기 좋은 예: "Person 객체를 담은 아주 큰 배열이 있다고 하자. 이 배열에 담긴 객체들을 나이순으로 정렬하라"
여기서 두 힌트를 얻을 수 있다.
1. 큰 배열이므로 효율성이 중요하다.
2. 나이에 따라 정렬하는 것이므로, 그 값의 범위가 좁게 제한되어 있음을 이용할 수 있다.
정렬 알고리즘들을 살펴보면, 아마 버킷정렬 또는 기수 정렬이 가장 적합하리라는 것을 눈치 챌 수 있을 것이다. 버킷을 작게 만들 수 있고(각 버킷에 1년)O(n)으 실행시간을 달성할 수 있다. 그렇다면 값의 범위가 작을 때 사용하기 좋은 정렬?
공용체 union
공용체
자료형 모음 하나에 대한, 각기 다른 해석이 가능한 자료형
융통성이 좋음, 즉 생각을 많이 해야함.
구조는 모든 멤버에 대해 서로 다른 메모리 위치를 할당 함.
union은 모든 메모에 대해 고통 메모리 위치 할당.
union union-name
{
datatype var1;
datatype var2;
- - - - - - - - - -
- - - - - - - - - -
datatype varN;
};
멤버 저근 객체 생성 구문
union union-name obj;
객체 생성 및 공영체 멤버 접근 예
vi objet_union_acess.c
#include<stdio.h>
union Employee
{
int Id;
char Name[25];
int Age;
long Salary;
};
void main()
{
union Employee E;
printf("\nEnter Employee Id : ");
scanf("%d",&E.Id);
printf("\nEnter Employee Name : ");
scanf("%s",&E.Name);
printf("\nEnter Employee Age : ");
scanf("%d",&E.Age);
printf("\nEnter Employee Salary : ");
scanf("%ld",&E.Salary);
printf("\n\nEmployee Id : %d",E.Id);
printf("\nEmployee Name : %s",E.Name);
printf("\nEmployee Age : %d",E.Age);
printf("\nEmployee Salary : %ld",E.Salary);
}
Output :
Enter Employee Id : 1
Enter Employee Name : Kumar
Enter Employee Age : 29
Enter Employee Salary : 45000
Employee Id : -20536
Employee Name : ?$?$ ?
Employee Age : -20536
Employee Salary : 45000
멤버 손상 값 확인.
변수 사용 예제.
vi variab_union.c
#include<stdio.h>
union Employee
{
int Id;
char Name[25];
int Age;
long Salary;
};
void main()
{
union Employee E;
printf("\nEnter Employee Id : ");
scanf("%d",&E.Id);
printf("Employee Id : %d",E.Id);
printf("\n\nEnter Employee Name : ");
scanf("%s",&E.Name);
printf("Employee Name : %s",E.Name);
printf("\n\nEnter Employee Age : ");
scanf("%d",&E.Age);
printf("Employee Age : %d",E.Age);
printf("\n\nEnter Employee Salary : ");
scanf("%ld",&E.Salary);
printf("Employee Salary : %ld",E.Salary);
}
Output :
Enter Employee Id : 1
Employee Id : 1
Enter Employee Name : Kumar
Employee Name : Kumar
Enter Employee Age : 29
Employee Age : 29
Enter Employee Salary : 45000
Employee Salary : 45000
각 멤버가 한 번에 사용되기 때문에 모든 멤버에 대한 내용이 출력된다.
공용체 크기 비교
vi union_cmp.c
#include<stdio.h>
struct Employee1
{
int Id;
char Name[25];
long Salary;
};
union Employee2
{
int Id;
char Name[25];
long Salary;
};
void main()
{
printf("\nSize of Employee1 is : %d",sizeof(Employee1));
printf("\nSize of Employee2 is : %d",sizeof(Employee2));
}
Output :
Size of Employee1 is : 31
자료형 모음 하나에 대한, 각기 다른 해석이 가능한 자료형
융통성이 좋음, 즉 생각을 많이 해야함.
구조는 모든 멤버에 대해 서로 다른 메모리 위치를 할당 함.
union은 모든 메모에 대해 고통 메모리 위치 할당.
union union-name
{
datatype var1;
datatype var2;
- - - - - - - - - -
- - - - - - - - - -
datatype varN;
};
멤버 저근 객체 생성 구문
union union-name obj;
객체 생성 및 공영체 멤버 접근 예
vi objet_union_acess.c
#include<stdio.h>
union Employee
{
int Id;
char Name[25];
int Age;
long Salary;
};
void main()
{
union Employee E;
printf("\nEnter Employee Id : ");
scanf("%d",&E.Id);
printf("\nEnter Employee Name : ");
scanf("%s",&E.Name);
printf("\nEnter Employee Age : ");
scanf("%d",&E.Age);
printf("\nEnter Employee Salary : ");
scanf("%ld",&E.Salary);
printf("\n\nEmployee Id : %d",E.Id);
printf("\nEmployee Name : %s",E.Name);
printf("\nEmployee Age : %d",E.Age);
printf("\nEmployee Salary : %ld",E.Salary);
}
Output :
Enter Employee Id : 1
Enter Employee Name : Kumar
Enter Employee Age : 29
Enter Employee Salary : 45000
Employee Id : -20536
Employee Name : ?$?$ ?
Employee Age : -20536
Employee Salary : 45000
멤버 손상 값 확인.
변수 사용 예제.
vi variab_union.c
#include<stdio.h>
union Employee
{
int Id;
char Name[25];
int Age;
long Salary;
};
void main()
{
union Employee E;
printf("\nEnter Employee Id : ");
scanf("%d",&E.Id);
printf("Employee Id : %d",E.Id);
printf("\n\nEnter Employee Name : ");
scanf("%s",&E.Name);
printf("Employee Name : %s",E.Name);
printf("\n\nEnter Employee Age : ");
scanf("%d",&E.Age);
printf("Employee Age : %d",E.Age);
printf("\n\nEnter Employee Salary : ");
scanf("%ld",&E.Salary);
printf("Employee Salary : %ld",E.Salary);
}
Output :
Enter Employee Id : 1
Employee Id : 1
Enter Employee Name : Kumar
Employee Name : Kumar
Enter Employee Age : 29
Employee Age : 29
Enter Employee Salary : 45000
Employee Salary : 45000
각 멤버가 한 번에 사용되기 때문에 모든 멤버에 대한 내용이 출력된다.
공용체 크기 비교
vi union_cmp.c
#include<stdio.h>
struct Employee1
{
int Id;
char Name[25];
long Salary;
};
union Employee2
{
int Id;
char Name[25];
long Salary;
};
void main()
{
printf("\nSize of Employee1 is : %d",sizeof(Employee1));
printf("\nSize of Employee2 is : %d",sizeof(Employee2));
}
Output :
Size of Employee1 is : 31
비트필드 bit field
비트필드
1byte (8bit) 구주체
메모리 절략 주로 임베디드 사용. 스위치 ON OFF
struct struct-name
{
datatype var1 : size of bits;
datatype var2 : size of bits;
- - - - - - - - - -
- - - - - - - - - -
datatype varN : size of bits;
};
#include<stdio.h>
struct info1
{
int num;
};
struct info2
{
int num : 1;
};
void main()
{
struct info1 f1;
struct info2 f2;
printf("\n\n\tSize of info1 is : %d",sizeof(info1));
printf("\n\n\tSize of info2 is : %d",sizeof(info2));
}
Output :
Size of info1 is : 2
Size of info2 is : 1
1byte (8bit) 구주체
메모리 절략 주로 임베디드 사용. 스위치 ON OFF
struct struct-name
{
datatype var1 : size of bits;
datatype var2 : size of bits;
- - - - - - - - - -
- - - - - - - - - -
datatype varN : size of bits;
};
#include<stdio.h>
struct info1
{
int num;
};
struct info2
{
int num : 1;
};
void main()
{
struct info1 f1;
struct info2 f2;
printf("\n\n\tSize of info1 is : %d",sizeof(info1));
printf("\n\n\tSize of info2 is : %d",sizeof(info2));
}
Output :
Size of info1 is : 2
Size of info2 is : 1
구조체 VS 배열
구조체 : 동일하지 않은 자료형 모음
배열 : 동일한 자료형의 모음
struct userdata ---> record
{
member1 ---> field
member2
}
변수 일 때 접근
변수.멤버이름
포인터 일 때 접근
*주소 -> 멤버이름
자기 참조 구조체
-링크드 리스트 자료구조(추가, 삭제, 검색)
Node ->node -> node : 연결 리스트
typedef struct _A{
char szName[16];
char szPhone[16];
struct _A *pNext;
}A;
배열 : 동일한 자료형의 모음
struct userdata ---> record
{
member1 ---> field
member2
}
변수 일 때 접근
변수.멤버이름
포인터 일 때 접근
*주소 -> 멤버이름
자기 참조 구조체
-링크드 리스트 자료구조(추가, 삭제, 검색)
Node ->node -> node : 연결 리스트
typedef struct _A{
char szName[16];
char szPhone[16];
struct _A *pNext;
}A;
함수 포인터
1. 재귀 호출
A(){
A();
}
재귀호출 == 반복문 + Stack
caller == callee
A()함수 ()호츨자의 피연산자 A는 함수 이름이다. 함수 이름은 메모리 주소이다. 함수 이름의 주소 체계는 프로시저 형식의 주소가 부여된다.
동일한 함수가 동일한 이름의 함수를 호출 하면은 스텍 크기가 증가한다.
스텍또한 자료 구조이므로, 그 구조에 따른 형틀을 가지고 있으며, 그 용어를 stack frame라 한다.
stack frame은 논리 구조의 자료 구조이다.
스택의 논리 구조를 구현 할 필요는 없다. 누군가 이미 그 구조를 만들어 놓아기 때문이다.
스택 프레임 자료에다가 반복문을 추가해 사용하게 된다면, 그게 바로 재귀 호출이 된다.
스택 자료 구조의 특징
스택이 증가하면 메모리 주소는 감소한다.
순간 메모리 사용량 증가.
연산량이 많아 느림
파일시스템(폴더)나 트리구 형태의 자료에서 사용된다
재귀함수 분석
디버그 모드 컴파일
브레이크 포인트 설정
한줄단위 추적 ---> 메모리 맵에 흐름 확인
STDOUT 값 전달.
function factorial {
(( $1 )) &&
echo $(( $1 * $( factorial $(( $1 - 1 )) ) )) ||
echo 1
}
factorial 5
function factorial {
(( $1 )) || return 1
factorial $(( $1 - 1 ))
return $(( $1 * $? ))
}
factorial 5
echo $?
vi test.sh
#!/bin/bash
factorial()
{
if [[ $1 -le 1 ]]
then
echo 1
else
last=$(factorial $[$1-1])
echo $(($1 * last))
fi
}
factorial 5
cp(recursive)은 디렉토리의 내용을 복사하고, 하위 디렉토리가 있는 경우(재귀 적으로)복사한다.
2. 함수 포인터
callback 함수 사용.
함수의 이름은 곳 주소이다.
케릭터 포인터를 인수로 받아 int 형으로 반환하는 함수 포인터
int testfun(char*);
int *(pTest(char*); // 캐릭터 포인터를 인수 값으로 받는다.
pTest = testfun();
동작구조
sort 정렬
텍스트로된 파일의 행단위 정렬을 할때 사용하는 명령어이다.
복잡한 워드문서등의 편집이 아닌 간단한 텍스트문서를 대상으로 정렬 작업을 할때 주로 사용되는 명령어이다.
이 명령어는 주로 특정 DB나 프로그램, 또는 쉘프로그램등의 입력값으로 사용되는 데이터를 직접 정렬하려고 할때 사용된다.
sort [-옵션] [-o 저장될 파일명] 정렬할 파일명 [병합할 파일명]
기본 정렬 : 맨 앞 글자 알파벳 오름 차순 정렬
ls -al | sort
-r 옵션
-r은 내림차순 정렬이다.
ls -al | sort -r
-k숫자 옵션
-k는 줄의 맨 앞 문자가 아닌 공백을 기준으로 n번째 문자를 기준으로 정렬하는 것이다.
ls -al | sort -k9
-g 옵션
-g은 알파벳 순이 아닌 숫자 크기 순으로 정렬하는 것이다. -k와 결합하여 적용해서 크기순으로 정렬
ls -al | sort -k5 -g
-u 옵션
비교하는 값이 동일할 경우 제거하는 옵션
ls -al | sort -k5 -g -u
크기 역순으로 정렬하기
이제 위에서 다룬 모든 옵션을 사용하여 크기 역순으로 중복을 제거하면서 파일을 정렬
ls -al | sort -k5 -g -u -r
Sort는 명령어 결과 혹은 문서 내용을 정렬
cat data.txt
5
3
2
7
sort data.txt
2
3
5
7
cat data2.txt
a 4
c 5
f 1
z 2
두번 째 열 기준 정렬
sort + 1 data2.txt
f 1
z 2
a 4
c 5
sort/uniq 를 같이 사용해 정렬한 후 충복된 내용의 행이 연속적으로 있으면 하나만 나기고 삭제.
A(){
A();
}
재귀호출 == 반복문 + Stack
caller == callee
A()함수 ()호츨자의 피연산자 A는 함수 이름이다. 함수 이름은 메모리 주소이다. 함수 이름의 주소 체계는 프로시저 형식의 주소가 부여된다.
동일한 함수가 동일한 이름의 함수를 호출 하면은 스텍 크기가 증가한다.
스텍또한 자료 구조이므로, 그 구조에 따른 형틀을 가지고 있으며, 그 용어를 stack frame라 한다.
stack frame은 논리 구조의 자료 구조이다.
스택의 논리 구조를 구현 할 필요는 없다. 누군가 이미 그 구조를 만들어 놓아기 때문이다.
스택 프레임 자료에다가 반복문을 추가해 사용하게 된다면, 그게 바로 재귀 호출이 된다.
스택 자료 구조의 특징
스택이 증가하면 메모리 주소는 감소한다.
순간 메모리 사용량 증가.
연산량이 많아 느림
파일시스템(폴더)나 트리구 형태의 자료에서 사용된다
재귀함수 분석
디버그 모드 컴파일
브레이크 포인트 설정
한줄단위 추적 ---> 메모리 맵에 흐름 확인
STDOUT 값 전달.
function factorial {
(( $1 )) &&
echo $(( $1 * $( factorial $(( $1 - 1 )) ) )) ||
echo 1
}
factorial 5
function factorial {
(( $1 )) || return 1
factorial $(( $1 - 1 ))
return $(( $1 * $? ))
}
factorial 5
echo $?
vi test.sh
#!/bin/bash
factorial()
{
if [[ $1 -le 1 ]]
then
echo 1
else
last=$(factorial $[$1-1])
echo $(($1 * last))
fi
}
factorial 5
cp(recursive)은 디렉토리의 내용을 복사하고, 하위 디렉토리가 있는 경우(재귀 적으로)복사한다.
2. 함수 포인터
callback 함수 사용.
함수의 이름은 곳 주소이다.
케릭터 포인터를 인수로 받아 int 형으로 반환하는 함수 포인터
int testfun(char*);
int *(pTest(char*); // 캐릭터 포인터를 인수 값으로 받는다.
pTest = testfun();
동작구조
sort 정렬
텍스트로된 파일의 행단위 정렬을 할때 사용하는 명령어이다.
복잡한 워드문서등의 편집이 아닌 간단한 텍스트문서를 대상으로 정렬 작업을 할때 주로 사용되는 명령어이다.
이 명령어는 주로 특정 DB나 프로그램, 또는 쉘프로그램등의 입력값으로 사용되는 데이터를 직접 정렬하려고 할때 사용된다.
sort [-옵션] [-o 저장될 파일명] 정렬할 파일명 [병합할 파일명]
기본 정렬 : 맨 앞 글자 알파벳 오름 차순 정렬
ls -al | sort
-r 옵션
-r은 내림차순 정렬이다.
ls -al | sort -r
-k숫자 옵션
-k는 줄의 맨 앞 문자가 아닌 공백을 기준으로 n번째 문자를 기준으로 정렬하는 것이다.
ls -al | sort -k9
-g 옵션
-g은 알파벳 순이 아닌 숫자 크기 순으로 정렬하는 것이다. -k와 결합하여 적용해서 크기순으로 정렬
ls -al | sort -k5 -g
-u 옵션
비교하는 값이 동일할 경우 제거하는 옵션
ls -al | sort -k5 -g -u
크기 역순으로 정렬하기
이제 위에서 다룬 모든 옵션을 사용하여 크기 역순으로 중복을 제거하면서 파일을 정렬
ls -al | sort -k5 -g -u -r
Sort는 명령어 결과 혹은 문서 내용을 정렬
cat data.txt
5
3
2
7
sort data.txt
2
3
5
7
cat data2.txt
a 4
c 5
f 1
z 2
두번 째 열 기준 정렬
sort + 1 data2.txt
f 1
z 2
a 4
c 5
sort/uniq 를 같이 사용해 정렬한 후 충복된 내용의 행이 연속적으로 있으면 하나만 나기고 삭제.
wget 하위 디렉토리 다운로드
wget 파일 다운로드
하위 디렉토리 다운로드
wget -m -p -E -k -K -np {URL Address}
하위 디렉토리
wget -r
링크 파일
wget -r -l 1
html에 링크된 파일들을 가져온다.
-r 옵션은 --recursive 이고 -l 은 반복할 레벨을 뜻한다. (즉 링크를 추적할수 있는 방법론 1으므로 한번 링크 추적)
다른 이름 저장
wget -O 새로운이름 http://l-ht.com
-np: 링크된 파일 중 상위 디렉토리는 제외 (no-parent)
-A html.htm : html.htm 형식의 파일만
-L : 상대주소를 이용한 링크
-q : 메세지 출력 금지
-nv: 메세지 요약 출력
-nd : no directoris, 로컬에 다운받을때 디렉토리를 생성하지 않으며 모든 파일을 같은 디렉토리 넣는다.
-t 1: retries, 링크된 주소로 서버를 찾기 못할때 재 전송 할 횟수를 지정한다.
-H : 다른 호스트의 재귀적 탐색을 원할 경우 span-host를 의미한다.
index.html 만 가지고 오기
wget -r -l 0 -L -np -A index.html -nv URL
wget -A mpg,mpeg,avi,asf -r -H -l 2 -nd -t 1 http://usrl.com
ftp로그인 다운로드 방법
wget -f ftp://아이디:votmdnjem@아이피주소및 파일 위치
wget을 이용한 사이트 응답시간 체크
다음과 같은 2가지 사항에 대해서 체크한다면, 웹서비스에 대한 기본적인 품질 체크 가능.
페이지 응답체크
페이지 응답시간
Submit Process
여기에 덧붙여서 Submit Process까지 체크한다면, 더 나은 품질 모니터링 환경을 만들 수 있다.
어떤 웹서비스가 제대로 작동하는지 확인하고 싶을 경우, POST(:12) 혹은 GET(:12)으로 연결된 몇개의 페이지를 연결해서 검사해야할 필요가 있다. 예를 들어서 로그인을 위해서 OpenID(:12)를 사용한다고 가정해보자.
기존의 로그인 방식이라면, 로그인관련 데이터가 로컬에 있으니, 로그인데이터를 관리하는 DB시스템이 제대로 살아있는지만 확인할 수 있으면 된다. 그러나 OpenID와 같은 경우에는 로컬 DB를 이용하는게 아닌, 로그인 서비스를 이용하는 방식이기 때문에 실제 Submit을 해서 다음 페이지로 넘어가는지를 확인해 주어야 한다.
Submit 프로세스를 체크하기 위해서는 HTTP(:12)와 POST(:12), GET(:12)을 이용한 데이터 전달방식 그리고 cookie(:12)에 대해서 알고 있어야 할것이다. 여기에서는 그냥 wget(1)을 이용해서 간단하게 처리하는 방법에 대해서 알아본다.
# wget --load-cookies=cookies.txt --save-cookies=cookies.txt \
--post-data 'uname=myid&pass=mypass&op=login' \
'http://www.domain.com/auth.php' -O /dev/null
아주 간단하다. --post-data 옵션을 이용하면, 해당 페이지에 POST 데이터를 넘길 수 있다. POST 데이터를 받은 웹서버는 인증과정을 거친 후, 그 결과를 Cookie로 클라이언트에 전달하고, 이후의 인증 세션유지는 cookie 값의 교환으로 이루어지게 된다. --save-cookies 옵션을 이용하면, 서버로 부터 넘어온 cookie 값을 파일에 저장할 수가 있다. 이제 --load-cookies 옵션을 이용해서 해당 웹페이지를 호출할 때, 쿠키도 같이 보내면 된다.
위의 명령을 쉘스크립트(:12) 형태로 만들어서 주기적으로 실행하고, 그 결과를 분석하는 걸로, 간단하게 Submit Process에 대한 체크를 할 수 있다. C(:12) 언어가 마음에 든다면, fork(:12) & exec(:12)를 이용한 실행코드를 만들어 낼 수도 있을 것이다. 위의 경우는 요청한 페이지정보를 /dev/null 로 보내고 있는데, 로그인 결과까지를 확인하고 싶다면, 입력받은 페이지를 스트링매칭 시키는 방법으로 분석해야 할 것이다.
응답시간
응답시간 역시 wget을 이용해서 간단하게 해결할 수 있다. 더불어 -p옵션을 사용한다면, 해당 페이지에 링크되어 있는 이미지, 사운드, CSS(:12) 데이터들의 로딩시간까지 함께 체크할 수 있다.
하위 디렉토리 다운로드
wget -m -p -E -k -K -np {URL Address}
하위 디렉토리
wget -r
링크 파일
wget -r -l 1
html에 링크된 파일들을 가져온다.
-r 옵션은 --recursive 이고 -l 은 반복할 레벨을 뜻한다. (즉 링크를 추적할수 있는 방법론 1으므로 한번 링크 추적)
다른 이름 저장
wget -O 새로운이름 http://l-ht.com
-np: 링크된 파일 중 상위 디렉토리는 제외 (no-parent)
-A html.htm : html.htm 형식의 파일만
-L : 상대주소를 이용한 링크
-q : 메세지 출력 금지
-nv: 메세지 요약 출력
-nd : no directoris, 로컬에 다운받을때 디렉토리를 생성하지 않으며 모든 파일을 같은 디렉토리 넣는다.
-t 1: retries, 링크된 주소로 서버를 찾기 못할때 재 전송 할 횟수를 지정한다.
-H : 다른 호스트의 재귀적 탐색을 원할 경우 span-host를 의미한다.
index.html 만 가지고 오기
wget -r -l 0 -L -np -A index.html -nv URL
wget -A mpg,mpeg,avi,asf -r -H -l 2 -nd -t 1 http://usrl.com
ftp로그인 다운로드 방법
wget -f ftp://아이디:votmdnjem@아이피주소및 파일 위치
wget을 이용한 사이트 응답시간 체크
다음과 같은 2가지 사항에 대해서 체크한다면, 웹서비스에 대한 기본적인 품질 체크 가능.
페이지 응답체크
페이지 응답시간
Submit Process
여기에 덧붙여서 Submit Process까지 체크한다면, 더 나은 품질 모니터링 환경을 만들 수 있다.
어떤 웹서비스가 제대로 작동하는지 확인하고 싶을 경우, POST(:12) 혹은 GET(:12)으로 연결된 몇개의 페이지를 연결해서 검사해야할 필요가 있다. 예를 들어서 로그인을 위해서 OpenID(:12)를 사용한다고 가정해보자.
기존의 로그인 방식이라면, 로그인관련 데이터가 로컬에 있으니, 로그인데이터를 관리하는 DB시스템이 제대로 살아있는지만 확인할 수 있으면 된다. 그러나 OpenID와 같은 경우에는 로컬 DB를 이용하는게 아닌, 로그인 서비스를 이용하는 방식이기 때문에 실제 Submit을 해서 다음 페이지로 넘어가는지를 확인해 주어야 한다.
Submit 프로세스를 체크하기 위해서는 HTTP(:12)와 POST(:12), GET(:12)을 이용한 데이터 전달방식 그리고 cookie(:12)에 대해서 알고 있어야 할것이다. 여기에서는 그냥 wget(1)을 이용해서 간단하게 처리하는 방법에 대해서 알아본다.
# wget --load-cookies=cookies.txt --save-cookies=cookies.txt \
--post-data 'uname=myid&pass=mypass&op=login' \
'http://www.domain.com/auth.php' -O /dev/null
아주 간단하다. --post-data 옵션을 이용하면, 해당 페이지에 POST 데이터를 넘길 수 있다. POST 데이터를 받은 웹서버는 인증과정을 거친 후, 그 결과를 Cookie로 클라이언트에 전달하고, 이후의 인증 세션유지는 cookie 값의 교환으로 이루어지게 된다. --save-cookies 옵션을 이용하면, 서버로 부터 넘어온 cookie 값을 파일에 저장할 수가 있다. 이제 --load-cookies 옵션을 이용해서 해당 웹페이지를 호출할 때, 쿠키도 같이 보내면 된다.
위의 명령을 쉘스크립트(:12) 형태로 만들어서 주기적으로 실행하고, 그 결과를 분석하는 걸로, 간단하게 Submit Process에 대한 체크를 할 수 있다. C(:12) 언어가 마음에 든다면, fork(:12) & exec(:12)를 이용한 실행코드를 만들어 낼 수도 있을 것이다. 위의 경우는 요청한 페이지정보를 /dev/null 로 보내고 있는데, 로그인 결과까지를 확인하고 싶다면, 입력받은 페이지를 스트링매칭 시키는 방법으로 분석해야 할 것이다.
응답시간
응답시간 역시 wget을 이용해서 간단하게 해결할 수 있다. 더불어 -p옵션을 사용한다면, 해당 페이지에 링크되어 있는 이미지, 사운드, CSS(:12) 데이터들의 로딩시간까지 함께 체크할 수 있다.
# wget -p http://www.domain.com/index.php > /dev/null
재귀함수 두 숫자 gcd
#include <stdio.h>
int hcf(int n1, int n2);
int main(void){
int n1, n2;
printf("Enter two positive integers: ");
scanf("%d %d", &n1, &n2);
printf("G.C.D of %d and %d is %d.", n1, n2, hcf(n1,n2));
return 0;
}
int hcf(int n1, int n2){
if (n2 != 0)
return hcf(n2, n1%n2);
else
return n1;
}
/*
Enter two positive integers: 365
60
G.C.D of 365 and 60 is 5. */
int hcf(int n1, int n2);
int main(void){
int n1, n2;
printf("Enter two positive integers: ");
scanf("%d %d", &n1, &n2);
printf("G.C.D of %d and %d is %d.", n1, n2, hcf(n1,n2));
return 0;
}
int hcf(int n1, int n2){
if (n2 != 0)
return hcf(n2, n1%n2);
else
return n1;
}
/*
Enter two positive integers: 365
60
G.C.D of 365 and 60 is 5. */
재귀함수 자연수 합
#include <stdio.h>
int sum(int n);
int main(void){
int number, result;
printf("Enter a positive interget: ");
scanf("%d", &number);
result = sum(number);
printf("sum = %d", result);
return 0;
}
int sum(int num){
if (num != 0 )
return num + sum(num-1); // sum() 자기 자신 호출
else
return num;
}
/*
Enter a positive integer:3
sum = 6
*/
int sum(int n);
int main(void){
int number, result;
printf("Enter a positive interget: ");
scanf("%d", &number);
result = sum(number);
printf("sum = %d", result);
return 0;
}
int sum(int num){
if (num != 0 )
return num + sum(num-1); // sum() 자기 자신 호출
else
return num;
}
/*
Enter a positive integer:3
sum = 6
*/
재귀 호출
재귀 호출
A(){
A();
}
재귀호출 == 반복문 + Stack
caller == callee
A()함수 ()호츨자의 피연산자 A는 함수 이름이다. 함수 이름은 메모리 주소이다. 함수 이름의 주소 체계는 프로시저 형식의 주소가 부여된다.
동일한 함수가 동일한 이름의 함수를 호출 하면은 스텍 크기가 증가한다.
스텍또한 자료 구조이므로, 그 구조에 따른 형틀을 가지고 있으며, 그 용어를 stack frame라 한다.
stack frame은 논리 구조의 자료 구조이다.
스택의 논리 구조를 구현 할 필요는 없다. 누군가 이미 그 구조를 만들어 놓아기 때문이다.
스택 프레임 자료에다가 반복문을 추가해 사용하게 된다면, 그게 바로 재귀 호출이 된다.
스택 자료 구조의 특징
스택이 증가하면 메모리 주소는 감소한다.
순간 메모리 사용량 증가.
연산량이 많아 느림
파일시스템(폴더)나 트리구 형태의 자료에서 사용된다
재귀함수 분석
디버그 모드 컴파일
브레이크 포인트 설정
한줄단위 추적 ---> 메모리 맵에 흐름 확인
STDOUT 값 전달.
function factorial {
(( $1 )) &&
echo $(( $1 * $( factorial $(( $1 - 1 )) ) )) ||
echo 1
}
factorial 5
function factorial {
(( $1 )) || return 1
factorial $(( $1 - 1 ))
return $(( $1 * $? ))
}
factorial 5
echo $?
vi test.sh
#!/bin/bash
factorial()
{
if [[ $1 -le 1 ]]
then
echo 1
else
last=$(factorial $[$1-1])
echo $(($1 * last))
fi
}
factorial 5
cp(recursive)은 디렉토리의 내용을 복사하고, 하위 디렉토리가 있는 경우(재귀 적으로)복사한다.
A(){
A();
}
재귀호출 == 반복문 + Stack
caller == callee
A()함수 ()호츨자의 피연산자 A는 함수 이름이다. 함수 이름은 메모리 주소이다. 함수 이름의 주소 체계는 프로시저 형식의 주소가 부여된다.
동일한 함수가 동일한 이름의 함수를 호출 하면은 스텍 크기가 증가한다.
스텍또한 자료 구조이므로, 그 구조에 따른 형틀을 가지고 있으며, 그 용어를 stack frame라 한다.
stack frame은 논리 구조의 자료 구조이다.
스택의 논리 구조를 구현 할 필요는 없다. 누군가 이미 그 구조를 만들어 놓아기 때문이다.
스택 프레임 자료에다가 반복문을 추가해 사용하게 된다면, 그게 바로 재귀 호출이 된다.
스택 자료 구조의 특징
스택이 증가하면 메모리 주소는 감소한다.
순간 메모리 사용량 증가.
연산량이 많아 느림
파일시스템(폴더)나 트리구 형태의 자료에서 사용된다
재귀함수 분석
디버그 모드 컴파일
브레이크 포인트 설정
한줄단위 추적 ---> 메모리 맵에 흐름 확인
STDOUT 값 전달.
function factorial {
(( $1 )) &&
echo $(( $1 * $( factorial $(( $1 - 1 )) ) )) ||
echo 1
}
factorial 5
function factorial {
(( $1 )) || return 1
factorial $(( $1 - 1 ))
return $(( $1 * $? ))
}
factorial 5
echo $?
vi test.sh
#!/bin/bash
factorial()
{
if [[ $1 -le 1 ]]
then
echo 1
else
last=$(factorial $[$1-1])
echo $(($1 * last))
fi
}
factorial 5
cp(recursive)은 디렉토리의 내용을 복사하고, 하위 디렉토리가 있는 경우(재귀 적으로)복사한다.
2019/01/02
flatpak 패키지 관리자 Dreams 설치
패키지 관리 유틸 설치
sudo apt-get install flatpak
sudo apt-get install flatpak
저장소 등록
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
플러그인 설치(ui 환경)
sudo apt install gnome-software-plugin-flatpak
패키지 다운로드 문제 발생 사용자 저장소 등록.
flatpak install --user https://flathub.org/repo/appstream/org.speed_dreams.SpeedDreams.flatpakref
사용자 권한으로 설치
flatpak --user update org.speed_dreams.SpeedDreams
패키지 검색
flatpak remote-ls --app | grep SpeedDreams
사용자 저장소 삭제
flatpak remote-delete flathub
패키지 다운로드 문제 발생 사용자 저장소 등록.
flatpak install --user https://flathub.org/repo/appstream/org.speed_dreams.SpeedDreams.flatpakref
사용자 권한으로 설치
flatpak --user update org.speed_dreams.SpeedDreams
패키지 검색
flatpak remote-ls --app | grep SpeedDreams
사용자 저장소 삭제
flatpak remote-delete flathub
설치
flatpak install flathub org.speed_dreams.SpeedDreams
현재 접근 할 수 없음....
Server returned status 503: Service Unavailable
다시 실행시 다운로드 받은 파일이 줄어 든 걸 볼 수 있음. 다운로드 받을 때 까지 계속 실행. 서버가 불안 한 것으로 보인.
다시 실행시 다운로드 받은 파일이 줄어 든 걸 볼 수 있음. 다운로드 받을 때 까지 계속 실행. 서버가 불안 한 것으로 보인.
실행
flatpak run org.speed_dreams.SpeedDreams
안드로이드 8.1, guest on Ubuntu 17.10 호스트 환경 GDB 에물레이터
안드로이드 8.1, guest on Ubuntu 17.10 호스트 환경
소스코드 다운로드 및 안드로이드 환경 구성
curl https://storage.googleapis.com/git-repo-downloads/repo >repo
chmod a+x repo
vi repo
#!/usr/bin/env python2.7
:wq
정보 추가 선택 사항 임.
git config --global user.email "linuxleejang@gmail.com"
git config --global user.name "JangHo"
하디드스크 용량 100G 정도 여유 공간 확보.
./repo init -b android-8.1.0_r1 --depth 1 -u https://android.googlesource.com/platform/manifest
./repo sync -c -j $(($(nproc) - 2)) --no-tags --no-clone-bundle
설치
. build/envsetup.sh
lunch aosp_x86_64-eng
USE_CCACHE=1 CCACHE_DIR=ccache make -j $(($(nproc) - 2))
에물레이터 실행
emulator -show-kernel
1분에서 2분 정도 기달림.
안드로이드가 다 부팅 된후 터미널 콘솔에다가 엔터키를 입력 하면 쉘 모드로 진입
참고
./repo init -b 태그 지정. master -release는 버전 변경이 항상 있음.
태크 목록 사이트
https://android.googlesource.com/platform/manifest
두 가지 트리
개발 코드 삭제. Google 및 OEM 개발자의 공개된 마스트로 문제가 해결된 버전.
마스터 빌드 오류는 더이상 지원이 없음. 공개된 버전은 문제가 없으므로, 오류 관련은 빌드 사용자가 기존 해결 내용을 참고 해야 함.
repo sync 호환성 보장 없음.
--depth 1 옵션과 sync -c --no-tags --no-clone-bundle 동기화 처리 옵션은 복제를 빠르게 하지만, 복제의 성공률이 문제가 있을 수 있음.
저장소 동기화 시간 문제
https://stackoverflow.com/questions/28379870/aosp-repo-sync-takes-too-long
호스트 환경 옵션
lunch aosp_x86_64-eng 호스트 환경이 X86
lunch aosp_arm-eng 암 버전 구축
안드로이 에물레이터 응답 대기 및 실패.
https://stackoverflow.com/questions/43779596/process-system-isnt-responding-in-android-emulator
메모리 확장 및 해상도 낮춰서 해결
config
ORIGINAL: disk.dataPartition.size=512M
MODIFIED: disk.dataPartition.size=512MB
ORIGINAL: hw.ramSize=1024
MODIFIED: hw.ramSize=1024MB
-show-kernel 옵션은 터미널과 연결해, 부팅 메시지를 확인할 수 있다. 이 메세지로 디버깅 정보를 확인 할 수 있음.
type emulato emulator 별칭 설정
명시 적으로 ROM을 선택하기 위해 몇 가지 인수 전달하는 방법을 알고 있어야 함.
emulator -help
emulator -help-build-images
emulator -help-disk-images
Android 에뮬레이터에서 맞춤 ROM 실행
https://stackoverflow.com/questions/25985384/run-custom-rom-on-android-emulator
GDB 디버깅 방법
먼저 GDB 명령을 실행 ./rungdb 하여 전체 명령 활성화 : 명령을 실행 하기 전에 명령을 표준 출력으로 출력합니다
findAOSP 빌드 디렉토리 내부에서 명령에 필요한 파일확인.
emulator명령 QEMU에 매개 변수를 전달하는 플래그가 있음.
소스코드 다운로드 및 안드로이드 환경 구성
curl https://storage.googleapis.com/git-repo-downloads/repo >repo
chmod a+x repo
vi repo
#!/usr/bin/env python2.7
:wq
정보 추가 선택 사항 임.
git config --global user.email "linuxleejang@gmail.com"
git config --global user.name "JangHo"
하디드스크 용량 100G 정도 여유 공간 확보.
./repo init -b android-8.1.0_r1 --depth 1 -u https://android.googlesource.com/platform/manifest
./repo sync -c -j $(($(nproc) - 2)) --no-tags --no-clone-bundle
설치
. build/envsetup.sh
lunch aosp_x86_64-eng
USE_CCACHE=1 CCACHE_DIR=ccache make -j $(($(nproc) - 2))
에물레이터 실행
emulator -show-kernel
1분에서 2분 정도 기달림.
안드로이드가 다 부팅 된후 터미널 콘솔에다가 엔터키를 입력 하면 쉘 모드로 진입
참고
./repo init -b 태그 지정. master -release는 버전 변경이 항상 있음.
태크 목록 사이트
https://android.googlesource.com/platform/manifest
두 가지 트리
개발 코드 삭제. Google 및 OEM 개발자의 공개된 마스트로 문제가 해결된 버전.
마스터 빌드 오류는 더이상 지원이 없음. 공개된 버전은 문제가 없으므로, 오류 관련은 빌드 사용자가 기존 해결 내용을 참고 해야 함.
repo sync 호환성 보장 없음.
--depth 1 옵션과 sync -c --no-tags --no-clone-bundle 동기화 처리 옵션은 복제를 빠르게 하지만, 복제의 성공률이 문제가 있을 수 있음.
저장소 동기화 시간 문제
https://stackoverflow.com/questions/28379870/aosp-repo-sync-takes-too-long
호스트 환경 옵션
lunch aosp_x86_64-eng 호스트 환경이 X86
lunch aosp_arm-eng 암 버전 구축
안드로이 에물레이터 응답 대기 및 실패.
https://stackoverflow.com/questions/43779596/process-system-isnt-responding-in-android-emulator
메모리 확장 및 해상도 낮춰서 해결
config
ORIGINAL: disk.dataPartition.size=512M
MODIFIED: disk.dataPartition.size=512MB
ORIGINAL: hw.ramSize=1024
MODIFIED: hw.ramSize=1024MB
-show-kernel 옵션은 터미널과 연결해, 부팅 메시지를 확인할 수 있다. 이 메세지로 디버깅 정보를 확인 할 수 있음.
type emulato emulator 별칭 설정
명시 적으로 ROM을 선택하기 위해 몇 가지 인수 전달하는 방법을 알고 있어야 함.
emulator -help
emulator -help-build-images
emulator -help-disk-images
Android 에뮬레이터에서 맞춤 ROM 실행
https://stackoverflow.com/questions/25985384/run-custom-rom-on-android-emulator
GDB 디버깅 방법
먼저 GDB 명령을 실행 ./rungdb 하여 전체 명령 활성화 : 명령을 실행 하기 전에 명령을 표준 출력으로 출력합니다
findAOSP 빌드 디렉토리 내부에서 명령에 필요한 파일확인.
emulator명령 QEMU에 매개 변수를 전달하는 플래그가 있음.
linux-kernel-module-cheat 컴파일
apt update
소스 다운로드
git clone https://github.com/cirosantilli/linux-kernel-module-cheat
cd linux-kernel-module-cheat/
./configure -t
sudo apt-get install gcc-6 g++-6
우분투 툴체인 저정소 추가
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
apt update
apt-get install gcc-6 g++-6
./configure
vi ./build
#!/usr/bin/env bash ---> 버전 변경
#!/bin/bash -x
./build
서브 모듈 다운로드
git submodule update --depth 1 --jobs 4 --init
로그 확인
git log --oneline
소스 다운로드
git clone https://github.com/cirosantilli/linux-kernel-module-cheat
cd linux-kernel-module-cheat/
./configure -t
sudo apt-get install gcc-6 g++-6
우분투 툴체인 저정소 추가
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
apt update
apt-get install gcc-6 g++-6
./configure
vi ./build
#!/usr/bin/env bash ---> 버전 변경
#!/bin/bash -x
./build
서브 모듈 다운로드
git submodule update --depth 1 --jobs 4 --init
로그 확인
git log --oneline
커널 개발을위한 qemu 간편 설정
루트 파일 시스템 생성
IMG=test_stretch.img
DIR=stretch
qemu-img create $IMG 1g
sudo mkfs.ext4 $IMG
mkdir -p $DIR
sudo mount -o loop $IMG $DIR
sudo debootstrap --arch amd64 stretch $DIR
sudo umount $DIR
rmdir $DIR
현재 커널 테스트
$ qemu-system-x86_64 -kernel /boot/vmlinuz-`uname -r` \
-hda qemu-image.img -append "console=ttyS0 root=/dev/sda"
커널 컴파일 테스트
$ git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux
$ make x86_64_defconfig
$ make kvmconfig
$ make -j 4
$ qemu-system-x86_64 -kernel linux/arch/x86/boot/bzImage \
-hda qemu-image.img -append "console=ttyS0 root=/dev/sda"
추가 옵션:
--enable-kvm(KVM으로 속도 향상
--nographic(GUI 생략)
참고 : https://nautiluslee.blogspot.com/search?q=%EC%BB%A4%EB%84%90+%EA%B0%9C%EB%B0%9C+qemu+kvm+config+%EC%84%A4%EC%A0%95
IMG=test_stretch.img
DIR=stretch
qemu-img create $IMG 1g
sudo mkfs.ext4 $IMG
mkdir -p $DIR
sudo mount -o loop $IMG $DIR
sudo debootstrap --arch amd64 stretch $DIR
sudo umount $DIR
rmdir $DIR
현재 커널 테스트
$ qemu-system-x86_64 -kernel /boot/vmlinuz-`uname -r` \
-hda qemu-image.img -append "console=ttyS0 root=/dev/sda"
커널 컴파일 테스트
$ git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux
$ make x86_64_defconfig
$ make kvmconfig
$ make -j 4
$ qemu-system-x86_64 -kernel linux/arch/x86/boot/bzImage \
-hda qemu-image.img -append "console=ttyS0 root=/dev/sda"
추가 옵션:
--enable-kvm(KVM으로 속도 향상
--nographic(GUI 생략)
참고 : https://nautiluslee.blogspot.com/search?q=%EC%BB%A4%EB%84%90+%EA%B0%9C%EB%B0%9C+qemu+kvm+config+%EC%84%A4%EC%A0%95
virtme QEMU 커널 개발 도구
virtme : 커널 개발의 필수 도구
프로젝트 사이트 : https://github.com/amluto/virtme/
사용방법 : https://github.com/amluto/virtme/blob/master/README.md
리눅스 커널은 QEMU를 통해 테스트 하는게 일반적이다. kernel/core 코드, 가상 드라이버 병합되므로서, 응용프로그램을 사용해 테스트하는데 유용하다.
"Virtme은 가상화 Linux 커널을 실행하는 간단한 도구이다. 전체 루트파일 시스템 이미지 대신 단순한 rootfs를 사용. Virtme의 특징은 작고 사용하기 쉬우며 커널 변경 사항을 간단하게 테스트 할 수 있다."
virtme 설치하기
git clone https://github.com/ezequielgarcia/virtme.git
cd virtme
sudo ./setup.py install
메세지 확인
Installed /usr/local/lib/python3.6/dist-packages/virtme-0.0.3-py3.6.egg
커널 소스 다운로드
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
virtme 설정
커널 설정 생성
cd linux
virtme-configkernel --defconfig
#
# configuration written to .config
#
Configured. Build with 'make ARCH=x86 -j4'
필요한 드라이버 사용
vim2m 드라이버 활성화는 video4linux memory2memory 가상 드라이버임.
make menuconfig 설정
vi .config
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2=y
CONFIG_V4L2_MEM2MEM_DEV=y
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIM2M=y
커널 빌드
make -j4 또는 make ARCH=x86 -j4
virtme 실행
sudo virtme-run --kimg arch/x86_64/boot/bzImage
또는
sudo virtme-run --kdir .
부팅시 스크립트 실행
-script-dir 옵션은 부팅시 스크립트를 실행할 위치를 지정한다.
sudo virtme-run --kdir . --script-dir test-dir/
-script-dir 매개 변수 사용해 vim2m 드라이버를 테스트 할 수 있는 스크립트 작성
vi v4l2-compliance_test.sh
#!/bin/sh
v4l2-compliance -d /dev/video0
모듈 디렉토리 지정하기
-mdir 옵션을 사용해 virtme 모듈을 추가 할 수 있다.
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=m
CONFIG_VIDEO_DEV=m
CONFIG_VIDEO_V4L2=m
CONFIG_V4L2_MEM2MEM_DEV=m
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIM2M=m
./tmp 디렉토리 설치 지정
make INSTALL_MOD_PATH=./tmp modules_install
INSTALL crypto/crypto_engine.ko
INSTALL drivers/crypto/virtio/virtio_crypto.ko
INSTALL drivers/media/common/videobuf2/videobuf2-common.ko
INSTALL drivers/media/common/videobuf2/videobuf2-memops.ko
INSTALL drivers/media/common/videobuf2/videobuf2-v4l2.ko
INSTALL drivers/media/common/videobuf2/videobuf2-vmalloc.ko
[..]
모듈 실행
sudo virtme-run --kimg arch/x86_64/boot/bzImage --mdir tmp/lib/modules/4.19.0-rc3
Decompressing Linux... Parsing ELF... Performing relocations... done.
Booting the kernel.
[..]
root@(none):/# modprobe vim2m
[ 66.071041] videodev: Linux video capture interface: v2.00
[ 66.083405] vim2m vim2m.0: Device registered as /dev/video0
프로젝트 사이트 : https://github.com/amluto/virtme/
사용방법 : https://github.com/amluto/virtme/blob/master/README.md
리눅스 커널은 QEMU를 통해 테스트 하는게 일반적이다. kernel/core 코드, 가상 드라이버 병합되므로서, 응용프로그램을 사용해 테스트하는데 유용하다.
"Virtme은 가상화 Linux 커널을 실행하는 간단한 도구이다. 전체 루트파일 시스템 이미지 대신 단순한 rootfs를 사용. Virtme의 특징은 작고 사용하기 쉬우며 커널 변경 사항을 간단하게 테스트 할 수 있다."
virtme 설치하기
git clone https://github.com/ezequielgarcia/virtme.git
cd virtme
sudo ./setup.py install
메세지 확인
Installed /usr/local/lib/python3.6/dist-packages/virtme-0.0.3-py3.6.egg
커널 소스 다운로드
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
virtme 설정
커널 설정 생성
cd linux
virtme-configkernel --defconfig
#
# configuration written to .config
#
Configured. Build with 'make ARCH=x86 -j4'
필요한 드라이버 사용
vim2m 드라이버 활성화는 video4linux memory2memory 가상 드라이버임.
make menuconfig 설정
vi .config
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2=y
CONFIG_V4L2_MEM2MEM_DEV=y
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIM2M=y
커널 빌드
make -j4 또는 make ARCH=x86 -j4
virtme 실행
sudo virtme-run --kimg arch/x86_64/boot/bzImage
또는
sudo virtme-run --kdir .
부팅시 스크립트 실행
-script-dir 옵션은 부팅시 스크립트를 실행할 위치를 지정한다.
sudo virtme-run --kdir . --script-dir test-dir/
-script-dir 매개 변수 사용해 vim2m 드라이버를 테스트 할 수 있는 스크립트 작성
vi v4l2-compliance_test.sh
#!/bin/sh
v4l2-compliance -d /dev/video0
모듈 디렉토리 지정하기
-mdir 옵션을 사용해 virtme 모듈을 추가 할 수 있다.
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=m
CONFIG_VIDEO_DEV=m
CONFIG_VIDEO_V4L2=m
CONFIG_V4L2_MEM2MEM_DEV=m
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIM2M=m
./tmp 디렉토리 설치 지정
make INSTALL_MOD_PATH=./tmp modules_install
INSTALL crypto/crypto_engine.ko
INSTALL drivers/crypto/virtio/virtio_crypto.ko
INSTALL drivers/media/common/videobuf2/videobuf2-common.ko
INSTALL drivers/media/common/videobuf2/videobuf2-memops.ko
INSTALL drivers/media/common/videobuf2/videobuf2-v4l2.ko
INSTALL drivers/media/common/videobuf2/videobuf2-vmalloc.ko
[..]
모듈 실행
sudo virtme-run --kimg arch/x86_64/boot/bzImage --mdir tmp/lib/modules/4.19.0-rc3
Decompressing Linux... Parsing ELF... Performing relocations... done.
Booting the kernel.
[..]
root@(none):/# modprobe vim2m
[ 66.071041] videodev: Linux video capture interface: v2.00
[ 66.083405] vim2m vim2m.0: Device registered as /dev/video0
피드 구독하기:
글 (Atom)