Shell Options

Shell 이 동작하는 방식을 여러 옵션을 통해 컨트롤할 수가 있습니다. 옵션을 설정할 때 사용할 수 있는 명령은 setshopt 두 가지가 있는데 shopt 은 bash 전용으로 sh 에서는 사용할 수 없습니다. set 명령의 설정값은 SHELLOPTS 변수에, shopt 명령의 설정값은 BASHOPTS 변수에 각각 저장됩니다.

set 옵션의 경우에는 -e 와 같은 1 문자 옵션도 함께 제공합니다. 이것은 shebang 라인이나 직접 bash 명령을 실행할 때 사용할 수 있습니다. 다음의 네 가지 예는 모두 동일한 것입니다. shebang 라인에는 옵션을 1 개만 사용할 수 있기 때문에 -eu 와 같이 사용합니다.

#!/bin/bash -eu             #!/bin/bash                 #!/bin/bash

command ...                 set -e -u                   set -o errexit -o nounset
command ...                                             
                            command ...                 command ...
                            command ...                 command ...


$ bash -e -u -c "command ...; command ..."

set

set 명령은 두 가지 기능이 있습니다. set -f -C 와 같은 옵션 설정 기능과 set 11 22 33 와 같은 positional parameters 를 설정할 수 있는 기능입니다. 옵션을 설정할 때는 붙여서 여러 개를 한 번에 설정할 수 있고 뒤에 이어서 positional parameters 도 설정할 수 있습니다.

설정된 옵션은 $- 특수 변수에 flags 으로 저장됩니다.

$ echo $-
bhimBHs
                         # -f (noglob), -C (noclobber) 옵션을 on 하면서
$ set -f -C 11 22 33     # positional parameters 를 11 22 33 으로 설정

$ echo $-
bfhimBCHs                # "f", "C" 가 추가됨

$ [[ $- == *f* ]] && echo yes      # -f (noglob) 옵션이 설정되어 있는지 테스트
yes

$ echo $@                # positional parameters 도 설정됨
11 22 33
                         # noglob, noclobber 옵션을 off 하면서
$ set +f +C --           # positional parameters 를 전부 삭제

$ echo $-
bhimBHs

$ echo $@
$

현재 옵션 설정 상태는 set -o 명령으로 볼 수가 있습니다. 값을 on 할 때는 set -o 옵션명 을 사용하고 off 할 때는 set +o 옵션명 을 사용합니다. test -o 옵션명 으로 현재 값을 테스트해볼 수 있으며 on 일 경우는 0off 일 경우는 1 이 반환됩니다.

$ set -e -o pipefail             # -e (errexit) 옵션과 pipefail 옵션을 on 

$ test -o pipefail; echo $?      # pipefail 옵션이 설정되어 있는지 테스트
0

$ set -o | grep "errexit\|pipefail"
errexit         on
pipefail        on

$ set +e +o pipefail             # -e (errexit) 옵션과 pipefail 옵션을 off

$ [ -o pipefail ]; echo $?
1

$ set -o | grep "errexit\|pipefail"
errexit         off
pipefail        off

- -

set -- 은 현재 설정되어있는 positional parameters 들을 전부 삭제합니다.

$ set -- -a -b -c    # 인수에 '-' 문자가 포함되므로 '--' 를 사용

$ echo "$@"
-a -b -c

$ set --

$ echo "$@"          # 전부 삭제되었다.
$

-

set - 은 xtrace, verbose 옵션설정을 turn off 시킵니다.

-a | allexport

설정한 functions, variables 들이 자동으로 export 되어 child process 에서 사용할 수 있게됩니다.

-b | notify

background process 가 종료되거나 stop 되면 기본적으로 다음 프롬프트가 표시될때 메시지를 보여줍니다. 하지만 이 옵션을 설정하면 상태변경시 바로 프롬프트상에 메시지를 표시해 줍니다.

-B | braceexpand

Brace 확장을 사용합니다. 기본값입니다.

-C | noclobber

> redirection 에의해 파일이 overwriting 되지 못하게 합니다.
하지만 >| 을 사용하면 overwrite 할 수 있습니다.

$ touch foobar

$ set -C

$ echo 111 > foobar
bash: foobar: cannot overwrite existing file

$ echo $?
1

$ echo 111 >> foobar       # append 는 가능하다 
$ echo $?
0

