리눅스의 Expansions and Substitutions, 특수문자

msung99·2022년 9월 17일
0
post-thumbnail
  • VirtualBox 와 Ubuntu 18.04 환경에서 진행했습니다.

Memory, Disk

  • Memory

  • Disk(디스크) : Kernal, Utility(bash, Is)

    • 커널 : 커널은 부팅될때 가장 먼저 운영채제가 메모리에 올라가도록 한다(로딩함). 내 컴퓨터가 꺼질떄까지 존재함

    • Utility(bash, Is) : On demand 한 특징을 지님. 즉, 실행시간에 캐쉬 같은것을 무시하면 로딩된다. 즉 utility 란 프로그램임

      • shell : utility 의 일종이다. 사용자로부터 입력된 명령을 읽고, 그 입력된 명령들을 interpret 해서 다른 utility 를 실행할 수 있도록 커널에 요청하는 역항을 수행한다.
        => 다른 uitlity 를 관리하기 위한 utility 라 할 수있다.

      • bash shell : 리눅스에서 대부분 사용. shell 프로그램은 On demand 하다.
        => shell 에서 $ ./a.out 과 같은 명령을 입력하면, 이 shell 프로그램이 fork 를 한다. 즉, 디스크에 있는 a.out 실행파일을 메모리에 올린다.


test.c 와 같은 실행파일을 컴파일 및 실행하면, 아래와 같이 디스크 상에 바이너리 형태의 실행파일(a.out)이 생성됨

그러고 나서 shell 에서 $ ./a.out 과 같은 명령을 입력하면, 이 shell 프로그램이 fork 를 한다. 즉, 디스크에 있는 a.out 실행파일을 메모리에 올린다.


Shell

  • 사용자로부터 입력받은 명령어를 interpret 하는 특별한 utility

  • interpret 후에 커널에게 다른 utility 를 실행할 수 있도록 요청한다.

  • 종류 : Bourne Shell, C Shell, Korn Shell, Bourne again Shell

=> Bourne Shell : 최초의 shell
Bourne again Shell : GNU 프로젝트에서 Brain Fox 라는 사람이 만듦. 대부분의 기능을 포함하고 있고, ubuntu 나 페도리와 같은 다양한 리눅스 환경에서의 디폴트 shell 이다.


Bash

  • CLI (Command Line Interpreter) => bash 는 명령어(Command Line)를 입력받고 해석 및 상호작용하는 환경이다.

쉘 명령어
$ whoamdi : 계정 정보 나옴
$ bash --version : 버전정보
$ cat /etc/shells : 현재 사용 가능한 (유효한) login shell 듷을 보여줌
$ echo $SHELL : 현재 사용중인 shell 을 보여줌


shell program

앞으로 3주차 수업동안 리눅스 쉘에서 수행가능한 다양한 명령어들과, 이런 명령어들의 묶음을 텍스트 파일로써 쉘 프로그램을 만들 것이다!

장점

  • 기존의 utility 들을 조합 및 재활용해서 빨리 생성 가능하다.
  • 사용하기 쉽다.
  • 이질적인 코드들을 adapt 시키는데 활용될 수 있다.

단점

  • 느리다.
  • 컴파일 기반이 아니라서 에러가 많이 발생할 수 있음

shell 변수

  • 쉘뿐만 아니라 많은 리눅스 utility 프로그램들은 수행에 필요한 정보(ex. 현재작업위치(Current Working Directory)) 들을 변수로써 정의해 놓았다.

  • 즉, 프로그램이 동작하는 방식에 영향을 미치는 값들의 모임

변수 에제

  • PWD : 현재 작업 위치경로를 저장
  • PATH : 명령어는 어디서 찾는지의 경로를 저장
  • HOME : home directory 를 저장

Environment 변수 (환경변수)

  • 부모 process 로부터 카피된 쉘 변수들
  • 리눅스에서 새로운 프로그램을 실행시키면, 그 쉘 프로그램도 하나의 utility 를 위한 utility 이다.

