기록은 기억의 연장선

더 많은 것을 기억하기 위해 기록합니다


  • Home

  • Tags

  • Categories

  • Archives

  • Search

markdown

Posted on 2017-12-28 | Edited on 2020-11-02 | In etc | Comments:

문단 쓰기, 줄바꿈

기본적으로 마크다운은 엔터 한번은 그냥 무시하고 한 문단으로 간주합니다.
띄워쓰기를 표시하려면 2번의 엔터를 쳐야 합니다.
그러나 몇몇 마크다운 에디터에서는 ‘엔터 한번’ == '개행’을 지원하기도 합니다.

1
2
3
4
개행 테스트
개행!

진짜 개행

개행 테스트
개행!

진짜 개행

html 직접 사용 가능

1
2
<hr />
<span style="color:red">**red**</span>

> 출력


**red**

특수문자 자동 적용됨

1
2
<div> 태그를 사용하자
&lt;div&gt; 태그를 사용하자

> 출력

태그를 사용하자 <div> 태그를 사용하자

제목. 6개 크기 까지 지원한다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# h1
## h2
### h3
#### h4
##### h5
###### h6
####### h7

# h1
## h2
### h3
#### h4
##### h5
###### h6
####### h7

인용

1
2
3
4
> 인용되는 글
> 길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게
>> depth를 늘림
> 내부에서 **markdown** 사용 가능

> 출력

인용되는 글
길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게길게

depth를 늘림, 변경할때는 아래와 같이 빈줄 하나 넣어야 함.

내부에서 markdown 사용 가능

리스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
숫자의 경우 자동으로 넘버링 된다.

처음쓰는 리스트의 숫자부터 카운트 된다.

1. 숫자
2. 숫자
3. 숫자

순서를 바꿔도 1,2,3 으로 출력된다

1. 숫자
4. 숫자
7. 숫자

일반 리스트는 *, +, - 중 아무거나 쓰면 된다.

* 일반 리스트
- 일반 리스트
+ 일반 리스트

리스트 안에 두 문단이상 사용할 경우, tab을 사용한다.

계속해서 이어가려면 아래와 왼쪽 탭 정렬선을 맞춰줘야 한다.

- 첫번째 리스트

이어지는 문단1

이어지는 문단2

- 두번째 리스트

> 출력

숫자의 경우 자동으로 넘버링 된다.

처음쓰는 리스트의 숫자부터 카운트 된다.

  1. 숫자
  2. 숫자
  3. 숫자

순서를 바꿔도 1,2,3 으로 출력된다

  1. 숫자
  2. 숫자
  3. 숫자

일반 리스트는 *, +, - 중 아무거나 쓰면 된다.

  • 일반 리스트
  • 일반 리스트
  • 일반 리스트

리스트 안에 두 문단이상 사용할 경우, tab을 사용한다.
계속해서 이어가려면 아래와 왼쪽 탭 정렬선을 맞춰줘야 한다.

  • 첫번째 리스트

이어지는 문단1

이어지는 문단2

  • 두번째 리스트

이스케이프 문자

태그로 변형되는 문자를 그냥 사용하고 싶을 때가 있습니다.(>, - 등)

그냥 사용하면 md에서 해석해버리므로 앞에 \ 를 붙여줍니다.

1
2
3
\> : 원래는 인용으로 표시됨
1998\.서울올림픽 : 원래는 1.서울올림픽으로 표시됨(자동 넘버링)
\- : 원래는 리스트로 표시됨

> : 원래는 인용으로 표시됨

1998.서울올림픽 : 원래는 1.서울올림픽으로 표시됨

- : 원래는 리스트로 표시됨

코드 블록

마크다운 내에서 코드를 표현 가능하다!
키보드 왼쪽 가장자리에 있는 ` 키를 사용하면 된다.
``` 옆에 사용하는 언어를 넣어주면 해당 문법에 맞게 해석한다

<!–7–>

> 출력

1
2
var str = 'test str';
console.log(str);

수평선

1
2
3
4
5
6
편한대로 골라쓰면 된다.

***
* * *
---
- - -

> 출력

편한대로 골라쓰면 된다.





강조하기

*나, _를 사용하여 표시한다.

1
2
*이탤릭*
**볼드**

> 출력

이탤릭

볼드

취소선

1
~~취소~~

> 출력

취소

링크 걸기

