ubuntu 추가 하드디스크 마운트 방법

|

ubuntu 추가 하드디스크 마운트 방법

  • 우분투가 설치된 하드디스크 외 추가 하드디스크 마운트 하는 방법에 대해 설명한다.

1. 하드디스크 설치

  • 사용하는 PC에 하드디스크를 설치한다.
  • PC를 킨 후 sudo fdisk -l로 잘 설치 되었나 확인
    • 새로 설치한 하드가 sda, sdb, sdc, … 어떤것인지 확인해 둠
    • 본 글에선 sdc로 설명하며, 현재 넘버링에 따라 해당 글자만 바꾸면 됨

2. 하드디스크 용량이 2TB 이상인 경우

  • sudo parted /dev/sdc 입력
  • mklabel 입력 후 gpt
    • 내부 데이터가 모두 사라진다는 메세지가 출력 됨
    • yes 입력
  • unit GB 입력하여 단뒤 변환
  • print 입력하여 용량 확인
  • mkpart primary 0GB 3001GB 입력(우측엔 본인 용량 입력하면 됨)
  • q 입력하여 커맨드로 돌아옴

3. 하드디스크 용량이 2TB 미만인 경우

  • sudo fdisk /dev/sdc 입력
    • 커맨드 입력 순서는 다음과 같음
views
image from https://psychoria.tistory.com/521

4. 파티션 포맷

  • mkfs.ext4 /dev/sdc1
    • 중간에 정보 입력하는 부분은 그냥 엔터 쳐서 무시하고 넘어가도 됨

5. UUID 확인

  • sudo blkid 입력하여 UUID 확인 후 복사해두기

6. 마운트

  • sudo mkdir /hdd_ext/hdd3000 로 외부 하드디스크 마운트 할 디렉터리 생성
  • sudo vim /etc/fstab로 마운트 정보 추가 및 부팅 시 자동 마운트 설정
    • UUID=583eb4bb-6f91-4634-b6f3-088157ae2010 /hdd_ext/hdd3000 ext4 defaults 0 0 맨 아랫줄에 입력
    • 입력 후 :wq로 저장 후 빠져나오기
  • sudo mount -a로 마운트
  • df -h로 마운트 확인
    • 마운트가 잘 되었으면 마운팅 된 하드디스크 정보가 보임
  • 일종의 바로가기 개념
  • sudo ln -s /hdd_ext /home/han/hdd_ext로 /hdd_ext를 홈 디렉터리에 바로가기 만들어줌
  • cd ~/hdd_ext로 이동
  • sudo chmod 777 hdd3000으로 읽기 쓰기 권한 줌
  • 링크 만들어진 폴더에 touch test.txt, sudo rm test.txt로 파일 생성이 문제없이 되는가 확인하기

  • [참고 글]

https://psychoria.tistory.com/521

https://wikidocs.net/16272

CH2. 재귀(Recursion)

|

CH2. 재귀(Recursion)

2-1 함수의 재귀적 호출의 이해

  • C언어에서의 재귀 시점이 아닌 자료구조의 시점에서 학습하는 재귀의 적용

재귀합수의 기본적인 이해

  • 탈출 조건이 성립하여야만 함수에서 탈출 할 수 없음
  • 탈출 조건이 성립하지 않는 구조가 될 경우 무한 loop에 빠지게 됨

재귀함수 디자인 사례

  • n의 팩토리얼(n!)을 구하는 함수를 작성하면 다음과 같이 됨
int Factorial(int n)
{
  if (n==0)
    return 0;
  else
    return n * Factorial(n-1);
}

2-2 재귀의 활용

  • 재귀를 효율적으로 활용하기 위한 사고의 전환을 위한 소단원

피보나치 수열: Fibonacci Sequence

  • 피보나치 수열은 앞의 수 두개를 더하여 다음 수를 만들어가는 수열임
    • 처음 두 수는 0, 1로 주어짐
    • 0, 1, 1, 2, 3, 5, 8, 13, …
  • 위의 특징을 활용하여 피보나치 수열 함수를 작성하면 아래와 같이 됨