EX) "$ ./a.out" 와 같이 실행시키면,
$ => 이 쉘 프로그램이 부모 process 가 되며,
./a.out => 이 쉘 프로그램이 자식 process 가 되는것인데,

부모 process 의 쉘 프로그램 중에서 환경변수만 카피해서 전달이된다. 즉, 환경변수들은 자식 process 들에게 상속된다! (카피된다)

=> 즉, 부모 proecess 의 환경변수를 수정하게 되면, 부모 process 에게는 영향을 주지 않아도 또 다른 자식 process 에게는 영향을 준다.

Built-in environment 변수 (내장 환경변수)

  • 리눅스에서 미리 정의해둔 중요한 일부 몇개의 환경변수
  • ex. PATH, HOME, PWD

set (쉘 명령어), 쉘 변수 생성 및 값 할당 방법

  • 쉘 변수는 처음 할당시에 만들어짐.

쉘 명령어

  • $변수명 = 값 : 새로운 쉘 변수 생성 및 값 할당
  • echo $변수명 : 쉘 변수에 저장된 값 출력
  • set : 쉘 변수 목록을 확인 (모든 쉘 변수들의 변수명과 값을 출력)
  • unset 변수명 : 쉘 변수 삭제
    • 명령어1 | 명령어2 : 앞에있는 명령어의 표준출력을 다음 명령어의 표준입력으로 전달하는 기법
    • (ex. set / grep 변수명 : set을 grep 이라는 명령의 표준입력을 전달하는것이다. 이때 grep 이란 입력받은 파일 또는 입력에서 문자열을 찾는 명령어. 즉 set 에서 변수명에 해당하는 변수를 찾는다 )
  • grep : 입력받은 파일 또는 입력에서 문자열을 찾는 명령어
  • more : 리눅스에서 파일 내용을 확인하는 명령어들 중에 하나로, 파일을 읽어 화면에 화면 단위로 끊어서 출력하는 명령어
  • set more : 출력되는 쉘 변수들의 정보들을 화면 단위로 끊어서 보여줌 (엔터치면 다음 화면 단위로 넘어감)
  • type 명령어 : 어디에 위치해 있는 utility 인지 확인(경로 출력)
    (type more : utility 인 more 의 경로출력, type grep : grep 의 경로출력)

=> * 주의점
1) 빈공간(space) 를 잘못할시에 에러발생.
2) 대소문자를 구분함
3) 변수명 맨앞에는 알파벳이나 언더스코어("_") 만 올 수 있다.


export, env

environment 변수(환경변수) : 부모 process 로부터 상속받은(카피된) 변수

쉘변수는 현재 process(시점) 에서만 영향을 미치는 변수인 반면,
환경변수는 그 자식들에게 영향을 준다는 특징(상속)이 있다.

  • export 변수명 = 값 : 환경변수 생성
  • export -n 환경변수명 : 환경변수를 일반변수로 변환
  • env (또는 printenv) : 환경변수 목록을 확인 (모든 쉘 환경변수들의 변수명과 값을 출력)
  • printenv : env 와 동일한 명령어
    ( <-> set이 모든 쉘변수 목록 출력이라면, env는 쉘 환경변수 목록만 출력)
  • pstree : proecss의 상관관계(부모-자식 관계)를 트리 형태로 출력해주는 명령어로써, 관계를 트리 형태로 출력해주므로 계층 관계를 한 눈에 파악할 수 있다.
  • exit : 현재 쉘에서 나오는 것

예제

  • 중간쯤에 "$ bash" 를 해서, 자식 process 가 수행된다. 즉, sub-shell 에서 $ 이 의미하는 것은 자식 process 이다.

이떄 sub-shell 에다 일반변수 no1 는 전달이(카피가) 되지 않고, 환경변수 no2만 전달된다.