링크 주소 자체에 링크를 거는 방법과, 문구를 사용하는 방법이 있다.
물론 상대경로도 가능하다!

  1. <http://주소>
  2. [링크걸 문구](http://주소)
1
2
3
4
5
<http://google.com>

[구글](http://google.com)

상대경로 : [1번 포스트](/1)

> 출력

http://google.com

구글

상대경로 : 1번 포스트

이미지 삽입

![사진이름](사진경로)

1
![테스트사진](http://leader.pubs.asha.org/data/Journals/ASHANL/934378/NIB1_web.png)

> 출력

테스트사진

테이블

| 와 - 로 구분하여 테이블을 그릴 수 있다.

1
2
3
4
Field1 | Field2 | Field3
-|-|-
Data1 | Data2 | Data3
Data4 | Data5 | Data6

> 출력

Field1 Field2 Field3
Data1 Data2 Data3
Data4 Data5 Data6

헤드부분, 즉 html의 th부분은 꼭 있어야 한다! (상단 2줄)

emoji

github은 emoji를 지원한다.
https://www.webpagefx.com/tools/emoji-cheat-sheet/

Read more »

[java] java se, ee 차이

Posted on 2017-12-28 | Edited on 2020-11-02 | In java | Comments:

토론글

https://okky.kr/article/278014

java SE, EE는 스펙이다(패키지는 SE는 java.xxxx, EE는 javax.XXXX 이다.)
java EE 스펙은 SE 스펙을 포함한다.

SE를 구현한 애들이 oracle, openJdk 등등인 것.
java EE를 구현한 애들은 tomcat, jeus, jboss 등이다.
그래서 톰캣을 설치할 때 java를 미리 설치해둬야 하는 것.

Read more »

[linux] bash_profile과 bashrc

Posted on 2017-12-26 | Edited on 2020-11-02 | In linux | Comments:

리눅스에서 alias를 수정하거나 PATH를 변경할 떄 접하게 되는 대표적인 4가지의 파일들…

1
/etc/profile, /etc/bashrc, ~\.bash_profile, ~\.bash_rc

profile

/etc/profile 파일의 경우 전역적인 파일로 모든 사용자가 로그인 시 실행되며,
~/.bash_profile 파일의 경우 지역적인 파일로 해당하는 사용자가 로그인 시만 실행된다.
또한 /etc/profile의 경우 어떠한 shell이든 상관없지만, ~/.bash_profile의 경우 bash shell일 경우에만 해당된다.

bashrc

profile과 달리 Login 과정이 없으므로 shell을 실행시키는 사용자로 구분한다.
/etc/bashrc의 경우 모든 사용자가 shell을 실행시킬 때 마다 실행되며,
~/.bashrc의 경우 해당하는 사용자가 shell 실행시킬 때 실행된다.

Login Shell, Non-Login Shell

두 파일의 차이는 로그인 여부인데, 쉘의 종류에도 Login Shell, Non-Login Shell이 있다

Login Shell

Shell을 실행할 때 로그인이 필요한 경우를 말한다.
ssh로 접속하거나, su 명령어로 다른계정을 들어갈 때 등이 해당된다.

/etc/profile, ~/.bash_profile

Non-Login Shell

Shell을 실행할 떄 로그인이 필요하지 않은 경우를 말한다.
즉 Shell이 실행되는 모든 상황을 의마한다.
GUI에서 터미널을 띄울때나, bash 명령어로 다시 bash를 실행하는 경우 등이 해당된다.

/etc/bashrc, ~/.bashrc

Non-Login Shell은 Login Shell을 포함한다.
Login Shell이 실행될 때 profile과 bashrc 파일이 모두 실행되게 되고,
Non-Login Shell이 실행될 때 bashrc 파일만 실행되게 된다.

profile의 경우 대부분 환경 변수같은 것을 명시하고 bashrc의 경우 alias 같은 것을 명시한다…(?)

Read more »

[linux] apt 명렁어

Posted on 2017-12-25 | Edited on 2020-11-02 | In linux | Comments:

패키지란

커널 및 라이브러리 버전의 배포판 환경에 맞추어 빌드한 실행파일을 압축한 것.

apt란

우분투에서 쓰이는 데비안 계열의 패키지를 관리하는데 쓰이는 도구이다.

패키지 저장소 리스트 : /etc/apt/sources.list

이 패키지 저장소 덕분에 일일히 홈페이지를 검색하며 들어가는 등의 수고를 할 필요가 없어지게 된다.

하지만 모든 프로그램이 우분투 공식 패키지 저장소에 들어갈 순 없다.
그래서 PPA(Personal Package Archivce)라는 개인 패키지 저장소를 이용한다.
(공식 패키지 저장소가 느릴때 PPA를 사용하기도 한다. 공식 저장소에는 몇만개의 패키지가 있으므로…)
해당 패키지 저장소를 apt 패키지 저장소에 추가해주면 해당 패키지 저장소를 통해 패키지를 내려받을 수 있게 된다.
저장한 PPA 목록은 /etc/apt/sources.list.d 에서 확인할 수 있다.

1
2
3
4
5
6
7
8
#추가
sudo add-apt-repository '저장소이름'
#삭제
sudo add-apt-repository --remove '저장소이름'

#이후작업
sudo apt-get update # 저장된 패키지 저장소를 토대로 패키지 목록을 업데이트 한다
sudo apt-get install '패키지명' # 패키지를 다운로드한다.

패키지 리스트 업데이트

1
apt-get update

> 실제 패키지를 업그레이드 하는 것이 아니라 사용가능한 패키지 리스트의 정보를 업데이트

패키지 업데이트

1
apt-get upgrade

> 실제 설치되어 있는 패키지들을 최신 버전으로 업그레이드

패키지 설치

1
apt-get install [패키지명]

패키지 재설치

1
apt-get --reinstall install [패키지명]

패키지 삭제

1
2
apt-get remove [패키지명] # 설정파일은 지우지 않음
apt-get purge [패키지명] # 설정파일까지 지움

패키지 검색

1
apt-cache search [패키지명]

패키지 정보

1
apt-cache show [패키지명]

apt 명령어를 이용해 설치한 패키지는 /var/cache/apt/archives 에 설치된다.

Read more »

[linux] 프로세스

Posted on 2017-12-24 | Edited on 2020-11-02 | In linux | Comments:

작업 : 작성한 프로그램 + 프로그램 실행에 필요한 데이터
작업이 커널에 등록되어 커널의 관리하에 있게 되면 이를 프로세스라고 부른다.
일반적으로 실행중인 프로그램을 말한다.

종속된 자식 프로세스는 부모 프로세스의 환경을 물려받으나 역은 성립하지 않는다.

Read more »

[linux] 파일/디렉토리 관리

Posted on 2017-12-23 | Edited on 2020-11-02 | In linux | Comments:
  1. 와일드 카드
    ? : 어떤 한 문자
  • : 어떤 문자도 없거나 그 이상
    [] : [] 내에 지정된 각각의 문자
    [a-d] 는 a,b,c,d를 의미, [acd]는 a,c,d를 의미한다. [abcd]* 는 a,b,c,d로 시작하는 파일 모두를 의미한다.
    [abcd]?, [a-d]? 등등의 예시가 많다. “rm [abc]*” 처럼 사용할 수 있다.
  1. 리다이렉션
    표준 입출력을 키보드나 모니터가 아닌 파일로 받거나, 출력하는 것을 의미.

표준 출력의 변경 : >, >>
결과를 파일로 보냄, >>는 기존 파일의 내용을 유지한 채 내용을 추가할 떄 사용한다.

access.log 와 같이 사용하면 access.log 파일의 내용을 모두 지우고 크기를 0으로 만들어 버릴 수 있다.
아무것도 없는 내용을 access.log에 전달하기 때문

표준 입력의 변경 : <
cat < testFile 과 같이 사용. 표준 출력은 터미널로 하고 표준 입력에 키보드가 아닌 testFile 이라는 파일을 사용한다
일반적으로 cat 파일명 < 파일명 의 형태가 많이 사용된다.

표준 에러 : 2>, 2>>
에러 내용을 파일로 저장하고자 할 때 사용한다. ls /asdfas 2> errorFile
2인 경우는 파일 디스크립터의 순서가 입력 0, 출력 1, 에러 2 이기 때문

표준출력과 표준에러를 한꺼번에 저장하려면 &>를 사용한다.
find / -name aa* &> errorLog

명령 > 파일명 : 명령의 결과가 파일에 저장. 에러는 모니터로 출력
명령 2> 파일명 : 에러 내용이 파일에 저장. 명령 결과는 모니터 출력
명령 &> 파일명 : 명령 결과, 에러 내용이 파일에 저장

  1. 파이프라인
    한 명령의 표준 출력을 다른 명령의 표준 입력으로 보내는 방식
    사용되는 기호는 | 이며, |로 구분 되면 한 개 이상의 명령이 연속되어 나올 수 있다
    이전 명령의 표준 출력이 다음 명령의 표준 입력이 되는 방식이다.
    command1 | command2 | command3 | command4 …
    1의 출력이 2의 입력, 2의 출력이 3의 입력, 3의 출력이 4의 입력…
    |&을 사용하면 표준출력 + 표준에러를 다음 명령의 표준 입력으로 사용할 수 있다.
    $? 는 특수한 변수로써, 앞서 실행한 명령의 종료 상태값을 받는다.

※ 파이프라인에 자주 사용되는 grep 명령어는 패턴에 맞는 문자열을 찾아주는 명령어이다.
grep 123 라고 입력하면, 사용자로부터 입력을 받아서 패턴에 맞을 경우 화면에 출력해준다.
grep만 입력하면 키보드로 표준 입력을 받는다. 보통은 파이프라인을 사용하여 명령의 결과값을
grep에게 표준입력으로 전달한다.

  1. 기타(||, &&, ;, &)
  1. ; : 한줄에 여러 명령어 입력.
    mkfs -t sfs -f /dev/sda5; mkdir /backup; mount /dev/sda5/backup 와 같이 사용
    하나의 작업을 기다렸다가 다시 입력하고 하는 방식보다 위와 같이 세미콜론으로 연결해서 사용 가능하다.

  2. &&, || : 앞에서 실행한 명령의 결과에 따라 다음 명령어 실행. 각 연산자의 특징을 이용하여 사용된다.
    ; 으로 연결했을 경우 앞의 명령의 실패여부에 관계없이 뒤의 명령이 무조건 실행된다.
    포멧이 실패했는데 마운트가 되는 경우가 발생할 수도 있는 셈이다.
    그리하여 &&과 ||를 써서 적절히 성공여부에 따라 명령을 조절할 수 있다.
    &&의 경우 앞,뒤가 참이여야 하는 논리연산자이다.
    그러므로 앞의 연산이 거짓일 경우, 뒤의 연산을 실행하지 않는다. -> 이것이 중요하다.
    cat asddd && echo ‘test’ 해보면, asddd 파일이 없을 경우 첫번째 연산결과가 거짓이므로 뒤의 echo는 실행되지 않는다.
    || 또한 마찬가지다. ||는 둘중 하나만 참이면 되는 논리연산자이다.
    그리므로 앞의 연산이 참일 경우, 뒤의 연산을 실행하지 않는다.
    cat asddd || echo ‘test’ 했을 경우, 앞의 연산이 참이면 뒤의 연산이 실행되지 않는다.
    즉, 위 두 연산자를 사용하려면 &&는 명령이 성공할 경우의 명령을 나열하면 되고, ||는 명령이 실패할 경우의 명령을 나열하면 되겠다.

  3. & : 백그라운드 모드로 실행
    명령어 마지막에 &를 붙여주면 백그라운드 모드로 실행 가능하다.

  1. 디렉토리 구조
    모든 디렉토리는 / 부터 시작한다.
    .는 현재 디렉토리 …는 부모 디렉토리 ~는 사용자의 홈 디렉토리를 의미한다.

  2. 파일

  1. 일반 파일 : 우리가 평상시 쓰는 파일
  2. 디렉토리 파일 : 파일을 포함하고 있는 파일. 일반 파일,디렉토리 파일, 특수 파일을 포함할 수 있다.
    근데 실제로 들어가보면 파일을 포함하고 있는 것이 아니라, 리눅스가 파일을 엑세스 하는데 필요한 정보를 가지고 있을 뿐이다.
  3. 특수 파일 :
Read more »

[linux] 사용자/그룹 관리

Posted on 2017-12-22 | Edited on 2020-11-02 | In linux | Comments:

리눅스는 여러명의 사용자가 동시에 로그인하여 시스템을 사용할 수 있는 멀티유저 운영체제이다.
이러한 사용자들은 각각 계정을 가지고 시스템에 접근하게 된다.
그리고 이 사용자들을 묶어서 관리할 수 있는 그룹이라는 것이 있다.
모든 사용자는 하나의 그룹을 가진다.

사용자 관리

/etc/passwd : 사용자 정보가 담긴 파일

1
2
3
root:x:0:0:root:/root:/bin/bash

# 사용자명:패스워드:UID:GID:사용자정보:홈디렉토리:쉘
  1. 사용자명 : 로그인 시 사용하는 사용자명.
    • 네이밍 규칙 : 영문자 대소문자, 숫자, “-”, “_”, “.” 사용 가능, 보통 1~32자 사용
  2. 패스워드 : /etc/shadow 파일에 암호화되어 저장되어 있다.
  3. UID : 사용자 고유 ID
    • 일반 사용자는 1000~60000을 사용한다(/etc/login.defs에 명시)
      root 는 0으로 예약되어 있다.
  4. GID : 사용자가 속한 그룹 고유 ID
  5. 사용자정보 : 사용자에 대한 간단한 정보를 기입할 수 있다.
  6. 홈디렉토리 : 사용자 폴더. 로그인 시 최초 접속되는 폴더이기도 하다.
  7. 쉘 : 사용자가 사용하는 쉘 환경

사용자 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
> useradd [options] 사용자명 

# options
# -c [텍스트] : 사용자정보
# -m : 홈디렉토리 생성
# -M : 홈디렉토리 생성 안함
# -d [폴더] : 홈디렉토리 지정
# -N : 사용자 개인 그룹 생성하지 않음. default : 생성
# -u [UID] : UID 직접 지정
# -g [GID] : GID 직접 지정
# -s [Shell] : shell 지정

# 이 외에도 많은 옵션이 존재한다. useradd --help 를 활용한다.

생성 시 사용하는 default 값을 확인하고 바꿀 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/sh
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no

> useradd -D -b /test
> useradd -D
GROUP=100
HOME=/test #변경됨
INACTIVE=-1
EXPIRE=
SHELL=/bin/sh
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no

# 위에 대한 설정파일은 /etc/default/useradd 이다

사용자 추가 시 홈 디렉토리에 생성되는 파일

1
2
3
4
5
6
7
8
9
10
11
12
> useradd user1 -m
> cd /home/user1
> ls -al
합계 32
drwxr-xr-x 2 user1 user1 4096 10월 29 16:23 .
drwxr-xr-x 4 root root 4096 10월 29 16:23 ..
-rw-r--r-- 1 user1 user1 220 9월 1 2015 .bash_logout
-rw-r--r-- 1 user1 user1 3771 9월 1 2015 .bashrc
-rw-r--r-- 1 user1 user1 655 6월 25 2016 .profile
-rw-r--r-- 1 user1 user1 8980 4월 20 2016 examples.desktop

# /etc/skel에 있는 파일을 복사해 사용한다.

사용자 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> usermod [options] 사용자명 

# options
# -c [텍스트] : 사용자정보 수정
# -d [폴더] : 홈디렉토리 변경
# -u [UID] : UID 변경
# -s [Shell] : shell 지정
# -L : 계정 락킹
# -U : 계정 언락킹

# -g [group] : 사용자 기본 그룹 변경
> usermod -g user2 user1
# user1의 기본 그룹을 user2로 변경

# -G [groups] : 사용자 그룹 추가,변경(제거). 기본 그룹은 영향을 받지 않는다.
> usermod -a -G group1,group2 user1
# user1에 group1,group2를 추가. -a 옵션은 기존그룹에 추가할지 안할지 여부이다.
> usermod -G group1 user1
# 그룹을 제거하는 방법. -a를 주지 않아 기존 그룹을 유지하지 않았다.

패스워드 변경

1
2
3
4
5
6
> passwd [options] 사용자명

# options
# -d : 패스워드 삭제
# -e : 패스워드 강제 만료
# -l, -u : 패스워드 락킹/언락킹. usermod에 있는 -L, -U 옵션을 쓰는것이 더 좋다고 한다..

사용자 삭제

1
2
3
4
5
userdel [options] 사용자명

# options
# -r : 사용자의 홈디렉토리, 메일박스, 임시디렉토리 까지 같이 삭제.
그룹은 기본적으로 속한 사용자가 없으면 자동 삭제된다

그룹 관리

/etc/group : 그룹 정보가 담긴 파일

1
2
3
sudo:x:27:user1,user2

# 그룹명:패스워드:GID:사용자리스트
  1. 그룹명 : 그룹의 이름이다
  2. 패스워드 : 그룹 패스워드
  3. GID : 그룹 고유 ID
  4. 사용자리스트 : 해당 그룹에 속한 사용자들의 리스트.
    생략되는 경우도 많기 때문에 비어있다고 그룹에 속한 사용자가 없다고 확신할 수 없다.

그룹 추가

1
2
3
4
> groupadd [options] 그룹명

# options
# -g [GID] : GID 지정

그룹 수정

1
2
3
4
> groupmod [options] 그룹명

# options
# -n [이름] : 그룹명 변경

그룹 삭제

1
> groupdel 그룹명
Read more »

[git] github push 403

Posted on 2017-12-21 | Edited on 2020-11-02 | In git | Comments:

https://cheonjoosung.github.io/git/2017/07/10/it_git_permissionerror.html

1
git remote set-url origin 'https://<github-username>@github.com/<github-username>/<github-reppository-name>'
Read more »

[linux] 관리자 권한 전환

Posted on 2017-12-21 | Edited on 2020-11-02 | In linux | Comments:

Windows에서 최고 관리자가 Administrator였다면, 리눅스에서는 root입니다.
보안상의 이유로 root로 직접 로그인하는 것은 권장되지 않고,
일반 사용자로 로그인 한 뒤, 필요시에 root 권한으로 작업하는 것을 권장합니다.

sudo

일반 사용자가 root 권한으로 명령어를 실행하고자 할 떄 사용하는 명령어입니다.

1
sudo cat /etc/shadow

당연히 누구나 사용할 순 없고, 허가된 사용자만이 사용 가능한 명령어입니다.
이를 확인하기 위해선 /etc/sudoers 파일을 확인해야 합니다.

현재 우분투를 사용하고 있으므로, 우분투를 기점으로 해당 파일을 열어봤을때

1
2
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL

부분을 발견할 수 있습니다.

보다시피 sudo 그룹에 해당하는 멤버들은 모든 명령어를 사용할 수 있다고 명시되어 있습니다.
(기본적으로 관리자 계정으로 등록된 사용자는 sudo 그룹에 소속되어 있음)

그럼 유저를 하나 만들고, sudo 명령어를 사용 가능하도록 만들어보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 먼저 사용자 추가를 위해 root 계정으로 변경합니다. (su 명령어는 아래서 설명)
> su -

# user1 추가 및 패스워드 설정
> useradd -m user1
> passwd user1

> su - user1
> sudo cat /etc/shadow
[sudo] password for user1:
user1 is not in the sudoers file. This incident will be reported.
# sudo 명령어를 실행할 수 없다.

# user1에 sudo 그룹을 추가
> su -
> usermod -G sudo user1

# 다시 실행
> su - user1
> sudo cat /etc/shadow
[sudo] password for user1:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
.....
# 출력이 잘 된다!

sudo 명령어를 통해 root 권한으로 명령어를 실행하고 나면 다시 일반 사용자 권한으로 돌아오게 됩니다.
sudo 명령어 실행 시 입력한 암호는 5분 동안 유지됩니다! (5분간 암호를 재입력하지 않아도 됨)

su

sudo 처럼 잠시 관리자 권한을 빌려오는 것이 아니라, 아예 관리자 권한으로 전환할 때 사용합니다.

1
2
3
> su - 
암호 :
root@:~#

- 옵션을 주어야 root 사용자의 환경변수까지 다 읽어오게 됩니다.
입력하지 않을 경우 환경변수가 없어 명령어를 찾지 못하는 현상이 발생할 수도 있습니다.

su 뒤에 사용자명을 입력하여 root가 아닌 다른 사용자로 전환할 수도 있습니다.

1
2
3
> su - user2
암호 :
user2@:~$
Read more »

[db] 쿼리작성 및 최적화

Posted on 2017-12-13 | Edited on 2020-11-02 | In db | Comments:

시스템 설정

SQL 모드

MySql 서버에는 sql_mode 라는 시스템 설정이 있다.
이 설정을 통해 SQL의 작성, 결과 등에 영향을 주게 된다.

  1. STRICT_ALL_TABLES : 저장하려는 값의 길이가 컬럼의 길이보다 길 경우 오류 발생시킴. 원래는 초과된 부분만큼 자르고 저장하였음.
  2. STRICT_TRANS_TABLE : 컬럼의 타입과 값의 타입이 일치하지 않을 경우 오류 발생시킴. 원래는 비슷한 타입으로 최대한 변환시켜서 저장했음.
  3. ANSI_QUOTES : 문자열 표현에 오직 싱글쿼터만 사용가능. 더블쿼터는 컬럼명이나 테이블명만 사용 가능. 원래는 문자열에 싱글/더블 쿼터 모두 사용 가능했음.
  4. ONLY_FULL_GROUP_BY : GROUP BY 절에 포함되지 않은 컬럼을 출력하거나 HAVING에 사용할 수 없음. 원래는 가능했음… MySQL의 이상했던 점.
  5. PIPE_AS_CONCAT : 오라클 처럼 || 문자로 문자열 연결 가능. 원래는 불가능.

등등…

적용하는법은 my.cnf 파일에

1
sql_mode=STRICT_TRANS_TABLES,ANSI

의 형태로 작성해주면 된다. ,로 구분하여 여러개 지정할 수 있다.

sql_mode에서 알 수 있는 MySQL의 특징은?

영문 대소문자

MySql은 설치된 운영체제에 따라 테이블의 대소문자를 구분한다.
ex) 윈도우 : 구분X, 리눅스 : 구분O
DB나 테이블이 디스크의 디렉터리나 파일로 매핑되기 때문이다.
가능하면 대문자만 또는 소문자만으로 통일하는 것이 좋다.

예약어

일반적으로 테이블이나 컬럼 생성 시 예약어를 이름으로 사용하면 에러가 발생한다.
그러나 역따옴표(`)나 쌍따옴표(")로 감싸면 이를 피할 수 있다.
예를 들면 테이블 생성 시 역따옴표(`)로 둘러싸면 에러를 발생시키지 않는다.
하지만 역따옴표로 둘러싸서 생성하는 것을 권장하지는 않는다.


메뉴얼 읽는 법

image

  • 대문자는 키워드를 의미한다.
  • 이텔릭체는 사용자가 작성하는 이름 또는 표현식을 의미한다.
  • 대괄호( [] )는 선택사항임을 의미한다.
  • 파이프( | )는 연결된 것 중 단 하나만 선택할 수 있음을 의미한다.
  • 중괄호( {} )는 괄호 내 선택사항 중 반드시 하나를 선택해야 함을 의미한다.
  • …는 앞에 명시된 키워드나 표현이 반복될 수 있음을 의미한다.

MySQL 연산자, 내장함수

리터럴

문자열

항상 홑따옴표(’)를 사용해서 표시한다.
홑따옴표 자체를 사용하고 싶을 때는 홑따옴표를 두번 연속 입력하면 된다.
쌍따옴표와 홑따옴표의 조합으로 위의 행위를 할 수 있지만 MySql만 지원되는 방식이다.

숫자

다른 시스템들과 동일하게 ’ 나 " 없이 숫자 값을 입력하면 된다.

※ 자동 형 변환
MySql에서는 문자와 숫자를 비교할 때 자동으로 숫자값으로 형 변환해준다. (숫자 > 문자)

1
WHERE number_col = '10001';

와 같은 경우는 문제가 되지 않지만,

1
WHERE string_col = 10001;

의 경우에는 문제가 발생할 수 있다.
위와 같은 경우 오른쪽 숫자가 우선순위가 더 높으므로
왼쪽의 string_col이 숫자로 형 변환하는 상황이 발생하는데,
이로 인해 string_col은 인덱스를 사용하지 못하고,
만약 문자값이 포함된 데이터가 있다면 SQL 실행 오류로도 이어진다.

날짜

MySql에서 정해진 형태의 포멧으로 날짜를 입력하면(문자열로),
MySql에서 자동으로 DATE나 DATETIME으로 변환하여 준다.
위의 숫자 리터럴과 동일하다. (날짜 > 문자)

불리언

BOOLEAN이란 타입이 있긴 하나 실상 TINYINT에 대한 동의어일 뿐이다.
(테이블 컬럼 타입을 BOOLEAN으로 생성한 뒤 확인해보면 TINYINT 이다.)
BOOLEAN의 TRUE는 1을 의미하고, FALSE는 0을 의미한다.
0과 1만을 사용한다는 점을 주의해야 한다!!

연산자

동등 비교

=, <=>
기본적으로 NULL과의 연산은 결과값이 모두 NULL이다.

1
SELECT NULL=1 FROM DUAL;

> NULL

그래서 NULL의 경우 IS NULL등의 연산자로 비교해야 하는데, <=> 의 경우에는 NULL 또한 하나의 값으로 인식하여 계산한다.

1
SELECT NULL<=>NULL FROM DUAL;

> 1

부정 비교

<>, !=
둘중 어느것을 사용하든 상관없지만 통일하는 것이 좋다.

NOT 연산자

결과를 반대로 만든다. 부정의 결과를 정확히 예측할 수 없는 경우 사용하지 말자.
ex) !‘test’

AND, OR 연산자

&&, ||로 대체할 수 있으나 혼란을 야기하니 사용하지 말자.

나누기, 나머지 연산자
1
2
3
4
5
6
SELECT 29/9 FROM DUAL;
-- 3.222.. // 몫 + 나머지
SELECT 29 DIV 9 FROM DUAL;
-- 3 // 몫
SELECT 29 MOD 9 FROM DUAL;
-- 2 // 나머지
LIKE 연산자

상수 문자열이 있는지 없는지 정도만을 판단한다.
와일드 카드는 딱 2개만 사용가능하다.

% : 0개 또는 1개 이상 일치
_ : 정확히 1개 일치

와일드카드 문자가 검색어의 뒤쪽에 있다면 인덱스 레인지 스캔을 사용할 수 있다!
와일드카드가 앞쪽에 올 경우 인덱스 풀 스캔 또는 테이블 풀 스캔을 하게 된다.(B-Tree 인덱스의 특징 때문)

와일드카드 문자를 검색에 사용하고 싶을 경우 ESCAPE 구문을 사용한다.

1
SELECT 'a%' LIKE 'a/%' ESCAPE '/' FROM DUAL;
BETWEEN 연산자

>= 연산자와 <= 연산자를 합친 기능을 수행한다.
BETWEEN을 위의 연산자로 풀어도 성능상 차이가 없으니 크게 고려하지 않아도 된다.

IN 연산자

동등비교를 여러번 하는 연산자이다. 즉 일반적으로 빠르게 처리된다.
연산자의 입력이 상수가 아니라 서브쿼리일 경우 상당히 느려질 수 있으니 주의해야 한다.
NOT IN의 경우 부정형 비교여서 인덱스 풀 스캔을 사용한다.

※ BETWEEN 연산자와 IN 연산자 차이점
BETWEEN의 경우 범위만큼 인덱스를 다 읽어야 하는 반면,
IN의 경우 위에서 언급했듯이 동등 연산자를 여러번 수행하는 것과 같다.
실행계획을 비교해보면 인덱스를 타고 있지만 rows에서 차이가 나는것을 확인할 수 있다.

내장함수

NULL 값 비교
  • IFNULL : 값이 NULL인지 비교하고 NULL이면 다른 값으로 대체한다.
    첫번째 인자는 NULL인지 비교할 값, 두번째 인자는 NULL일시 대체값이다.
    첫번째 인자가 NULL이 아닐경우 그대로 출력된다.
  • ISNULL : 값이 NULL인지 아닌지 비교. NULL일 경우 TRUE(1), 아닐경우 FALSE(0)
현재 시각 조회
  • NOW : 시간 조회. 하나의 SQL내면 모두 같은 값을 가진다.
  • SYSDATE : 시간 조회. 하나의 SQL내에서도 호출 시점에 따라 결과값이 달라진다.
1
2
3
4
SELECT NOW(), SLEEP(1), NOW() FROM DUAL;
-- '2017-12-19 22:39:52' | '0' | '2017-12-19 22:39:52'
SELECT SYSDATE(), SLEEP(1), SYSDATE() FROM DUAL;
-- '2017-12-19 22:40:27' | '0' | '2017-12-19 22:40:28'

보다시피 SYSDATE의 경우 SLEEP(1)로 인해 1초가 차이난다.
SYSDATE의 경우 호출때마다 다른 값을 반환하므로 상수가 아니다.
그래서 인덱스를 효율적으로 사용하지 못한다. (인덱스라기 보단 캐싱을 못한다는게 더 맞지 않을까?)
이러한 문제점이 있으니 SYSDATE는 가급적 사용하지 않는것이 좋다.
CURRENT_TIMESTAMP, CURRNET_DATE, CURRENT_TIME은 NOW와 동일한데다 출력을 다양하게 활용할 수 있으니 이것을 사용해도 좋을 것 같다.

날짜 <> 문자
지정 문자 내용
%Y                     4자리 연도
%y 2자리 연도
%m 월
%d 일자
%H 24h 시간(00 ~ 23)
%h 12h 시간(01 ~ 12)
%i 분
%s 초
  • DATE_FORMAT : 날짜를 문자열로 변환한다.
    ex) DATE_FORMAT(NOW(), %Y-%m-%d)
    > 2017-12-19
  • STR_TO_DATE : 문자를 날짜로 변환한다. 여기서 주는 포멧은 기존 문자열의 포멧을 알려주는 것이다.
    ex) STR_TO_DATE(‘19920207’,’%Y%m^%d’)
    > 1992-02-07
    참고로 SQL 표준형태로 입력된 문자열은 STR_TO_DATE를 사용하지 않아도 자동으로 DATETIME으로 변환되어 처리된다.