int Fibo(int n)
{
  if (n==1)
    return 0;
  else if (n==2)
    return 1;
  else
    return Fibo(n-1) + Fibo(n-2);
}
  • 재귀적으로 정의된 함수의 호출 순서를 완벽히 나열하려고 할 필요는 없음
    • 더 복잡해질 뿐..

이진 탐색 알고리즘의 재귀적 구현

  • Chapter 1에서 다룬 이진 탐색 알고리즘을 재귀함수 기반으로 재구현
    • 알고리즘의 논리 자체가 수의 비교라는 반복적 흐름을 갖고있으므로 가능
  • 반복 패턴은 아래와 같이 정의됨
    • 탐색 범위의 중앙에 목표 값이 저장되었는지 확인
    • 저장되지 않았다면 탐색 범위를 반으로 줄여서 다시 탐색 시작
    • 탐색 범위의 시작위치를 의미하는 first가 탐색 범위의 끝을 의미하는 last보다 커지는 경우 탐색 종료
  • 위의 내용을 기반으로 이진 탐색 알고리즘을 재귀적으로 구현하면 다음과 같다
int BSearchRecur(int ar[], int first, int last, int target)
{
  if(first > last)
    return -1
  mid = (first + last) / 2;
  if(ar[mid] == target)
    return mid;
  else if(target < mid)
    return BSearchRecur(ar, first, mid-1, target);
  else if(target > mid)
    return BSearchRecur(ar, mid+1, last, target);
}
  • 하지만 재귀함수의 성능은 일반적으로 구현하는 반복문의 경우보다 떨어짐(더 느리고 복잡함)

하노이 타워: The Tower of Hanoi

  • 재귀함수의 힘을 보여주는 대표적인 예로 꼽힘

하노이 타워 문제의 이해

  • 3개 원반의 경우
    • 세 개의 크기가 다른 원반이 있으며, 작은 원반, 중간 원반, 큰 원반이 존재
    • 원반은 반드시 상대적으로 큰 원반이 아래, 작은 원반이 위에 존재해야 함
    • 원반은 한 번에 하나씩 옮길 수 있음
    • 총 세 개의 기둥 A, B, C가 존재
    • A에 순서대로 꽂혀있는 원반을 모두 C로 옮기는 경우
      • 총 7번만의 과정으로 쉽게 원반을 옮길 수 있음
  • 원반이 많아질 경우에도 동일하게 처리하면 됨

하노이 타워의 반복패턴 연구

  • 4개의 원반인 경우
    • 네 개의 크기가 다른 원반이 있으며, 1, 2, 3, 4 순서대로 점점 커짐
    • A 기둥의 원반을 B, C 기둥을 이용해 C 기둥으로 모두 옮기는 문제
    • B 기둥에 1, 2, 3을 옮긴 후, C 기둥으로 4를 옮기고 나머지는 3개의 원반인 경우와 동일하게 진행
    • B 기둥에 1, 2, 3을 옮기는 과정도 3개 원반인 경우와 동일
  • 막대 A에 꽂혀있는 원반 n개를 막대 C로 옮기는 과정
    • 1단계: 작은 원반 1 ~ n-1 을(n-1개) A에서 B로 이동
    • 2단계: 큰 원반 n 을 A에서 C로 이동
    • 3단계: 작은 원반 1 ~ n-1 을(n-1개) B에서 C로 이동
  • 함수의 구성은 num 개의 원반을 by를 거쳐 from에서 to로 이동
    • void HanoiTowerMove(int num, char from, char by, char to)
    • 하지만 연산의 구성에서 n-1 의 원반이 필요하므로 n = 1 일 때의 예외 처리가 필요(탈출조건)
