자택경비대

RE(IEEE Std 1003.2)와 BRE(Basic Regular Expression)

Programming

정규식

RE(Regulare Expression)은 한국어로 정규식이라고 불리며, POSIX.2 IEEE Std 1003.2에 정의되어 있다.

정규식은 atom이라는 주 단위를 사용하는데, 이는 다음과 같다.

()또는 [] 표현식, . (어떠한 한 글자), ^ (글자를 포함하지 않은 줄의 시작점), $ (글자를 포함하지 않은 줄의 끝 지점), \를 포함하는 ^.[$()|*+?{\ 문자, 0 부터 9 까지의 숫자를 포함하지 않은 { 문자, 혹은 다른 식별자를 포함하지 않는 문자.

문법

atom 뒤에 다음과 같은 식별자를 사용하여 표현할 수 있다.

*은 0 혹은, 그 이상의 문자와 일치하는것, +는 1 혹은 그 이상의 문자와 일치, 그리고 ?는 0 혹은 1 문자와 일치하는지를 나타낸다.

범위

{로 시작하여 정수형 숫자를 포함하고, 이후 , 가 사용될 수 있고, 다시 정수형 숫자를 포함할 수 있고, }로 끝나는 표현을 의미한다.

만약 두 숫자가 사용되었다면 , 이전의 값은 , 이후의 값을 넘어갈 수 없다.

, 없이 한 숫자만 사용되었으며 바로 }문자로 닫힌 표현식은 정확히 그 숫자의 갯수만큼이 일치함을 나타낸다.

, 뒤에 어떠한 숫자가 없이 }문자로 닫힌 표현식은 , 이전의 숫자를 i로 정의하고, , 이후의 숫자를 j로 정의할 경우, i부터 j까지의 범위의 어떠한 경우에 일치함을 나타낸다.

Bracket expression

[]로 둘러싸인 표현식을 의미하며, 일반적으로 [] 사이의 나열된 문자열에 일치함을 뜻한다. 만약 첫 글자가 ^로 시작한다면, []사이의 나열된 문자열에 불일치함을 뜻한다.

만약, 두 글자 사이에 - 문자가 사용되었다면, 그것은 두 문자 사이의 ASCII 범위를 포함하는것을 뜻하게 된다.

[::]로 둘러싸인 표현식은 사이에 character class의 이름을 사용하여 미리 정의된 범위의 문자열을 나타낼 수 있다.

character class의 내용들은 C 에서 사용되는 ctype.h의 character classification 정의들과 같다.

     
alnum digit punct
alpha graph space
blank lower upper
cntrl print xdigit

[:class:] 또한 [^로 시작되는 반대되는 개념의 일치에도 사용될 수 있다. 따라서 [^[:class:]]는 해당 character class에 포함되지 않는 문자열의 집합을 의미하게 된다.

단어의 범위를 나타내는 특별한 [[:<:]], [[:>:]] 표현식도 있다. 각각 단어의 시작, 끝부분을 나타내게 된다.

예제는 다음과 같다.

# With out bracket expression
echo 'this is island' | sed 's/is/foo/g'

thfoo foo fooland


# With bracket expression
echo 'this is island' | sed 's/[[:<:]]is[[:>:]]/foo/g'

this foo island

비식별자로서의 특수문자

문자 ]를 리스트, 즉 []에서 사용하기 위해선, 가장 처음의 문자로 두거나, 첫 문자 ^ 뒤에 바로 두면 된다.

문자 -를 리스트내에서 사용하려면, ]와 마찬가지로 가장 처음의 위치에 두거나, 가장 마지막 자리에 두면 된다.

이외에 다른 특수문자를 사용하고 싶다면 백 슬래시 \를 앞에 함께 사용하여 식별자로서의 기능을 잃게 할 수 있다.

Basic Regulare Expresion

BRE또는 Obsolete RE 라고도 불리며 현재는 대부분 하위호환성을 유지하기 위해 존재한다.

BRE에서는 +, |, ?가 일반문자로 사용된다.

향상된 정규식