환경변수를 일반변수로 변환하기

  • export -n 환경변수명 : 환경변수를 일반변수로 변환

예제

위 그림예제에서 p 는 parent process, c 는 child process 를 의미

export -n no2 에서 환경변수 no2 는 일반변수로 변하게 되었다.
맨 마지막 child process 에서 echo no2 를 해보면 no2 가 환경변수가 아니라서, 즉 child process 에 no2 라는 변수가 존재하지 않으므로 조회가 안된다!


명령어 실습

  • env | grep no : 환경변수(env) 목록에서 no 라는 문자열 확인
  • printenv | grep no : 환경변수 목록을 확인 ( = env | grep no 와 동일한 명령)
  • env | wc -l : 라인(한 줄) 단위로 환경변수의 개수를 확인 (=> wc : word count, l : line)
  • printenv | wc -l : env | wc-l 과 동일함
  • pstree | grep bash

built-in environment variables (내장 환경변수)

  • 리눅스에서 미리 정의해둔 중요한 일부 몇개의 내장 환경변수
  • 디렉토리 명은 콜론 ":" 으로 구분된다.

종류

  • PATH : 현재 경로(디렉토리) // ex. PATH = /usr/local/sbin:/usr/ ~~
  • HOME : Home Directory // ex. HOME = /home/fos
  • PWD : Current Work Directory // ex. PWD = /home/students/common
  • BASH : 현재 사용중인 쉘 이름 // ex. BASH = /bin/bash
  • OSTYPE : OS 타입(종류) // ex. OSTYPE = Linux

ls : 현재경로에 있는 파일들
cd : 경로변경
pwd : 현재경로

PATH

cf) 기존의 PATH 에 할당된 디렉토리에 추가적인 디렉토리 정보를 추가하고 싶은 경우

  • 형태 : PATH = $PATH":추가경로"

ex. PATH = $PATH":/home/you/bin"
기존 PATH가 PATH = /home/fos/bin:home/fos/.local/bin:/usr/ ~ /games:/snap/bin 이였다면,
새롭게 지정된 PATH 는
PATH = /home/fos/bin:home/fos/.local/bin:/usr/ ~ /games:/snap/bin/home/you/bin 이 된다.

HOME

cd 명령어 : 아무 인자없이 딸랑 cd만 적으면 HOME 디렉토리로 넘어감

cf) 내장된 HOME directory 를 변경하고 싶은경우
형태: $ HOME = 새롭게 지정할 경로(디렉토리)


Expansions and Substitutions (확장과 치환)

리눅스에서 명령어를 입력시에 바로 실행되는 것이 아니다.

  • 명령어 입력시에 실행되기 이전의 과정들
  1. Bash 쉘이 먼저 command line (명령어) 를 스캔한다.

  2. 이떄 스캔시에 특별한 원소들(ex. 키워드, meta char)이 있는지 찾아보고 interpret 한 결고를 새로운 문자열 (command lone) 으로 변환한다.

=> 이러한 과정을 expanded(확장) 또는 substituted(치환) 라고 부른다.

cf) expansions 와 substitutions 의 혼용 언어 (다른 말로)

  • Parameter expansion (Variable substitution)
  • Arithmetic expansion (수식 확장)
  • Command substitution (명령어 치환)
  • Filename expansion (globbing)

Brace Expansion

  • 생성 및 출력하고자 하는 문자열들의 일정한 패턴을 가지고 문자열들을 생성하는 확장작업

  • 여러 expansion 과 substitutions 중에서 가장 먼저 일어나는 작업

  • prefix(접두사) 와 suffix(접미사) 을 이용해서 문자열들을 조합해서 확장할 수 있는 기능을 제공

  • 주의) 단일 확장인 경우, 공백이 있는 경우에는 확장이 일어나지 않는다.

  • 점 2개 ".." 를 사용해서도 사용가능 및 문자열이 생성된다. => 점 2개의 양끝에 있는 숫자는 start point 와 end point 가 된다.

    • 주의) start, end point 에는 숫자끼리 또는 문자끼리 할당되어야함. 만일
      숫자와 문자가 할당될 경우 brace expansion 이 수행되지 않는다.