//frmo에 꽂혀있는 num개의 원반을 by를 거쳐서 to로 이동
void HanoiTowerMove(int num, char from, char by, char to)
{
  if(num == 1) // 이동할 원반의 개수가 1개인 경우
    printf("원반1을 %c에서 %c로 이동 \n", from, to);
  else // 이동할 원반의 개수가 2개 이상일 경우
  {
    HanoiTowerMove(num-1, from, to, by); // 작은 원반 n-1개를 A에서 C를 거쳐 B로 이동
  }
}
  • 2단계 큰 원반 n을 A에서 C로 이동 와 3단계 작은 원반 n-1개를 B에서 C로 이동 을 추가하면 아래와 같다.
void HanoiTowerMove(int num, char from, char by, char to)
{
  if(num == 1)
    printf("원반1을 %c에서 %c로 이동 \n", from, to);
  else
  {
    HanoiTowerMove(num-1, from, to, by); // 작은 원반 n-1개를 A에서 C를 거쳐 B로 이동
    printf("원반%d을(를) %c에서 %c로 이동 \n", num, from, to); // 큰 원반(n)을 A에서 C로 이동
    HanoiTowerMove(num-1, by, from, to); // 작은 원반 n-1개를 B에서 C로 이동
  }
}
  • 이를 기반으로 코드를 완성시키면 아래와 같음
#pragma warning(disable:4996)
#include<stdio.h>

void HanoiTowerMove(int num, char from, char by, char to)
{
	if (num == 1)
		printf("원반1을 %c에서 %c로 이동 \n", from, to);
	else
	{
		HanoiTowerMove(num - 1, from, to, by);
		printf("원반%d을(를) %c에서 %c로 이동 \n", num, from, to);
		HanoiTowerMove(num - 1, by, from, to);
	}
}
int main(void)
{
	HanoiTowerMove(5, 'A', 'B', 'C');
	getchar();
	return 0;
}
  • 재귀함수를 이용하여 복잡한 알고리즘을 간단하게 해결

CH1. 자료구조와 알고리즘의 이해

|

CH1. 자료구조와 알고리즘의 이해

1-1 자료구조에 대한 기본적인 이해

자료구조란 무엇인가

  • 자료구조에서는 데이터를 표현하고 저장하는 방법에 대해서 설명함
    • 데이터의 저장을 담당하는것이 바로 자료구조
    • 넓은 의미에서 int형 변수 선언이나 구조체의 정의, 배열의 선언 또한 자료구조에 속함
  • 실제로는 아래의 세부 자료 구조들이 존재
    • 선형구조
      • 리스트
      • 스택
    • 비선형구조
      • 트리
      • 그래프
    • 파일구조
      • 순차파일
      • 색인파일
      • 직접파일
    • 단순구조
      • 정수
      • 실수
      • 문자
      • 문자열
  • 수업에서는 __선형구조, 비선형구조__에 대해서만 다룸
  • 선형구조는 자료의 표현방식이 선형임을 의미
    • 선형 자료구조는 데이터를 선의 형태로 나란히 혹은 일렬로 저장하는 방식(공부하기 수월)
  • 비선형구조는 데이터를 나란히 저장하지 않음(어려움)

본서에서 자료구조 설명하는 방향

  • 본 서는 코드레벨에서의 구현이 아닌 자료구조의 모델 자체에 대한 이해를 강조한 서적

자료구조와 알고리즘

  • 자료구조는 데이터의 표현 및 저장방법을 뜻한다면, 알고리즘은 저장된 데이터를 대상으로 하는 문제 해결 방법을 의미
  • 따라서 자료구조가 결정되어야 그에 맞는 문제 해결 방법을 제시 할 수 있으므로 밀접한 관계를 가짐

1-2 알고리즘의 성능분석 방법

