모의해킹 침해대응 과정/Linux 기초

리눅스 기초때기 5일차 쉘의 특성

알거음슴 2021. 4. 2. 18:06

1. 쉘의 특성

 - 명령어 해석기 (Command interpreter)

 - 프로그램 언어 (Programable Language) ---> 쉘 스크립트(쉘 프로그램)

 

 

2. 리다이엑션 (Redirection) < , >

 1) fd (file descriptor) : 파일 기술자 

* /proc/PDI/fd 에서 fd 확인가능. (프로세스가 실행중일때는 내용이있지만 종료시 내용이 사라짐)

* 프로세스가 파일을 열때 할당되는 번호

* 프로세스의 열린 파일을 구분할 때 사용하는 식별번호

  (1) 예약되어있는 파일 기술자 : 이미 지정되어 지정할 수 없는 fd

 0 (stdin) : 표준입력, 특별히 입력이 지정되지 않은 경우 키보드로 입력을 받는다.

 1 (stdout) : 표준 출력, 특별히 출력이 지정되지 않은 경우 출력결과를 모니터로 출력한다.

 2 (stderr) :표준 에러, 특별히 출력이 지정되지 않은경우 출력결과를 모니터로 출력한다.

 * 즉 모든 프로세서는 0,1.2번은 모두 자동으로 fd가 할당된다.

 

(2) < , > 기호 / 입력 리다이엑션, 출력 리다이엑션

 cat < etc/passwd = 입력 리다이엑션

위의 경우는 입력은 /etc/passwd 라는 파일을 입력(키보드의 기능) 받고 출력 기본값인 모니터로 출력한다.

 cat > testfile = 출력 리다이엑션

위의 경우는 입력은 기본값인 키보드로 받으나, 출력은 testfile 으로 받아두도록 하겠다.

 * CMD > file = 새로 생성하기 (overwrite)

 * CMD >> file = 이어 쓰기 (append)

 

 (3) 에러 리다이엑션 ( CMD 2> [FILE NAME])

- 에러 리다이엑션의 경우에는 fd 번호를 부여해야만 적용이 가능하다, 역시나 > 또는 >> 으로 이용가능하다.

 ex1) ls -l /test (정상출력) ls -l /nodir (애러출력) 의 경우 fd 의 부여 여부에 따른 차이.

[root@server1 /test]# ls -l /test /nodir > dirfilename1
ls: cannot access '/nodir': No such file or directory
[root@server1 /test]# cat dirfilename1 
/test:
total 4.0K
drwxrwxrwx   2 root root   45 Apr  5 10:04 .
dr-xr-xr-x. 19 root root 4.0K Apr  2 11:25 ..

 * 위의 경우에는 정상 출력내용이 dirfilename1 안에 들어가고, 에러는 모니터에 출력된것을 확인할 수 있다

ex2) ls -l /test (정상출력) ls -l /nodir (애러출력) 의 경우 fd 의 부여 여부에 따른 차이.

[root@server1 /test]# ls -l /test /nodir 2> dirfilename1
/test:
total 8.0K
drwxrwxrwx   2 root root   45 Apr  5 10:04  .
dr-xr-xr-x. 19 root root 4.0K Apr  2 11:25  ..
[root@server1 /test]# cat dirfilename1 
ls: cannot access '/nodir': No such file or directory

 * 위의 경우에는 정상 출력내용이 모니터에 출력되고애러 출력내용은 dirfilename1 들어간걸 확인할 수 있다.

[참고] 두가지 경우를 모두 활용하는법

ls /test /nodir > dirfilename 2>&1 

-> 정상출력을 dirfilename 으로 보내고 추가적으로 에러도 &1 즉 dirfilename 로 보낸다 결국 정상과 애러 모두 하나의 파일에 넣을 수 있다.

 

 (4) 주요 활용처

스크립트 실행 시 로그파일 생성 ex ) ./script.sh > file.log 2>&1

출력내용이 긴 자료를 파일을 별도로 저장하여 확인 ex) ./configure --perfix=/usr/local/apache2 > file.log 2>&1