ex) echo b{ed, olt, ar}s => 3개의 문자열 beds, bolts, 그리고 bars 가 생성 및 print 된다.

예제

  • echo {1} 과 같이 단일 확장일때 brace expansion 이 발생x
  • echo test{1,2} . {c.h} 와 같이 곱셈의 형태로도 문자열 생성 및 출력가능

  • echo {5..12} 와 같이 start point = 5, end point = 12를 할당해서 5 ~ 12 사이의 숫자로 구성된 문자열 생성 및 출력가능

  • echo {5..k} 와 같이 숫자와 문자를 혼용 불가능

  • 위와 같이 260 개의 문자를 명령어 한줄로써 생성가능함!

  • 괄호 {} 가 여러개 있을 때 순서대로 문자열 생성 및 출력 처리후 그 다음 문자열 생성 및 출력 하는 과정으로 이루어짐

    => 즉, 위 예제에서는 A~Z 까지 문자 생성후에 a~z 까지 문자를 생성한다.

  • brace expansion 은 항상 확장이나 치환이 가장 먼저 일어난다는 것에 유의하자!

2번쨰 줄에 "$ echo {1,2} $ A" 에서 $ A 은 변수 치환(parameter expansion) 으로, 변수 치환보다 brace expansion, 즉 확장이 먼저 일어나서 "1 $ A" 와 "2 $ A" 라는 문자열이 먼저 생성되고
그 후에 변수 치환($ A 가 foo 로 치환)이 일어나서 1foo 와 2foo 라는 문자열을 얻을 수 있다.

(cf. 변수치환은 아래에서 설명!)

이에 따라 4번째줄 $ echo $ A{1,2} 를 보면 brace expansion 이 먼저 일어남에 따라
$ A1 과 $ A2 라는 문자열이 생성되고 변수치환이 일어나서 문자열에 foo1 과 foo2 가 생성 되는데, foo1 과 foo2 라는 변수는 존재하지 않으므로 null 이 출력되는 것이다.

실습

touch 로 아래와 같이 txt 파일 생성가능


Tilde Expansion

~ : HOME 변수를 치환한 변수
~+ : PWD 변수를 치환한 변수 (Current Working Directory 를 출력)
~- : OLDPWD 변수를 치환한 변수 (Previous Working Directory, 즉 바로 직전의 작업 디렉토리를 출력)

예제

디렉토리 구조를 보면 oss 라는 디렉토리가 가 상위에 있고, 그의 아래 디렉토리로 bin, prj 라는 디렉토가 있는 상태.

또 HOME 디렉토리 = oss 인 상태이다.


Parameter Expansion (변수 치환)

  • 형태1 : $변수명
  • 형태2 : ${변수명}

$ 뒤에 변수명을 주게되면, 이 변수에 해당하는 값으로 그 값이 치환되서 다른 command 에게 전달된다.
=> 쉽게말해, 해당 변수에 대한 값으로 치환되는 것

예제

  • HOME 변수에 저장된 값은 /home/inha/oss/pr 이다.
    parameter expansion 이 발생해서 $HOME 을 하면 /home/inha/oss/pr 으로 치환 및 출력된다.

  • USER 변수, HOSTNAME 변수에 저장된 값은 inha, ubuntu 이다.
    parameter expansion 이 발생해서 ${USER} 와 ${HOSTNAME} 은 각각 inha 와 ubuntu 로 치환된다.