시간 복잡도와 공간 복잡도

  • 시간 복잡도는 속도에 해당하는 알고리즘의 수행시간 분석결과를 가리킴
  • 공간 복잡도는 메모리 사용량에 대한 분석결과를 가리킴
  • 보통 공간 복잡도보다 시간 복잡도를 더 중요시 여김
  • 시간 복잡도의 판단은 처리해야 할 데이터의 수 $n$에 대한 연산횟수의 함수 $T(n)$을 구성
    • 데이터 수의 증가에 따른 연산횟수의 변화 정도를 정량적으로 판단 할 수 있기 때문

순차 탐색(Linear search) 알고리즘과 시간 복잡도 분석의 핵심요소

  • 순차 탐색 알고리즘이라는 간단한 알고리즘으로 시간 복잡도를 계산
# pragma warning disable(4996)
# include<stdio.h>
int LSearch(int ar[], int len, int target)
{
	int i;
	for (i = 0; i < len; i++)
	{
		if (ar[i] == target)
			return i;
	}
	return -1;
}

int main(void)
{
	int arr[] = { 3, 5, 2, 4, 9 };
	int idx;

	idx = LSearch(arr, sizeof(arr) / sizeof(int), 4);
	if (idx == -1)
		printf("탐색실패 \n");
	else
		printf("타겟 저장 인덱스: %d \n", idx);
	idx = LSearch(arr, sizeof(arr) / sizeof(int), 7);
	if (idx == -1)
		printf("탐색실패 \n");
	else
		printf("타겟 저장 인덱스: %d \n", idx);
	getchar();
	return 0;
}
  • 위 코드에서 순차탐색 알고리즘인 LSearch 함수 내의 for문을 볼 때, 데이터 수 $n$에 대한 시간 복잡도 $T(n)$을 계산해보자.
    • 알고리즘에 사용된 연산자는 <, ++, == 세 가지임
    • 이 중 값을 비교하는 == 연산을 가장 적게 수행하는 탐색 알고리즘이 좋은 탐색 알고리즘임
    • 즉, 탐색 알고리즘의 핵심은 동등비교를 하는 비교연산에 있음
      • 비교연산을 적게할수록 <연산과 ++연산의 수행횟수가 줄게 됨(다른 연산들이 == 연산에 의존적)
    • 즉, ==연산의 횟수를 대상으로 시간 복잡도를 분석하면 됨
    • 찾고자 하는 배열의 값이 맨 앞에 있으면 비교연산의 수행횟수는 1이 됨 -> best case
    • 찾고자 하는 배열의 값이 맨 뒤에 있으면 비교연산의 수행횟수는 n이 됨 -> worst case (중요)
    • Average case의 경우 합리적이나 계산이 복잡하고 평균의 정의가 애매 -> 따라서 worst case로 계산

순차 탐색 알고리즘의 시간 복잡도 계산 1: Worst case

  • 데이터의 수가 n개일때 worst case는 n이 됨
  • $T(n)=n$

순차 탐색 알고리즘의 시간 복잡도 계산 2: Average case

  • 가정 1. 탐색 대상이 배열에 존재하지 않을 확률을 50%라고 가정: $T(n)=n$
  • 가정 2. 배열의 첫 요소부터 마지막 요소까지 탐색 대상이 존재할 확률은 동일: $T(n)=\frac{n}{2}$
  • 가정 1과 가정 2에 따라 위의 두 식을 하나로 묶어야 함 -> $n\times \frac{1}{2}\times +\frac{n}{2}\frac{1}{2}=\frac{3}{4}n$
  • 따라서 순차 탐색 알고리즘의 average case의 시간 복잡도는 $T(n)=\frac{3}{4}n$가 됨
  • 계산이 복잡하고, 모든 가정을 제대로 정의하지 못하면 신뢰도가 낮게 됨