날짜 연산
  • DATE_ADD : 첫번째 인자로 날짜, 두번째 인자로 더할 날짜를 주면 된다.
    두번째 인자는 INTERVAL n {KEYWORD} 의 형태로 줘야 한다.
    DATE_SUB 함수도 있으나 두번째 인자로 음수값을 줄 수 있기 때문에 DATE_ADD만으로도 충분하다.
    ex) DATE_ADD(NOW(), INTERVAL 3 DAY)
    ※ KEYWORD : YEAR, MONTH, WEEK, DAY, HOUR …
문자열 처리
  • LPAD, RPAD : 좌측 혹은 우측에 특정한 문자를 지정한 바이트 만큼 채우는 함수이다.
    첫번째 인자로 대상 문자열, 두번째 인자로 채울 바이트(기존 문자열 포함), 세번째 인자로 채울 문자를 넣는다.
  • LTRIM, RTRIM, TRIM : 연속된 공백문자를 제거하는 함수이다.
    LTRIM은 왼쪽, RTRIM은 오른쪽, TRIM은 양쪽의 공백을 제거한다.
문자열 결합
  • CONCAT : 문자열을 결합해서 하나의 문자열로 합치는 함수로 인자 개수는 제한이 없다.
    ex) CONCAT('My name is ', 'JoonT. ', 'Nice to ', ‘meet you.’);
    > My name is JoonT. Nice to meet you.
  • CONCAT_WS : CONCAT과 같은데 첫번째 인자로 구분할 문자열을 넣어줄 수 있다.
    ex) CONCAT_WS(’-’, ‘a’, ‘b’, ‘c’);
    > a-b-c
  • GROUP_CONCAT : GROUP BY 로 그룹핑된 집합을 문자열로 연결시킬 수 있다.
    단순 문자열 연결 외에도 구분자 추가, 정렬, 중복 제거 등을 할 수 있으므로 상당히 유용하다.