파라미터 (변수) 값이 정의되어 있지 않은 경우(값이 할당되어 있지 않은경우)

  • 즉, 변수값이 할당되어 있지 않거나(unset) null 이 할당되어 있는 경우
    => 이럴때 parameter expansion 을 사용해서 값을 정의해줄 수 있다.
  • 형태1 : ${변수명:-할당할 값}
    => 의미 : 이러한 "변수명" 을 가진 값으로 치환해주세요. 단, 값이 없거나(unset) null 이 할당되어 있는 경우에는 "할당할 값" 이러한 값으로 디폴트 값을 넣어주세요!

  • 형태2 : ${변수명-할당할 값}
    => unset 일때만 디퐅트 값 넣어주세요! 라는것 (null 이 할당되어 있는 경우는 디폴트 값을 넣지 않음)

  • unset 명령어 ($ unset 변수명) : 변수를 제거

OSS 변수에 값 null 이 할당된 상황이다.

$ echo ${OSS-1000} => null 이 할당된 경우는 디폴트 값을 넣지 않고 변수에 저장된 값 그대로 null 을 출력한다.


Command Substitution (명령 치환)

  • 해당 명령어의 결과물로 치환하는 것

형태1 : $(명령어)
형태2: '명령어'

예제

  • whoami 명령어 : 사용자 계정을 알려줌(출력)
    => 이 명령어를 사용하고 나온 결과값이 inha 이다.

  • hostname 명령어 : 현재 호스트 이름을 알려줌(출력)
    => 이 명령어를 사용하고 나온 결과값이 ubuntu 이다.

  • 중첩된 구조를 사용해야 하는 경우 '' 를 쓰지말고, $ 를 쓰자!
    => $ echo $(echo $(ls)) : $(ls) 가 먼저 command substitution 이 실행되고,
    그 결과값을 기반으로 $(결과값) 을 실행해서 최종 결과값인 Test.txt 로 치환된다.

  • %Y%m%d 는 출력형식을 지정하는 것


Arithmetic Expansion

  • 산술표현 결과가 문자열로 치환됨

형태1 : $((산술식))
형태2 : $[산술식]

  • bash 는 기본적으로 변수간의 연산을 문자열로 취급하기 때문에,
    c = a+b 의 결과는 30이 아니라, a+b 가 나온다.

그래서 이럴때 산수 연산을 하고 싶를때 arithmetic expression 을 사용하는 것이다.


"$" 를 이용한 연산 짬뽕

지금껏 배운 연산중 3가지는 아래와 같다.

  • ${} : Parameter Expansion
  • $(()) : Arithmetic Expansion
  • $() : Command Substitution

=> 이 3개의 연산은 모두 동시에 일어나되, 왼쪽에서 오른쪽 방향으로 연산이 수행된다.

예제

$ echo $x $((x++)) $x
=> parameter expansion 과 command expansion 이 동시에 일어났는데,
연산이 왼쪽에서 오른쪽으로 수행된다.

즉 $x 가 수행되고, $((x++)) 가 수행되고, 마지막으로 $x 가 순서대로 수행된다.


실습


Filename Expansion (파일이름 확장)

  • Wildcards (와일드 카드) : 존재하는 파일이름에서 어떤 패턴을 표현하기 위한 특별한 문자

와일드카드 종류

    • : 0개 이상의 문자들과 매칭되는 파일이름들에 대한 문자열로 확장되는 것 (현재 존재하는 working directory 안에서)
    • ex)
      • $ ls * : 현재 working directory 에 있는 파일 이름들에 대한 문자열을 출력
      • $ ls a * : a 로 시작하는 파일이름 문자열을 보여줌(출력)
      • ls * .c : .c 로 끝나는 모든 파일이름 문자열을 출력

  • ? : 모든 단일문자(문자 하나) 와 매칭되는 파일이름들에 대한 문자열로 확장하는 것
    • ex)
      • $ ls ? : 어떤 단일문자가 와도 좋으나, 딱 하나의 문자로 구성된 파일이름을 문자열로 출력
      • $ ls fo? : 파일이름이 앞에는 fo 이고, 그 뒤에 단일문자가 아무거나 와도되는 파일이름들로 구성된 문자열로 출력 (ex. 파일이름 : fo1, foo)

  • [...] : 괄호 [] 안에 둘러싸인 모든 문자중 아무 단일문자를 가지는 파일 이름들에 대한 문자열을 출력
    • $ ls [abc]* : a,b,c 중에 아무거나 맨 처음 시작문자로 가지는 파일이름들 출력 (ex. 파일이름 : aws_file, b_file)

