자택경비대

MacOS 기본 bash 쉘 버전 업그레이드 하는법

Programming

우선 Homebrew 를 이용해 최신버전의 bash를 설치한다.

brew install bash

chsh 명령어를 이용해 기본 쉘을 변경할 수 있는데, brew로 설치한 shell은 등록이 되어있지 않기 때문에 오류가 발생한다.

chsh -s $(which bash)
# chsh: /usr/local/bin/bash: non-standard shell

따라서 다음과 같이 설치된 경로를 /etc/shells 파일에 추가하여 등록한 뒤에, chsh 명령어를 사용하면 해결된다.

sudo nano /etc/shells  # which bash 명령어의 결과값을 추가한다
chsh -s $(which bash)

Password: ...

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로 치환합니다.

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

Programming

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

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

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