이진 탐색(Binary Search) 알고리즘의 소개

  • 배열에 저장된 데이터는 정렬되어 있는 상태일 때만 사용 가능
  • 길이가 9인 배열에 다음과 같이 정렬된 데이터가 있다고 가정
  • arr[] = {1, 2, 3, 7, 9, 12, 21, 23, 27}
  • 위의 배열을 대상으로 숫자 3이 저장되어 있는지를 확인하기 위한 이진 탐색 알고리즘 적용
    • 첫 번째 시도: 배열의 중앙에 찾는 값이 저장되어 있는지를 확인
      • 배열 인덱스 시작과 끝은 각각 0과 8
      • 0과 8을 합하여 그 결과를 2로 나눔
      • 2로 나눠서 얻은 결과 4를 인덱스 값으로 하여 arr[4]에 저장된 값이 3인지 확인
    • 두 번째 시도: 탐색의 대상을 반으로 줄임(정렬되어있으므로)
      • arr[4]의 값인 9와 3의 대소를 비교
      • arr[4]>3 이므로 탐색 범위를 인덱스 0~3으로 제한
      • 0과 3을 더하여 결과를 2로 나눔(나머지 버림)
      • 2로 나눠서 얻은 결과 1을 인덱스 값으로 하여 arr[1]에 저장된 값이 3인지 확인
    • 세 번째 시도: 동일 패턴 반복
      • arr[1]의 값인 2와 3의 대소를 비교
      • arr[1]<3이므로 탐색 범위를 인덱스 2~3으로 제한
      • 2와 3을 더한 후 2로 나눠 2 계산(나머지 버림)
      • arr[2]의 값이 3인지 확인

이진 탐색 알고리즘의 구현

  • 왼쪽 끝 인덱스 first와 오른쪽 끝 인덱스 last가 first<=last 조건을 만족할 동안 비교가 진행되어야 함
    • first = last일 때에도 비교해야 할 대상이 아직 하나 남아있기 때문
# pragma warning disable(4996)
# include<stdio.h>
int BSearch(int ar[], int len, int target)
{
	int first = 0;
	int last = len - 1;
	int mid;
	while (first <= last)
	{
		mid = (first + last) / 2;

		if (target == ar[mid])
			return mid;
		else
		{
			if (target < ar[mid])
				last = mid - 1; // ???
			else
				first = mid + 1; // ???
		}
	}
	return -1;
}

int main(void)
{
	int arr[] = { 3, 5, 2, 4, 9 };
	int idx;

	idx = BSearch(arr, sizeof(arr) / sizeof(int), 4);
	if (idx == -1)
		printf("탐색실패 \n");
	else
		printf("타겟 저장 인덱스: %d \n", idx);
	idx = BSearch(arr, sizeof(arr) / sizeof(int), 7);
	if (idx == -1)
		printf("탐색실패 \n");
	else
		printf("타겟 저장 인덱스: %d \n", idx);
	getchar();
	return 0;
}
  • 위 코드에서 아래처럼 구현하지 않고 위처럼 +1을 추가하여 구현한 이유는?
if (target < ar[mid])
  last = mid;
else
  first = mid;
  • 정답 코드처럼 하지 않으면 불필요한 mid에 저장된 인덱스 값이 배열요소도 새로운 탐색의 범위에 포함이 되기 때문
  • 또한 위 코드처럼 작성 할 경우 대상을 배열에서 찾지 못할 경우 무한loop에 빠지며 프로그램이 종료되지 않게 됨
    • 탐색 대상이 배열에 존재하지 않을 경우 first의 값이 last보다 커져서 반복문을 탈출해야 함