1
2
3
4
5
6
7
8
SELECT GROUP_CONCAT(emp_no) FROM dept_emp GROUP BY dept_no;
-- 1,2,3,4,5... : 기본적으로 ,로 연결됨
SELECT GROUP_CONCAT(emp_no SEPARATOR '-') FROM dept_emp GROUP BY dept_no;
-- 1-2-3-4-5... : 구분자를 줄 수 있음
SELECT GROUP_CONCAT(emp_no ORDER BY from_date DESC) FROM dept_emp GROUP BY dept_no;
-- dept_emp에 있는 컬럼으로 정렬 가능
SELECT GROUP_CONCAT(DISTINCT emp_no) FROM dept_emp GROUP BY dept_no;
-- 중복제거도 가능
값의 비교와 대체(CASE WHEN…THEN…END)

CASE WHEN…THEN…END
switch문과 비슷하다.
CASE str
WHEN ‘A’ THEN ‘A matched’
WHEN ‘B’ THEN ‘B matched’
ELSE ‘Nothing matched’
END
각각의 부분에 대해 동등(=) 연산을 한다.

아래처럼 따로 조건을 줄 수도 있다.
CASE
WHEN str >= 65 AND str <= 90 THEN ‘Upper Case’
WHEN str >= 97 AND str <= 122 THEN ‘Lower Case’
END