일반사용자가 전체 파일을 검색하는경우 ( 퍼미션 때문에 에러가 많이뜸 )

ex ) find / -name core -type f 2>/dev/null

 

 

3. 파이프(Pipe) CMD | CMD

앞 CMD 를 커널버퍼에 출력하고. 커널 버퍼의 내용을 뒷 CMD 로 읽어드리게 하는 방식.

 (1) tee : 파이프 중간에 사용하여 입력을 출력으로 보내기 전에 파일로 기록.

ex) tee 를 사용하여 내용도 출력하며 출력된 내용을 파일에도 저장해보자.

[root@server1 /test]# date | tee file2.

Mon Apr  5 10:39:59 KST 2021
[root@server1 /test]# cat file2

Mon Apr  5 10:39:59 KST 2021

 

 (2) 터미널 출력 내용을 공유 하는 경우

script : 터미널에 입력한 모든 CMD와 출력내용을 특정 파일에 저장함.

script -a /dev/null | tee /dev/pts/0 | tee /dev/pts/1

tty 0 번과 tty 1번에 해당 스크립트가 실행중인 내용을 모두 공유함

 

 

4. 쉘(bash) 자체의 기능

쉘도 하나의 프로그램이기에 여러 설정과 기능들을 내장하고 있다.

set 

- 쉘 자체의 기능을 확인하고 키고 끌수 있다.

set -o : 쉘 자체의 기능 전체 목록 확인

set -o [기능이름] : 해당 기능을 ON

set +o [기능이름] : 해당 기능을 OFF

 (1) 로그아웃 (Ctrl+d) 방지 : set -o ignoreeof

set -o ignoreeof : eof 의 일부 기능을 제한시킴 (대표적인게 현제쉘의 종료기능)

eof = ctrl +d = 파일의 끝 또는 현제 쉘의 종료 의 기능 중, 쉘의 종료기능만 제한하는것임.

 (2) 덮어쓰기 (>) 방지 : set -o noclobber

리다이엑션의 기능중 > 하나만 사용시 덮어쓰기 기능이 되는데, 이 기능을 제어할 수 있음.

 

 

5. 변수

(1) 변수의 종류

 지역변수 (Local Variable) : 현재 쉘에서만 적용되는 변수 ex) VAR=5 

 환경변수 (Local Variable) : 현재뿐 아닌 서브쉘에서도 적용되는 변수 ex) export VAR=5

 특수변수 (Local Variable) : 특수목적의 변수 ex) $$, $?, $!, $0, $1, $#, $*, ....

(2) 지역변수 선언방법 ( [변수]=[변수값] )

[root@server1 ~]# var=hello
[root@server1 ~]# echo $var
hello

기본적으론 = 을 활용하여 적용한다. 또한 변수를 선언후 변수를 적용할땐 $ 기호를 활용하여 적용한다.

 (3) 환경변수 선언방법 ( [exprot] [변수] )

[root@server1 ~]# var=hello

[root@server1 ~]# export var
[root@server1 ~]# echo $var
hello
[root@server1 ~]# bash
[root@server1 ~]# echo $var
hello

 * 현재 쉘과 서브쉘에만 적용되는 사항임으로, 상위쉘 또는 다른 쉘에서는 exprot 가 되지않음.

 [참고] 시스템(쉘) 환경변수

set : 모든 변수의 대해 출력 (지역변수 환경변수 엘리어스등 모든 변수 출력)

env : 환경변수만 출력 및 시스템(쉘) 환경변수 출력.

 ex) 지역변수와 환경변수를 선언하고 내용을 확인해보자.

[root@server1 ~]# var1=cnetos
[root@server1 ~]# export var2=Linux
[root@server1 ~]# set | grep var1
var1=cnetos
[root@server1 ~]# set | grep var2
var2=Linux
[root@server1 ~]# env | grep var1
[root@server1 ~]# env | grep var2
var2=Linux

 

 (3) 시스템(쉘) 환경변수

1. PS1 변수 : 쉘 프롬프트를 정의할 때 사용하는 환경변수 = $PS1

 * ~/.bashrc 에 정의하여 변수를지속함.