예제

  • touch 명령어 ㅣ 파일 생성

  • ls test?.py => filename expansion 은 존재하는 파일들에 대해서만 확장되는 거싱다. 즉, 확장자 .py 를 가지는 파일이 없다면 확장되지 않음

유의사항

  • 파일이름 확장(filename expansion) 은 brace expansion 이후에 발생한다는 것을 명심하자!
    ( brace expansion 이 확장과 치환에서 가장 먼저 일어난다고 앞서 배웠었다! )

예제

  • ls test?.[c-o] : file expansion => test 로 시작하고 + c 에서 o 까지 해당하는 모든 문자에 해당하는 파일이름을 출력

  • ls test?.{c..o} : brace expansion => 가장 먼저 brace 가 된다. 즉
    test?.c 와 test?.d 와 같이 만들어놓고 이 중에서 와일드카드를 감안하여 존재하는 파일이름과 매칭된다.


Meta Characters

  • 일부문자듫에 대한 특수한 기능을 수행하도록 정의해놓았음

ex. 공백문자, tab, 개행문자 등등


Quotes (따옴표)

  • meta character 들의 특수한 기능을 없애기 위해 사용된다.

  • 따옴표 종류: " ' " '

  • 기본적으로 quotes 는 문자처리가 되서, single quotes (작은 따옴표 쌍) 을 하던 double quotes (큰 따옴표 쌍) 을 하던간에 그냥 단순하게 처리된다.

아래를 보면 그냥 문자처리 됨을 알 수 있다

그러면 언제 quotes 를 쓰는가?

아래를 보면 공백문자가 단어 사이마다 존재해서 hello 와 world 가 서로 다른 인자로써 ls 에게 전달이 된다. 즉, 각각이 서로 다른 파일로 보고 에러가 발생한다.

이럴때 따옴표로 묶어주면 하나의 인자로 ls 에 전달이 가능해진다!

아래 예제도 같은 원리로, * 가 와일드카드로 인식되지 않게 하고 싶다면 이럴때도
따옴표로 묶어주면 된다!


Quoting rules (따옴표 처리 규칙)

  • 작음 따옴표 쌍과 큰 따옴표 쌍이 meta characters 에 대해서 서로 다르게 동작한다.

  • Quoting(따옴표 처리)는 어떤 미리 정의된 특정 문자들(meta characters)의 특별한 기능을 없애고 그냥 평범한 문자로 바꿔버림

따옴표처리 종류

1) Escape character ( \ )

  • 역슬래쉬 \ 는 하나의 meta character 의 기능을 제거시킴

2) Single quote ('')

  • 작은 따옴표 안에 담긴 모든 meta character 의 기능을 제거시킴

3) Double quote ("")

  • 큰 따옴표 안에 담긴 대두분의 meta character 의 기능을 제거시킴
    단, parameter expansion(변수 확장) 과 command substitution(명령어 치환) 은 예외임.

    즉, 변수확장 과 명령어 치환은 기능이 제거되지 않고, meta character 들이 그대로 기능을 수행한다.

예제

$ touch \ * 
=> meta character 인 * 의 기능을 없앤다. 즉, * 라는 파일이름을 가진 파일을 생성함

$ touch "this is a $USER"
=> 큰 따옴표에 안에 들어있는 meta characte 인 $ 는 기능을 상싱하지 않기 떄문에, 
변수 확장(parameter expansion) 기능이 그대로 수행된다!

실습

profile
블로그 이전했습니다 🙂 : https://haon.blog

0개의 댓글