THEN 부분에 쿼리를 실행해서 조건별 쿼리 실행도 가능하다.
CASE sex
WHEN ‘M’ THEN (SELECT salary from salaries WHERE ~~ LIMIT 1)
WHEN ‘F’ THEN 0
END
남자일때는 쿼리를 실행하고, 여자일떄는 쿼리를 실행하지 않는다.
이로 인해 불필요한 쿼리가 실행되는 것을 막을 수 있다.

타입 변환
  • CAST : 명시적 형 변환을 하는 함수이다.변환할 값과 변환할 타입을 지정해주면 된다. 둘은 AS 로 연결한다.
    ex) CAST(‘1234’ AS INTEGER)
  • CONVERT : CAST와 동일하게 형 변환을 하는 함수이다.
    형 변환외에 문자집합 변환도 가능하다는 점이 차이점이다.
    ex) CONVERT(1234, UNSIGNED)
    ex) CONVERT(‘asd’ USING ‘utf8’)
이진값 <> 16진수

HEX : 이진값 -> 16진수
UNHEX : 16진수 -> 이진값

MD5, SHA

비대칭형 암호화 알고리즘에 사용된다.
SHA는 SHA1 알고리즘을 써서 160비트(20바이트) 해시값을 반환하고,
MD5는 메세지 다이제스트 알고리즘을 사용해서 128비트(16바이트) 해시값을 반환한다.
비밀번호 암호화 하는 과정에서 자주 사용되며, URL과 같은 긴 문자열에 인덱스를 주고싶을 때 해당 문자열을 해시값으로 변환해 인덱스를 주기도 한다.
해시값은 거의 진짜 왠만해선 중복되는 일이 없기 때문이다.