이진 탐색 알고리즘의 시간 복잡도 계산: Worst case

  • 이진 탐색 알고리즘 또한 BSearch 함수의 while문 내의 배열 중앙 값과 찾는 값이 비교연산인 ==가 연산횟수를 대표함
  • 하지만 순차 탐색과는 다르게 n이 쉽게 정의되지 않음
    • 데이터의 수 n이 n/2, n/4, n/8, …, 1이 될 때까지 비교연산을 진행
    • 마지막으로 n이 1일 때 비교연산을 한번 더 수행(worst case, 수가 존재하지 않을 경우)
    • 데이터의 수가 8일 경우 8, 4, 2, 1로 총 4회의 연산 수행
  • 좀 더 정리하자면 다음과 같음
    • n이 1이 되기까지 2로 나눈 횟수 k회, 따라서 비교연산 k회 진행
    • 데이터가 1개 남았을 때, 이때 마지막으로 비교연산 1회 진행
    • 따라서 $T(n)=k+1$이 됨
  • k를 구하는 과정은 다음과 같음
    • n이 1이 되기까지 2로 나눈 횟수 k에 대해 n과 k에 관한 식은 다음과 같음
    • $n\times (\frac{1}{2})^{k}=1$ 이므로 양변에 log를 씌워 정리하면 $k=\log_{2}n=k$가 성립
  • 따라서 +1항은 근사화가 가능하므로 $T(n)=\log_{2}n$으로 정의됨

빅-오 표기법(Big-Oh Notation)

  • 빅-오라는 것은 함수 $T(n)$에서 가장 영향력이 큰 부분이 어딘가를 따지는 것임
  • $T(n)=n^{2}+2n+1$일 때, n이 매우 커지게 됨에 따라 $T(n)\approx n^{2}$가 됨
  • 이를 $O(n^{2})$라 하고, Big-Oh of $n^{2}$ 라고 읽음
  • 빅-오는 다항식 T(n)에 대해 최고차항의 차수로 정의 됨
    • $T(n)=5n^{3}+3n^{2}+2n+1$ -> $O(n^{3})$
  • 즉, 시간복잡도함수 T(n)에서 실제로 큰 의미를 갖는 것은 최고차항의 차수가 됨
    • 하지만 이는 식의 종류에 따라 다르므로(다차원 다항식에만 적용가능), 다양한 형태의 빅-오 표기들이 존재

대표적인 빅-오

  • $O(1)$
    • 상수형 빅-오
    • 데이터 수에 상관없이 연산횟수가 고정인 유형의 알고리즘을 뜻함
    • 예를 들어 연산의 횟수가 데이터 수에 상관없이 3회 진행되는 알고리즘일지라도 O(3)이 아닌 O(1)로 표기
  • $O(\log{n})$
    • 로그형 빅-오
    • 데이터 수의 증가율에 비해 연산횟수의 증가율이 훨씬 낮은 알고리즘을 의미(바람직한 유형)
    • 로그의 밑이 얼마냐에 따라 차이가 나나 알고리즘의 성능 관점에서 매우 미미하기에 대부분 무시됨
  • $O(n)$
    • 선형 빅-오
    • 데이터의 수와 연산횟수가 비례하는 알고리즘을 의미
  • $O(n\log{n})$
    • 선형로그형 빅-오
    • 데이터의 수가 두 배로 늘 때, 연산횟수는 두 배를 조금 넘게 증가하는 알고리즘
    • 많은 알고리즘들이 이 형태를 띔
  • $O(n^{2})$
    • 데이터 수의 제곱에 해당하는 연산횟수를 요구하는 알고리즘
    • 데이터의 양이 많은 경우에는 적용하기 부적절 (중첩된 반복문의 사용)
    • 중첩된 반복문의 사용은 알고리즘 디자인에서 바람직하지 못함
  • $O(n^{3})$
    • 데이터 수의 세 제곱에 해당하는 연산횟수를 요구하는 알고리즘
    • 삼중으로 중첩된 반복문 내에서 알고리즘 관련 연산이 진행되는 경우
    • 바람직하지 못한 꼴
  • $O(2^{n})$
    • 지수형 빅-오
    • 사용하는것 자체가 바람직하지 못한 알고리즘
  • 빅-오간의 성능은 아래로 갈수록 점점 나빠지는 꼴
    • 즉, 연산량이 기하급수적으로 증가하게 되므로 위에 가까울수록 좋은 알고리즘이다