$ echo 111 >| foobar       # '>|' 를 사용하면 overwrite 이 가능해진다.
$ echo $?
0

-e | errexit

script 실행중에 명령이 에러로 종료하면 exit 합니다.
if, while, until, ||, && 같은 분기문 에서는 예외입니다.

-E | errtrace

subshell, 명령치환, shell function 에서도 ERR trap 을 가능하게 합니다.

emacs

emacs 스타일 line editing 을 사용합니다.

-f | noglob

globbing 사용을 disable 합니다. globbing 을 회피하고자 할 때 사용할 수 있습니다

-h | hashall

명령이 사용될때 위치를 기억합니다. 기본값입니다.

-H | histexpand

! 문자를 이용한 history 확장 기능을 제공합니다. set -o history 이 설정돼있어야 사용할 수 있습니다.

history

명령 history 기능을 enable, disable 할 수 있습니다.

ignoreeof

ctrl-d 키의 명칭은 end of file 로 키보드로부터 직접 입력을 받는 명령에서 입력을 마칠때 사용합니다. 또한 프롬프트 상에서 ctrl-d 를 입력하면 exit 명령을 한것과 같이 터미널이 종료되는데 이 옵션을 설정하면 $IGNOREEOF 변수에 설정된 값을 따릅니다. ( 가령 설정값이 10 이면 10 회 ctrl-d 입력을 해야 exit 합니다. )

interactive-comments

프롬프트에서 # 코멘트를 사용할수 있습니다.

-k | keyword

command var1=val1 var2=val2 와같이 사용하며 command 에만 적용되는 일시적인 변수설정을 가능하게 해줍니다.

-m | monitor

job control 기능을 사용합니다. 스크립트 파일 실행시 이옵션은 disable 됩니다.
subshell 까지 영향이 미치지 않습니다.

-n | noexec

script 내의 명령들을 실행하지 않으므로 syntax errors 를 checking 하는 용도로 사용할수 있습니다.

nolog

현재 사용안함.

-p | privileged

shell 스크립트 파일에는 set uid 비트를 설정해도 소용이 없기 때문에 bash 프로그램 자체를 복사하여 set uid 비트를 설정해 사용할 경우를 말합니다. 실행시에는 보안을 위해 해당파일 소유자 (effective user) 의 스타트업 파일, $BASH_ENV, $ENV 파일은 처리되지 않고 현재 export 되어있는 함수들도 사용할수 없으며 SHELLOPTS, BASHOPTS, CDPATH, GLOBIGNORE 같은 변수들은 무시됩니다. suid 비트가 설정되어 있더라도 이 옵션을 주어야지 effective user id 로 실행이 되며 그렇지 않으면 real user id 로 실행됩니다.

### alice 계정 ###

alice@box:/tmp$ cp /bin/bash bash
alice@box:/tmp$ chmod u+s bash    # suid 비트 설정
alice@box:/tmp$ id
uid=1004(alice) gid=1005(gamers) groups=1004(alice),1005(gamers)

### bob 계정 ###

bob@box:/tmp$ ./bash       # suid 비트가 있지만 euid 가 설정되지 않는다.
bash-4.3$ id
uid=1002(bob) gid=1005(gamers) groups=1002(bob),1005(gamers)

bob@box:/tmp$ ./bash -p    # -p 옵션을 주어야 euid 가 설정된다.
bash-4.3$ id
uid=1002(bob) gid=1005(gamers) euid=1004(alice) groups=1002(bob),1005(gamers)

-P | physical

cd 할때 심볼릭 링크 디렉토리 구조를 따르지 않고 물리적 디렉토리 구조를 따릅니다.

# 예를들어 /usr/sys 가 /usr/local/sys 를 symbolic link 한다면

$ cd /usr/sys && echo $PWD
/usr/sys
$ cd .. && pwd
/usr

# 옵션을 설정 할경우는 :

$ cd /usr/sys && echo $PWD
/usr/local/sys
$ cd .. && pwd
/usr/local

pipefail

파이프로 연결된 명령들이 실행될때는 마지막 명령의 종료 상태 값이 true, false 를 판단하는데 사용됩니다. 하지만 이옵션을 설정하면 연결된 명령들 중에 하나라도 false 이면 false 가 됩니다.

$ true | false | true; echo $?
0

$ ( set -o pipefail;  true | false | true ); echo $?
1
-----------------------------------------------------