변환된 해시값은 16진수로 출력되기 때문에 값을 저장하려면 변환되는 해시값의 크기보다 2배 큰 값을 할당해줘야 하는데(1바이트 == 16진수 2개), 원래의 16바이트, 20바이트에 저장하고 싶다면 BINARY 타입의 컬럼에 저장하면 된다.
BINARY로 변환은 위에서 사용한 HEX, UNHEX 함수를 사용하면 된다.

디버깅용 함수

SLEEP(초) : 실행되면 그 구간만큼 멈춘다. 디버깅 용도로 사용한다.
BENCHMARK(쿼리문, 실행횟수) : 쿼리문이 실행되는데 몇초 걸리는가 테스트 해볼 수 있다.
실행횟수로 여러번 반복해볼 수도 있는데… 솔직히 별로 안쓸듯.
왜냐면 쿼리문은 하나의 컬럼, 레코드인 스칼라값을 반환해야 하고,
실행횟수도 실제로 10번 실행하는 것과 BENCHMARK로 10번 실행하는것이 다르기 떄문.
실제 쿼리를 10번 실행하는 서비스 환경에서는 10번의 네트워크 자원, 서버 자원등이 다 요청되지만 BENCHMARK의 경우 단 1번만 요청되기 떄문.

IP 주소 변환