perl이나 python등에서 사용되는 기능이 추가된 정규식을 뜻한다.

  • \<: 글자를 포함하지 않는 단어의 시작부분을 뜻한다. [[:<:]]와 동일하다.
  • \>: 글자를 포함하지 않는 단어의 끝부분을 뜻한다. [[:>:]]와 동일하다.
  • \b: \<\> 두가지 모두의 의미를 포함한다.
  • \B: \b와 반대되는 표현이다.

아래와 같은 줄임표현도 있다.

  • \d: [[:digit:]]과 같은 표현이다.
  • \D: \d와 반대되는 표현이다.
  • \s: [[:space:]]와 같은 표현이다.
  • \S: \s와 반대되는 표현이다.
  • \w: [[:alnum:]_]과 같은 표현이다.
  • \W: \w와 반대되는 표현이다.

2>&-, 2>/dev/null, |&, &>/dev/null and >/dev/null 2>&1 의 차이점에 대해서

stackoverflow

배경지식: 각 fd (file descriptor), 1stdout, 2stderr 그리고 0stdin 을 가리킨다.

N>&-: N에 해당하는 fd를 닫는다.
N>/dev/null: N에 해당하는 fd로 부터의 출력을 /dev/null로 리다이렉팅 한다.
N>&M: N의 출력을 M의 출력과 하나로 합친다.
|&: 2>&1 | 의 축약어이다. (bash4 버전부터 추가)
&>/dev/null: >/dev/null 2>&1 의 축약어이다.

Bash 파일 테스트 연산자

Programming
  • 아래의 조건이 일치할 경우 참을 반환한다.

-e: 파일이 존재할 경우
-a: -e 와 같다. (deprecated)
-f: 일반 적인 파일일 경우 (디렉토리, 디바이스 드라이버 파일의 경우 거짓)
-s: 파일의 크기가 0이 아닐경우
-d: 디렉토리인 경우
-b: 파일이 블록 디바이스인 경우
-c: 파일이 캐릭터 디바이스인 경우
-p: 파일이 파이프인 경우
-h, -L: 파일이 심볼릭링크인 경우
-S: 파일이 소켓인 경우
-t: fd가 터미널 디바이스와 관련이 있는경우
-r: 읽기 권한이 있는경우
-w: 쓰기 권한이 있는경우
-x: 실행 권한이 있는경우
-g: sgid 플래그가 설정되어 있는경우
-u: suid 플래그가 설정되어 있는경우
-k: stickybit가 설정되어 있는경우
-O: 파일의 소유자인 경우
-G: 파일과 같은 그룹인 경우
-N: 파일이 마지막으로 읽은 후에 수정된 경우
f1 -nt f2: f1 파일이 f2 파일보다 새로운 경우
f1 -ot f2: f1 파일이 f2 파일보다 오래된 경우
f1 -ef f2: f1 파일이 f2 파일과 같은경우 (hardlink)
!: not 연산자, 다른 연산자 앞에 쓰여서 반대 효과를 낼 수 있다.

Reference

Bash 매개변수 확장

Programming

${variable:-word}

$variable이 존재하지 않거나 null인 경우 word로 치환됩니다.

${variable:=word}

$variable이 존재하지 않거나 null일 경우 word값을 $variable에 대입하고 치환합니다.

${varaible:?word}

$variable이 존재하지 않거나 null일 경우 word 값을 stderr에 출력하고 종료합니다.

${variable:+word}

$variable이 존재하지 않거나 null일 경우 아무것도 하지 않습니다. 이외의 경우 word로 치환합니다


${variable:offset:length}

파이썬의 slice와 동일하게 동작합니다. 단, step이 존재하지 않습니다. 음수로 offset, length를 지정할 때에는 : 으로부터 공백을 추가 하는것을 권장합니다(:- 확장과 혼동할 수 있기 때문).

${!prefix*}
${!prefix@}

prefix로 시작하는 변수들을 IFS 변수로 구분하여 확장합니다.

${!variable[*]}
${!variable[@]}

$variable이 배열 변수일 경우 원소들을 IFS변수로 구분하여 확장합니다. 배열이 아니거나 null일 경우 0으로 확장합니다.