# pipefail 옵션을 설정하지 않으면 sed 명령에 의해 
# command1 의 실패에 상관없이 foo 함수는 항상 true 가 반환된다.
foo () 
(
    set -o pipefail
    command1 $1 $2 | sed -En '/<main>:/,/^$/p'
)

posix

POSIX 모드로 실행합니다.

-t | onecmd

옵션설정 뒤에 따라오는 명령을 실행하고 다음 프롬프트 전에 자동으로 exit 합니다.

$ set -o onecmd; command1;

-T | functrace

subshell, 명령치환, shell function 에서도 DEBUG 와 RETURN trap 을 가능하게 합니다. RETURN trap 은 기본적으로 source 한 파일이 return 했을때 발생합니다.

-u | nounset

변수 확장을 할 때 존재하지 않는 변수일 경우 에러로 간주하여 exit 합니다.

-v | verbose

실행을 위해 읽은 명령을 화면에 표시해 줍니다.

vi

vi 스타일 line editing 을 사용합니다.

-x | xtrace

명령 실행전에 매개변수확장, 명령치환, 산술확장이 완료된 결과를 보여줍니다. 디버깅에 유용하게 사용할 수 있습니다.


BASH shopt

bash 에서 사용되는 옵션입니다. 옵션값을 on 할때는 shopt -s 옵션명 , off 할때는 shopt -u 옵션명 을 사용합니다. shopt 옵션명 을 이용해 현재 값을 조회해 볼 수 있으며 on 일 경우는 0 을, off 일 경우는 1 이 반환됩니다. shopt -q 옵션명 을 이용하면 출력없이 종료 상태 값만 설정됩니다.

다음과 같이 명령 라인에서 -O 옵션명 ( O 는 대문자 ) 을 이용해 설정할 수도 있습니다.

$ bash -c 'shopt' | grep "globstar\|lastpipe"
globstar        off
lastpipe        off

$ bash -O globstar -O lastpipe -c 'shopt' | grep "globstar\|lastpipe"
globstar        on
lastpipe        on

-p 옵션은 현재 옵션 상태를 쉘에서 명령으로 사용할 수 있게 출력해 줍니다.
-o 옵션을 이용하면 shopt 옵션뿐만 아니라 set 옵션도 사용할 수 있습니다.

# 1. noglob 은 set 옵션이므로 -o 옵션을 사용.
# 2. -p 옵션은 현재 옵션 상태를 출력합니다.
$ shopt -po noglob
set +o noglob

# 다음과 같이 현재 옵션 상태를 백업하고 복구할 수 있습니다.
reset=$(shopt -po noglob)
set -o noglob 
. . .
$reset

autocd

디렉토리 이동을 위해 cd 명령을 사용할 필요 없이 디렉토리명만 입력하면 됩니다.

cdable_vars

가령 Music 디렉토리가 있고 AA 변수값이 Music 이면 cd AA 할 수 있습니다.

cdspell

cd 명령을 사용할 때 디렉토리 이름의 transposed characters, a missing character, one character too many 같은 오류를 자동으로 수정해 줍니다.

checkhash

프롬프트에서 한번 실행한 명령은 다음에 재실행시 다시 명령을 $PATH 에서 검색할 필요없이 빠르게 실행하기 위해 내부적으로 hash table 에 경로를 저장해둡니다. 현재 저장되어 있는 내용은 hash 명령으로 볼 수 있는데요. 만약에 저장되어 있는 명령이 다른 위치로 옮겨지게 되면 ($PATH 내로 옮겨지더라도) 다음에 명령 사용시 No such file or directory 오류가 납니다. 이 옵션을 사용하면 hash table 에있는 명령이 존재하지 않을 경우 다시 $PATH 검색을 하게 합니다.

checkjobs

프롬프트에서 exit 명령을 실행했을때 background job table 에 stopped 상태에 있는 job 이 있으면 There are stopped jobs 메시지를 통해 알려줍니다. 하지만 running 상태에 있는 job 은 제외되는데요. 이 옵션을 설정하면 running 상태에 있는 job 들도 메시지를 통해 알려줍니다. 연이어 exit 명령을 내리면 세션을 종료하는데 이때 stopped 상태에 있는 job 들은 함께 종료되고 running 상태에 있는 job 들은 background 로 실행을 계속하게 됩니다.

$ ping 192.168.1.1 &
[1] 1736
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.

$ shopt -s checkjobs