IP주소를 UNSIGNED INTEGER의 형태로 상호변환 가능하다.

  • INET_ATON : IP 주소 -> UNSIGNED INTEGER
  • INET_NTOA : UNSIGNED INTEGER -> IP 주소
    ex)
1
2
3
4
SELECT name, INET_NTOA(ip_addr) 
FROM TEST
WHERE ip_addr BETWEEN
INET_ATON('192.168.0.1') AND INET_ATON('192.168.0.100');

훨씬 효과적으로 저장 및 조회가 가능하다.

MySQL 전용 암호화

MySQL내의 user를 생성할때 썼던 PASSWORD 함수를 말한다.
많은 사람들이 이 함수의 이름만 보고 실제 회원의 비밀번호를 이것으로 암호화하곤 했다.
하지만 이는 절대 암호화 함수가 아니다. MySQL 내부에서 그냥 사용하는 것이고, 내부 암호화 알고리즘도 명시된것이 없다. 바뀔수도 있다는 것이다.
실제로도 바뀌었다. MySQL 4.1 이전과 이후로 PASSWORD 함수를 입력하면 변경되는 값이 다름을 볼 수 있다.
이로인해 DB 버전 업데이트를 했을 경우 사용자가 로그인하지 못하는 심각한 일이 발생할 수 있다.
이럴 경우 기존의 PASSWORD함수를 OLD_PASSWORD로 바꿔서 임시로 막을 수 있다.
변경된 PASSWORD 함수에서는 암호화시에 *를 앞에 붙인다. 이로인해 어플리케이션에서 구분할수도 있다. 하지만…
기본적으로 이 함수를 절대 패스워드 암호화 하는데 쓰지 않도록 해야한다.