순차 탐색 알고리즘과 이진 탐색 알고리즘의 비교

  • 순차 탐색 알고리즘의 T(n) 함수: $T(n) = n$ -> $O(n)$
  • 이진 탐색 알고리즘의 T(n) 함수: $T(n) = \log_{2}{n}+1$ -> $O(\log{n})$
  • 실제 보기엔 $O(n)$과 $O(\log{n})$정도의 차이면 큰 차이가 아니라 하나, 실제로는 엄청난 차이를 보이는 것
    • $O(\log{n})$의 성능이 훨씬 우세

자료구조 공부 시작

|

자료구조 공부 시작

  • 윤성우의 열혈 자료구조 책을 이용한 자료구조 공부
  • https://www.orentec.co.kr/ 에서 인강

로그인 없이 원격 저장소 이용하기(Github)

|

로그인 없이 원격 저장소 이용하기(Github)

  • SSH(Secure SHell)를 통해 원격 저장소에 접근하는 방법에 대한 소개
  • Github는 서비스형 원격저장소이며, 다른 형태의 다양한 원격저장소가 존재
  • Github를 이용해서 원격저장소 운용 시 Clone할 때 Use HTTPS와 Clone with SSH의 두 가지 방식이 제공 됨
    • HTTPS의 장점은 그냥 ID와 PW만으로도 원격저장소에 push할 수 있으나, push 할 때마다 ID와 PW가 필요
    • SSH의 중요한 장점은 로그인을 매번 할 필요가 없게 됨
      • 단, 자동 로그인방식을 의미하는게 아닌 그냥 통신방식의 차이
  • ssh-keygen을 친 후 뜨는 경로에 비밀번호가 저장됨
  • 다음으로 계속 엔터를 치면 다른컴퓨터로 접속 가능하게 한 비밀번호가 생성됨
    • 단, SSH는 기계적으로 굉장히 복잡한 비밀번호를 자동으로 생성
  • 해당 경로로 이동(ex. cd ~/.ssh)
  • 경로의 파일들을 중 id_rsa, id_rsa.pub가 비밀번호 키
    • id_rsa: private key(비밀번호가 저장되어있음)
    • id_rsa.pub: public key(공개된 정보가 저장되어있음)
  • 개인 pc에 private 키가 저장되며, public 키도 개인 pc에 저장되나 이 파일은 복사되어 접속하고자 하는 pc의 일정한 디렉터리에 저장
    • 퍼블릭 키가 저장된 파일이 존재하는 pc에 개인 pc로(private 키가 저장된) 접속 시 이를 인지하고 자동으로 로그인해주게 됨
  • 아래의 과정을 통해 Github에 퍼블릭 키를 저장하게 된 것임
  • cat id_rsa.pub로 파일 내용을 보고 해당내용을 copy
  • 다음으로 깃헙에 가서 Settings에서 SSH and GPG keys를 들어가서 공개 키를 저장
    • new SSH key 선택
    • Title에 지역 저장소의 이름(임의대로) 지정
    • 아까 copy 한 내용을 붙여넣기
    • add SSH key 하면 등록 완료
  • Test를 위해 Github에 새로운 저장도를 만듦(gitfth_ssh)
  • 새 repository 생성 시 HTTPS가 아닌 SSH로 선택(주소창 왼쪽) 후 복사
  • 컴퓨터로 돌아와서 git clone git@github.com:ID/gitfth_ssh.git gitfth_ssh로 클론
  • 다음으로 yes를 치고 엔터
    • 보안적인 내용임
  • vim f1.txt파일을 만들고 내용 채운 후 저장
  • git add f1.txt, git commit -m 1로 커밋 후 git push
    • push가 잘 된다면 ssh 키(id_rsa, id_rsa.pub)가 잘 짝을 이루고 있는 상태임