$ exit
exit
There are running jobs.       # running job 도 메시지를 통해 알려준다.
[1]+  Running                 ping 192.168.1.1 &

checkwinsize

명령 실행 후 window size 를 체크하여 $LINES $COLUMNS 변수값을 갱신합니다.

cmdhist

multiple-line 명령을 작성할 경우 명령 줄들이 각각 다른 history 번호로 할당돼서 다음에 재사용하기가 어려운데 이 옵션을 사용하면 newline 을 ; 로 치환해서 저장해 줍니다. lithist 옵션과 같이 사용하면 newline 도 그대로 유지됩니다.

compat31

Bash 3.1 호환모드

compat32

Bash 3.2 호환모드

compat40

Bash 4.0 호환모드

compat41

Bash 4.1 호환모드

compat42

Bash 4.2 호환모드

complete_fullquote

direxpand

경로명에 변수를 사용하면 자동완성 시에 확장됩니다.

dirspell

경로명 자동완성시 철자가 틀릴경우 수정해 줍니다. direxpand 옵션과 같이 사용.

dotglob

이 옵션을 사용하면 .filename 와 같이 점으로 시작하는 파일도 매칭에 포함시킵니다.

execfail

script 실행중에 exec 명령이 실패하면 에러메시지와 함께 script 실행이 종료됩니다. 이옵션을 사용하면 에러메시지는 기존과 같이 출력되나 script 종료는 되지 않습니다.

expand_aliases

alias 의 사용여부를 설정합니다. 기본적으로 interactive shell 에서는 on 이고 non-interactive shell 에서는 off 입니다.

extdebug

확장 DEBUG trap 모드를 활성화 합니다.

  1. DEBUG trap 함수가 0 이 아닌 값을 리턴하면 다음에 오는 명령을 스킵하고 실행하지 않습니다.

  2. DEBUG trap 함수에서 2 를 리턴하면 현재 실행 중인 함수나 source 한 스크립트에서 리턴합니다.

  3. declare -F 함수이름 을 사용하면 해당 함수가 위치한 파일 이름과 라인 번호를 알려줍니다.

  4. BASH_ARGCBASH_ARGV 값을 사용할 수 있습니다.

  5. Function tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the DEBUG and RETURN traps.

  6. Error tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the ERR trap.

extglob

Globbing 에서 확장 패턴 매칭을 사용할 수 있습니다. 기본적으로 prompt shell 에서는 enable 되지만 shell 스크립트 파일을 실행할 때는 disable 됩니다.

extquote

Parameter expansion 에서 $'string'$"string" 를 사용할수 있게합니다. 디폴트 입니다.

$ shopt -s extquote; var=""                  $ shopt -u extquote; var=""

$ echo "${var:-$"translate me"}"             $ echo "${var:-$"translate me"}"
translate me                                  me
$ echo "${var:-$'ab\ncd'}"                   $ echo "${var:-$'ab\ncd'}"
ab                                           $'ab\ncd'   # 맨앞에 $ 는 프롬프트가 아님
cd

failglob

해당 페이지 참조

force_fignore

$FIGNORE 변수에 파일 확장자를 : 로 분리해서 등록해 놓으면 filename completion 시에 제외됩니다.

globstar

** 문자를 이용하여 하위 디렉토리 까지 recursive 매칭을 할수있습니다.