VALUES
1
2
3
4
5
6
7
INSERT INTO table_statistics(member_id, visit_count)
SELECT member_id, COUNT(*)
FROM tab_accesslog
GROUP BY member_id
ON DUPLICATE KEY
-- UPDATE visit_count = visit_count + COUNT(*) // 불가능
UPDATE visit_count = visit_count + VALUES(visit_count) -- 인서트하려 했던 값 참조 가능

UPDATE 문은 서브쿼리의 일부가 아니기 때문에 COUNT(*)로 접근이 불가능하다.
하지만 위와 같이 VALUES 함수를 사용하면 위에 INSERT에서 추가하려고 했던 컬럼에 접근 가능하다.

COUNT

출력된 레코드의 개수를 세거나, GROUP BY 함수와 같이 사용해 그룹화 된 요소들의 개수를 출력하는데 사용한다.
COUNT() 라고 행 전체를 다 읽어오거나… 그런 의미가 아니라,
그냥 레코드 1개 자체를 의미한다.
즉 COUNT(
), COUNT(‘A’), COUNT(1)은 아무 차이가 없다.
하지만 COUNT(컬럼명) 으로 했을 경우 NULL인 값은 제외되므로 이부분은 조심해서 사용해야 한다.

주석

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--- 한줄 주석(SQL 표준)

/*
여러줄 주석(SQL 표준)

여러줄
여러줄
여러분
*/

/*! 변형된 C언어 스타일의 주석인데, 이는 SQL에서 힌트로 사용할 수 있다. */
/*! STRAIGHT_JOIN */

# 한줄주석(비표준)

SELECT


18, 204, 206, 211, 213, 215, 217, 232, 238
1…171819

JunYoung Park

182 posts
18 categories
344 tags
RSS
© 2020 JunYoung Park
Powered by Hexo v3.6.0
|
Theme – NexT.Muse v7.1.0