${variable#match}  # Shortest
${variable##match}  # Longtest

# e.g.)
FOO="foobarbaz"; echo ${FOO#*ba}
rbaz
FOO="foobarbaz"; echo ${FOO##*ba}
z

앞에서 부터 match와 동일한 부분을 삭제하여 확장합니다. #은 가장 짧은 경우, ##은 가장 긴 경우를 삭제합니다.

${variable%match}
${variable%%match}

# e.g.)
FOO="foobarbaz"; echo ${FOO%ba*}
foobar
FOO="foobarbaz"; echo ${FOO%%ba*}
foo

#와 같이 match되는 부분을 삭제하여 확장하지만, 뒤에서 부터 확인합니다.

${variable/pattern/word}

patternword로 치환하여 확장합니다. 만약 pattern/으로 시작할 경우 모든 패턴을 word로 치환합니다.

실행 vs 읽기 비트, 리눅스폴더에서는 어떻게 동작하나요?

stackoverflow

사용자가 폴더를 열기 위해서는 실행 비트(+x)가 설정되어 있어야 한다는 것을 깨달았습니다. 왜 실행 권한이 폴더를 읽는데 필요한건가요?


리눅스에서 폴더에 권한을 부여할 때에는, 일반 파일에 권한을 부여할 때와 차이점이 있습니다.

  • 읽기 비트(r)가 유저에게 폴더안의 파일목록을 볼 수 있도록 합니다.
  • 쓰기 비트(w)가 유저에게 파일의 생성, 이름 변경, 삭제, 그리고 폴더의 속성 변경을 가능하게 합니다.
  • 실행 비트(x)가 유저에게 폴더로 들어 올 수 있도록 하고, 내부 파일들에 접근 가능하도록 합니다.
  • Sticky 비트 (실행 비트가 설정되어 있는경우 T 혹은 t)가 폴더 내부의 파일 혹은 폴더의 삭제, 이름 변경이 소유자에 의해 가능하도록 설정합니다.

wget으로 curl 대체, curl로 wget 대체 하는 법

Programming

wget -> curl

보통은 curl이 있고 wget이 없는 경우가 더 많겠지만, 아무튼 아래와 같이 옵션인자를 줘서 해결이 가능하다.


wget -q -O- [URL]



# -q 로깅을 하지 않는다

# -O 다운로드 출력을 stdout으로 리다이렉팅 한다

curl -> wget

curl로 wget을 대체하는 방법은 좀 더 간단하다.

curl -o [FILENAME] [URL]

두개의 명령어 출력을 하나로 합치는 방법

Programming

예를 들어 echo fooecho bar, 두 개의 명령어의 출력을 하나로 합쳐서 cat으로 파이핑 하고 싶다면 아래와 같은 방법으로 해낼 수 있다.

# 방법 1
( echo foo ; echo bar ) | cat

# 방법 2
{ echo foo ; echo bar ; } | cat

Alpine Linux에서 root 유저로 권한 변경하는법

Programming

Alpine Linux에서는 sudo 명령어를 사용할 수 없기 때문에, 대신 su root 명령어를 사용하면 된다.


~$ sudo

-ash: sudo: not found

~$ su root

Password:

~# whoami

root

Alpine Linux에서 일반유저로 도커 관리하는 방법

Programming

알파인 리눅스에서는 sudo, usermod 명령어가 없기 때문에 addgroup 명령어를 사용해서 일반 유저를 도커 그룹에 추가해주어야 한다.


~# addgroup docker [USERNAME]

root 권한으로 위 명령을 실행한 뒤에 일반 로그인유저로 접속하면 된다.

혹은, ssh 등으로 이미 접속해 있는 상태였다면 로그아웃 한 뒤에 재접속 하면 해결완료.

Alpine linux ERROR: unsatisfiable constraints: docker (missing): required by: world[docker] 오류 해결방법

Programming

알파인 리눅스에서 도커를 설치하려고 할때 다음과 같은 오류가 발생하는 경우

~# apk add docker
ERROR: unsatisfiable constraints:
  docker (missing):
    required by: world[docker]
~#

아래 명령어로 repository를 추가해준뒤 apk update하여 다시 시도하면 해결된다.

~# echo "http://dl-cdn.alpinelinux.org/alpine/latest-stable/community" >> /etc/apk/repositories
~# apk update
~# apk add docker