MIT:Missing Semester - 2주차

seanlion·2021년 1월 6일
0
post-thumbnail

수업 요약

[shell]

  • shell에서도 파이썬 환경에서 코딩하듯이 변수 지정해서 출력이 가능하다.
  • 다만, shell에서는 double quote(") 와 single quote(') 의 구분이 명확하다.
    • double quote의 경우 변수의 값을 출력해준다. ex: echo "value is $foo""value is bar"
    • single quote의 경우 변수도 string으로 인식해 그대로 출력해준다. ex : echo "value is $foo""value is $foo"

[함수]

bash shell에 함수를 쓸 수 있다.

  • 파이썬 언어 등의 함수에서 쓰는 argument 개념이 여기에도 있는데, argument를 여러개 받겠다는 argv 개념을 여기서 $1 으로 쓰는 것 같다.
mcd () {
        mkdir -p "$1"
        cd "$1"
}
  • source file 이라고 터미널에 치면 해당 file을 내가 쓰고 있는 셸에서 실행시키고 로드 시키겠다 라는 뜻이다. 즉 터미널에서 [mcd.sh](http://mcd.sh) 파일에서 만든 mcd 함수를 쓸 수 있는 것이다.
  • mcd test 라고 입력하면 mcd 함수가 실행되는 것이고, test 는 argument로 들어간다. 그 argument는 $1에서 인식해서 함수를 실행시키는 것이다.
    • $는 0~9 까지 다양하고, $? 도 쓰는 것 같다.

[기타1]

  • !! (bangbang)이라는 명령어도 있다.
  • 논리 연산자도 존재한다.
    • || 은 OR, &&은 AND 개ㅐ념이다.

[기타2]

변수 안에 프로그램의 실행 결과를 담을 수도 있다. ex: foo=$(pwd)

pwd 는 현재 위치를 알려주는 프로그램인데 그 프로그램의 결과를 foo에 담는 의미이다.

[기타3]

$@ 는 모든 argument를 담는다. 프로그램 입장에선 얼마나 많은 argument가 담겨올진 모르기 때문에, 받아온 argument들을 반복문으로 처리해줄 수 있다.

[예시 스크립트]

#!/bin/bash

echo "Starting program at $(date)"
echo "Running program $0 with $# arguments with pid $$"

for file in "$@"; do
	grep foobar "$file" > /dev/null 2> /dev/null # 2>는 output stream을 하나 더 들어서 redirecting error를 함.
	if [[ "$?" -ne 0 ]]; then
		echo "File $file does not have any folder, adding one"
    echo "# foobar" >> "$file"
  fi
done

-ne는 not equal의 줄임말이다.

참고 : &1 라는걸 쓸 수도 있네.

http://minsone.github.io/shell/shell-dev-null

*.sh 라는 걸 통해 globbing이라는 개념을 배웠다.

[convert 프로그램 실습]

convert 프로그램을 사용하면 이미지 처리가 가능하다.

convert image.{png,jpg} 라는 식으로 curly bracket 안에 인자를 한꺼번에 받아서 처리할 수 있다.

  • sudo apt install imagemagick-6.q16 로 imagemagick 설치.
    • 혹은 sudo apt install imagemagick
    • imagemagick은 linux용 프로그램으로 convert를 사용할 수 있다.

[이미지 받아오기]

  • wget -qO test-image.jpg [https://c4.wallpaperflare.com/wallpaper/242/379/608/firecat-cat-fire-hd-wallpaper-preview.jpg](https://c4.wallpaperflare.com/wallpaper/242/379/608/firecat-cat-fire-hd-wallpaper-preview.jpg) 으로 아무 이미지 받아오기
    • -q0 test-image.jpg는 저 링크 파일을 test-image로 바꾸겠다는 소리.

최종 명령어 : convert test-image.{jpg,png}

Convert, Resize and Alter Images Using the Linux Convert Command

[기타4]

touch ./project{1,2}/src/test/test/{1,2,3}.py → 한번에 여러개의 파일 만들 수 있음.

폴더 간 차이 알 수 있는 명령어

diff <(ls foo) <(ls bar)

[기타5]

문법체크해주는 shellcheck 라는 프로그램도 있음. 설치 필요.

man 보다 더 TMI 방출하는 tldr을 쓰자. but 설치 필요.

현재 디렉토리 안에 있는 특정 파일을 재귀적으로 다 찾아주는 명령어 = find

예시 : find . -name src -type d

  • .은 현재 디렉토리
  • src 는 찾으려는 이름
  • d 는 찾는 타입이 디렉토리. 파일은 f

예시 : find . -name "*.tmp" -exec rm {} \;

  • tmp 확장자 가진 파일 다 찾아서 rm 실행시켜라
  • exec 커맨드의 정확한 의미:
    • Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of ; is encountered. The string {} is replaced by the current file name being processed everywhere it occurs in the arguments to the command,.

Linux shell, how to use the exec option in find with examples

[기타6]

locate missing

  • 파일 시스템 내부에 있는 missing의 경로를 전부 다 찾아준다.

[기타7]

grep 에 대해 알아보자.

  • grep은 입력으로 전달된 파일의 내용에서 특정 문자열을 찾고자할 때 사용하는 명령어입니다.
  • 문자열이 같은지(equal)만을 검사하는 수준을 넘어, 훨씬 복잡하고 다양한 방식으로, 그리고 매우 효율적으로 문자열을 찾는 기능 또한 제공.
  • 이는 grep이 파일의 문자열을 검색할 때, 단순 문자열 매칭이 아니라, **정규 표현식(Regular Expression)**에 의한 패턴 매칭(Pattern Matching) 방식을 사용하기 때문입니다.

리눅스 grep 명령어 사용법. (Linux grep command) - 리눅스 문자열 검색

history 프로그램은 이때까지 쳤던 명령어 다 보여주는 프로그램

  • history substring search : 이때까지 실행시켰던 특정 명령어 다시 돌아가서 다시 실행시키는 프로그램 같음. 검색 필요.

[기타8]

cd 대신 쓸 수 있는 auto jump 라는 것도 있음.


연습문제

  1. [man ls]를 읽고 다음과 같은 방식으로 파일을 나열하는ls 명령을 작성합니다.

    • 모든 파일 포함, 모든 숨겨진 파일 포함
    • 사이즈는 사람이 읽을 수 있을 법한 형식으로 (e.g. 454M instead of 454279954)
    • 최신순 파일 정렬
    • 색상화 되어 출력

    출력 예시는 아래와 같습니다.

    -rw-r--r--   1 user group 1.1M Jan 14 09:53 baz
    drwxr-xr-x   5 user group  160 Jan 14 09:53 .
    -rw-r--r--   1 user group  514 Jan 14 06:42 bar
    -rw-r--r--   1 user group 106M Jan 13 12:12 foo
    drwx------+ 47 user group 1.5K Jan 12 18:08 ..

    ls -alcht 으로 1차 달성

    • a는 모든 파일, 숨겨진 파일 포함.
    • l은 long listing format
    • h는 사람이 읽을 수 있을법한 형식
    • c와 t는 정렬에 필요한 아규먼트
      • c: with -lt: sort by, and show, ctime (time of last modification of file status information); with -l:
        show ctime and sort by name; otherwise: sort by ctime, newest first.
      • t : sort by modification time, newest first
    • --color=auto 하면 컬러로 보여줌.

  1. 다음을 수행하는 bash 함수marco 및polo를 작성합니다. marco를 실행할 때마다 현재 작업 디렉토리가 어떤 방식으로 저장되어야합니다. 그러면polo를 실행할 때 어떤 디렉토리에 있든 상관없이 polo 가cd를 수행해서 marco 를 실행 한 디렉토리로 돌아갑니다. 디버깅을 쉽게하기 위해marco.sh 파일에 코드를 작성하고source marco.sh를 실행하여 쉘에 정의를 (재)로드 할 수 있습니다.

    • 일단 marco 함수 만들기
      • current working directory 경로 저장하기
    • polo 함수 만들기
      • cd 'marco에 저장한 디렉토리(절대경로로 해야할듯)'
    # 파일 명 : marco.sh
    marco(){
            cwd="$(pwd)"
            echo $cwd
    }
    
    polo(){
    
            cd $cwd
    }

  1. 거의 실패하지 않는 명령이 있다고 가정 해보십시오. 그것을 디버그 하려고 출력을 캡처해야 하지만, 실패를 실행하는 데 시간이 오래 걸릴 수 있습니다. 실패 할 때까지 표준 출력 및 오류 스트림을 파일로 캡처하고 마지막에 앞의 모든 것을 출력하는 bash 스크립트를 작성하십시오. 스크립트가 실패하는 데 걸린 실행 횟수도 보고 할 수 있다면 보너스 포인트입니다.

    #!/usr/bin/env bash
    test(){
            for num in "$@"; do
                    echo "$num" >> test.txt
                    n=$(($num % 100))
                    if [[ $n -eq 0 ]]; then
                        echo "fail result: $n" 2>> test.txt
                        break
                    fi
            done
    
            cat ./test.txt
    }

    [풀이]

    • 거의 실패하지 않는 명령을 만들기 어려워서, 비정상적인 명령어 argument가 들어오면(숫자를 받아야하는데, 문자를 받는다거나) 실패한다고 간주해서 처리하는 코드를 짰다.

    • 표준 출력 및 오류 스트림을 capture to file로 하기 위해 1>2> 를 test.txt로 보낸다.

    • 마지막에 앞의 모든 것을 출력 : cat으로 출력하기


  1. 강의에서 다루었듯이find-exec는 검색하는 파일에 대한 작업을 수행하는데 매우 강력합니다. 그러나 zip 파일을 만드는 것과 같이 모든 파일로 작업을 수행하려면 어떻게해야합니까? 지금까지 본 것처럼 명령은 인수와 STDIN 모두에서 입력을받습니다. 명령을 파이핑 할 때 STDOUT을 STDIN에 연결하지만 ‘tar’와 같은 일부 명령은 인수에서 입력을받습니다.

    이러한 문제를 해결하기 위해 STDIN을 인수로 사용하여 명령을 실행하는 [xargs] 명령이 있습니다. 예를 들어ls | xargs rm은 현재 디렉토리의 파일을 삭제합니다.

    당신의 임무는 폴더에서 모든 HTML 파일을 재귀적으로 찾아서 zip 파일을 만드는 명령을 작성하는 것입니다. 파일에 공백이 있어도 명령은 작동되어야 합니다. (hint: check -d flag for xargs)

    If you’re on macOS, note that the default BSD find is different from the one included in GNU coreutils. You can use -print0 on find and the -0 flag on xargs. As a macOS user, you should be aware that command-line utilities shipped with macOS may differ from the GNU counterparts; you can install the GNU versions if you like by using brew.

    문제 쪼개기

    • 폴더의 모든 HTML 파일을 재귀적으로 찾기
      • find로 HTML 파일을 찾고
      • find /folder -name "*.html" -type f | xargs -0
    • zip 파일 만들기
      • xargs를 이용해 find의 stdout을 zip으로 만들기
      • find /folder -name "*.html" -type f | xargs -0 zip myzip.zip
      • xargs -d 를 쓰라고 한다. (delimiter = 데이터의 시작과 끝을 나타내는 문자)
      • value1 value2 value3
        • 이렇게 있으면 delimiter는 공백(space)라고 볼 수 있다.
        • By default, the delimiter of xargs is newline/space character. But you can change the delimiter character with the -d or –delimiter option of xargs.
      • gzip 프로그램을 써보자.
        • 예문 : gzip -9 {{file.ext}}
        • 숫자는 compression level. 1=Fastest (Worst), 9=Slowest (Best), Default level is 6:
    • 파일에 공백이 있어도 명령 작동하기
      • xargs -0 option도 공백 처리 해주는 건데 이건 mac os에서 가능.
      • linux에선 xargs -d '\n' 를 써보자.

    최종 명령어 : find . -name "*.html" -type f | xargs -d '\n' gzip -9


  1. (고급) 명령 또는 스크립트를 작성하여 디렉토리에서 가장 최근에 수정 된 파일을 재귀적으로 찾으시오. 그리고 모든 파일을 최신순으로 나열 할 수 있습니까?

    find와 ls를 같이 쓰면 될 것 같다.

    최종 명령어 : find $1 -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head

How to recursively find and list the latest modified files in a directory with subdirectories and times

명령어 구문 해석해보기

  • find $1 : find에서 받는 기준($1)을, 뒤에 나오는 xargs ~~ 로 받겠다.

  • stat : 파일 정보를 보여주기

    • -c --format=FORMAT
      뜻 : use the specified FORMAT instead of the default; output a newline after each use of FORMAT
    • %Y : time of last data modification, seconds since Epoch(타임스탬프인듯)
    • %y : time of last data modification, human-readable
    • %n : file name
  • sort : 파일 정렬하기
    - n : 숫자로 정렬하기
    - r : 정렬 반대로하기(기본이 오름차순인듯)

  • cut : 파일에서 필드(데이터)를 뽑아내기

    • -d 구분자 : 필드를 구분하는 문자를 지정한다. 디폴트는 탭 문자다.
    • -f 구분자 : 잘라낼 필드(데이터) 정하기 -f2- 라는건, delimiter로 구분 이후 범위를 "2번째 필드부터 끝까지"로 하겠다.
    • 여기서는 '%Y :%y %n'으로 데이터가 나오니까 -d: 로 나누면 %Y | %y %n 으로 나눠질거고 f2 가 적용되었으니 %y 부터 까지 데이터를 뽑아내겠다. 라는 의미이다.
  • head : 파일의 첫번째라인을 뽑아내겠다.

리눅스 명령어 - cut

profile
소프트웨어 엔지니어링을 연마하고자 합니다.

0개의 댓글