$ echo **        # 모든 파일, 디렉토리
$ echo **/       # 모든 디렉토리
$ echo **/*.sh   # 확장자가 .sh 인 모든파일

globasciiranges

C locale 이 아닐 경우 [a-c] 와 같이 - 문자를 이용한 range 매칭시에 기본적으로 대, 소문자 구분을 하지 않습니다. 다시 말해 [aAbBcC] 와 같은 의미가 되는데요. 이 옵션을 설정하면 대, 소문자 구분을 합니다.

gnu_errfmt

shell 에러 메시지를 "standard GNU error message format" 으로 표시합니다.

histappend

shell 을 exit 할때 HISTFILE 변수에 설정돼 있는 파일에 현재 history list 를 append 합니다. off 이면 overwrite 합니다.

histreedit

프롬프트 에서 ! 문자를 이용한 history 확장을 사용할때 확장이 실패할 경우 입력했던 내용이 없어지지 않고 다시 수정할수 있는 기회를 줍니다.

histverify

프롬프트 에서 ! 문자를 이용한 history 확장을 사용할때 확장된 명령을 바로 실행하지 않고 필요할시 수정할수 있게 enter 를 입력할 기회를 줍니다.

hostcomplete

/etc/hosts 파일에 등록되있는 호스트이름 들의 completion 을 제공합니다.

huponexit

interactive login shell 이 exit 할때 모든 jobs 들에 HUP 시그널을 보냅니다.

interactive_comments

프롬프트에서 # 코멘트를 사용할 수 있습니다.

lastpipe

| 를 사용해서 명령을 실행할 때 단점은 연결된 명령들이 각각의 subshell 에서 실행되어 명령이 종료된 후에는 설정한 변수값을 읽을 수가 없습니다. lastpipe 옵션은 | 로 연결된 명령들 중에 마지막 명령을 현재 shell 에서 실행하게 해줍니다. 이 옵션을 사용하기 위해서는 job control (-m|monitor) 이 disable 되어있어야 합니다. non-interative shell 인 스크립트 파일 실행 시에는 기본적으로 disable 됩니다.

# read var 가 subshell 에서 실행되어 종료후 echo $var 로 값을 읽을수 없다.
$ echo hello | read var
$ echo $var 
$

$ cat ./test.sh
#!/bin/bash
shopt -s lastpipe
echo hello | read var
echo $var 

$ ./test.sh 
hello
-----------------------

$ ( shopt -s lastpipe; echo hello | read var; echo $var )
hello
--------------------------------------------------------

$ bash -O lastpipe -c 'echo hello | read var; echo $var'
hello

lithist

명령 history 옵션으로 multiple-line 명령을 작성할 경우 newline 유지해 줍니다.

login_shell

readonly 옵션으로 login shell 일경우 설정됩니다.

mailwarn

시스템에서 메일도착를 책킹한 이례로 메일을 읽은적이 있으면 "The mail in mailfile has been read" 메시지를 표시해 줍니다.

no_empty_cmd_completion

empty line 에서 자동완성 시도시 $PATH 를 검색하지 않습니다.

nocaseglob

globbing 시에 대, 소문자 구분을 하지 않습니다.

nocasematch

패턴매칭 시에 대, 소문자 구분을 하지 않습니다.

noexpand_translation

$"..." quotes 을 이용한 메시지 localization 에서 translate 된 결과는 $ 문자를 제외한 double quotes 상태가 되는데 이 옵션을 설정하면 single quotes 상태가 됩니다. ( translate 이 발생할 경우만 해당됩니다. )

nullglob

해당 페이지 참조

patsub_replacement

매개변수 확장의 패턴을 이용한 치환에서 & 문자가 매칭된 값을 가리키게 합니다. 디폴트 설정입니다.

$ CC=foobar
$ echo ${CC/f??/&-}     # "&" 문자는 f?? 패턴의 매칭값인 foo 가 된다.
foo-bar

progcomp

명령 자동완성 기능을 사용 가능하게 합니다. 디폴트 설정입니다.

progcomp_alias

명령 자동완성 기능을 사용할 때 매칭되는 자동완성 함수가 없을 경우 다시 alias 확장 결과를 명령 이름으로 사용할지 결정합니다. 디폴트는 off 입니다.

promptvars

프롬프트 스트링에 사용된 특수문자 들의 디코딩이 끝나고 나서 변수확장, 명령치환, 산술확장, quote 제거 적용을 받습니다. 기본 설정입니다.

restricted_shell

bash 가 restricted shell 일경우 설정되며 readonly 옵션입니다.

shift_verbose

shift 명령이 사용될때 shift count 가 positional parameters 수를 넘어서면 에러메시지를 프린트 합니다.

sourcepath

source 명령이 파일을 찾을때 $PATH 를 사용하게 합니다. 디폴트 설정입니다.

xpg_echo

echo 명령이 single, double quotes 모두에서 백슬래시를 이용한 escape sequences 을 사용하게 합니다.


개인마다 취향이 다르겠지만 설정해 놓으면 유용하다고 생각되는 옵션을 몇 가지 골라보았습니다.

HISTCONTROL=ignoredups
PROMPT_COMMAND='history -a'

set -o ignoreeof
set -o notify
shopt -s histappend
shopt -s histverify
shopt -s histreedit
shopt -s cmdhist
shopt -s lithist
shopt -s checkhash 
shopt -s checkjobs 
shopt -s globstar