2. PS2 변수 : 명령어가 아직 끝나지 않았음을 나타낼때 사용하는 프롬프트 변수 = $PS2

3. PATH 변수 : 명령어를 검색할 디렉토리를 선언 할 때 사용되는 변수 =$PATH

* 어떤 명령어를 입력 시, 쉘은 PATH 변수를 참조하여 실행한다.

[참조 : PATH 변수의 참조 순서]

1) /usr/local/bin

2) /usr/local/sbin

3) /usr/bin:/usr/sbin

4) /root/bin

순서로 디렉토리를 참조하여 해당 디렉토리에 있을 경우 그 명령어를 실행하는 방식으로 사용된다.

** vi ~/.bash_profile 파일 내에 PATH 변수의 값을 조정할 수 있음.

/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/root/bin

  1 # .bash_profile
  2 
  3 # Get the aliases and functions
  4 if [ -f ~/.bashrc ]; then
  5     . ~/.bashrc
  6 fi
  7 
  8 # User specific environment and startup programs
  9 
 10 PATH=$PATH:$HOME/bin
 11 PATH=$PATH:/test
 12 
 13 export PATH

:wq!

[root@server1 ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/root/bin:/root/bin:/test

** 이제부터는 /test에 있는 명령어 파일들도 별도 절대경로를 입력하지 않아도 실행이 가능하다.

4. HISTTIMEFORMAT 변수 : 명령어 history 기능에 시간형식을 달아줄 수 있는 변수.

 1) 기존 history 를 입력시

[root@server1 ~]# history | head
   21  ls
   22  cd
   23  cd /etc/sysconfig/network-scripts
   24  cd

 * 언제 명령어를 실행했는지 확인불가.

 2) HISTTIMEFORMAT 적용 시 (%T, %F)

exprot=HISTTIMEFORMAT"%F %T    " (etc/profile 에 선언)

-> 선언후에는 항상 telnet localhost 를 활용하여 재 로그인 해줘야한다.

* [참고] HISTTIMEFORMAT"%F %T

HISTTIMEFORMAT"%F %T 중 %F %T의 의 경우 여러 포멧들이 있다 포멧확인은 man 3 strftime 내부에 다양한 포멧을 확인 하고 원하는것으로 변경할 수 있다.

5. HOME 변수 : 사용자의 home 폴더를 지정하는 변수

6, PWD 변수 : 현제 작업 디렉토리를 정의하는 변수

7. LOGNAME 변수 : 현재 사용자의 로그인할때 이름을 정의하는 변수

8. USER 변수 : 현재 사용자의 이름이 선언된 변수

9. UID 변수 : 현재 사용자의 UID 번호가 선언된 변수

10. TERM 변수 : 터미널의 정의가 되어있는 변수

11. LANG 변수 : 현재 언어가 정의되어 있는 변수

 

 (4) 주요 특수변수

1) $ 변수 : 현재 쉘의 PID를 저장하고 있다.

 쉘 스크립트 내에서 임시 파일의 이름을 지정할때 보통 사용된다 ex) touch.tmp.$$

2) ? 변수 : 바로 이전 명령어의 정상 실행 여부의 대한 결과값이 들어있다. 

 쉘 스크립트 내에서 이전 명령어의 정상 수행 여부를 확인할 때 주로 사용된다.

 * 0일경우 정상실행 그 외의값은 오류로 정의.

3) ! 변수 : 바로 이전에 백그라운드로 실행한 프로세스의 PID 번호를 저장한다.

 쉘 스크립트 내에서 이전에 수행된 백그라운드 프로세스를 종료하는 용도로 활용

4) 인자 변수 ($#, $*, $0, $1, $2, ...)

 $0 : 프로그램 이름

 $1 : 프로그램 첫번째 인자 (argument)

 $2 : 프로그램 두번째 인자

 $* : 인자 전체 ( $1, $2, $3 .... ) 

 $# : 인자의 갯수 ( num($1, $2, $3 ...) )

 

 

6. 메타캐릭터(Metacharacter)

 

1) ' ' (작은 따옴표) : 작은 따옴표 안에 들어있는 내용을 쉘이 해석할 수 없도록 막아준다.

 단순 문자열 처리시 활용됨. ex) echo '$HOME'

2) " " (큰 따옴표) : 큰 따옴표 안에 들어있는 내용을 쉘이 해석할 수 없도록 막아준다

 * 위와 동일하나 단 인식되는 문자 도 있다. ex) $ ` ` \ 등.

3) ` ` (역 따옴표) : 쉘이 해석할때 명령어로 인식한다, 따라서 역따옴표 안의 내용을 실행한다.

4) \ (역 슬래쉬) : 바로 이후에 있는 문자를 쉘이 해석할 수 없도록 막아준다. (탈출문자)

 * \CMD 형식의 경우 CMD 자체에 내장시킨 모든 alias를 무시한체로 CMD적용 가능하다.

5) ; (세미콜론) : 한개의 라인에 여러개 명령어 수행할 때 사용된다.

 ex) ls ; date; cal = ls 별도 date 별도 cal 별도로 적용

 

[참조] 쉘의 종류

sh (본쉘) -> csh / ksh -> tcsh / zsh -> bash

 

 

7. 히스토리(History)

사용자가 입력한 명령어를 저장하기 위해서 stack 공간이 할당된다, stack의 기본공간은 1000개의 명령어를 저장가능하며. 이 저장공간을 보는 명령어가 history 이다. stack 공간은 특별한 지정이 없을경우 ~/.bash_history에 저장되며 사용자가 로그인될때마다 ~/.bash_history를 다시 불러들여 이전 명령어들의 리스트를 볼 수 있다.

 1) history 관련 환경변수.

 HISTSIZE : 히스토리를 기록하는 스택의 크기를 지정 (기본값 512개)

 HISTFILE : 히스토리 내용을 지속적으로 저장하는 파일 이름지정 (기본값 : ~/.bash_history)

 HISTFILESIZE : 히스토리 파일의 크기지정 (기본값 512개)

* history -c : stack 공간을 비워줌.

 

 

8. 엘리어스(Alias)

원하는 명령어 형식을 별칭으로 지정하여 별칭으로 이용가능

 

1. 형식

 선언 : [alias] [별칭]=['CMD']

 삭제 : [unalias] [별칭]

* alias 입력시 그동안 선언한 모든 alias 확인가능.

 

 

9. 환경파일

여러 환경 변수, 시스템 환경변수들이 선언되거나 정의되어있는 파일.

 1) 환경파일 의 종류

/etc/profile

$HOME/.bash_profile

$HOME/.bashrc

 

 2) 로그인시 환경파일이 읽어지는 순서

/etc/profile -> $HOME/.bash_profile ->$HOME/.bashrc  -> 쉘이 실행됨

* 추가 쉘 실행시 : $HOME/.bashrc -> 쉘이 실행됨

 

 3) 환경파일의 설명

/etc/profile : 해당 파일에 선언된 환경설정은 모든 사용자에게 적용되는 환경설정 가능.

$HOME/.bash_profile : 사용자가 로그인 될때만 읽혀지는 환경설정 파일

$HOME/.bashrc : 쉘이 실행될 때 마다 읽혀지는 환경설정 파일.

 

[참조] 환경 파일 분석

 /etc/profile 내부에는

     /etc/profile.d/{.sh, sh.local}

          /etc/bashrc

  -> 를 실행하라는 내용이 포함되어있음.

$HOME/.bash_profile 내부에는

     ~/. bashrc 

          /etc/bashrc

              /etc/profile.d/*.sh ( 단 선행되어 실행되면 해당부분은 실행되지않음 )

 -> 를 실행하라는 내용이 포함되어있음.

$HOME/.bashrc

     /etc/bashrc

          /etc/profile.d/*.sh

 -> 를 실행하라는 내용이 포함되어있음.

/etc/profile/*.sh 의 경우 기존에 한번 실행되면 추가적으로 실행되지 않음.