본문으로 이동

배시 (유닉스 셸)

위키백과, 우리 모두의 백과사전.
배시
원저자브라이언 폭스
개발자Chet Ramey
발표일1989년 6월 8일(36년 전)(1989-06-08)
안정화 버전
5.3[1] 위키데이터에서 편집하기 / 2025년 7월 3일(11개월 전)(2025년 7월 3일)
저장소
프로그래밍 언어C
운영 체제
플랫폼GNU
언어다국어 (Gettext)
종류, 유닉스 셸, 명령어 언어
라이선스
웹사이트www.gnu.org/software/bash/

배시(Bash, "본 어겐 셸/Bourne Again SHell"의 약자)는 유닉스 계열 운영체제를 위해 개발된 상호작용형 명령줄 인터프리터이자 스크립트 언어다. 1989년 GNU 프로젝트를 위해 브라이언 폭스가 제작했으며,[7] 본 셸(sh) 및 기타 독점 유닉스 셸들을 대체하기 위한 완전한 자유 소프트웨어로 설계되었고,[8] 자유 소프트웨어 재단의 지원을 받는다.[7] 배시는 널리 채택되어 수많은 리눅스 배포판에서 기본 로그인 셸로 흔히 사용된다.[9] 또한 셸 스크립트라고 불리는 파일로부터 명령어를 실행하는 기능을 지원하여 자동화를 용이하게 한다.

배시의 명령어 구문은 본 셸 구문의 상위 집합이며, 본 셸 구문의 모든 기본 기능을 복제했다. 결과적으로 배시는 대부분의 본 셸 스크립트를 수정 없이 실행할 수 있다. 그 외의 몇몇 아이디어들은 C 셸, 그 후속인 Tcsh, 그리고 콘셸에서 가져왔다. 배시는 거의 모든 현대 운영체제에서 사용할 수 있어 다양한 컴퓨팅 환경에서 다재다능한 도구로 쓰인다.

정의

[편집]

ASCII, 문자열과 숫자

[편집]

셸에 입력되는 언어는 먼저 문자 수준에서 인식되어야 한다.

POSIX 1003.1-2024, 2.10.1 Shell Grammar Lexical Conventions. The Open Group Base Specifications Issue 8, IEEE Std 1003.1-2024. 오픈 그룹. 2025년 8월 25일에 확인함. 
$ printf '<newline>:  <%b>\n' $'\n'
<newline>:  <
>
$ printf '<tab>:      <%b>\n' $'\t'
<tab>:      <	>
$ printf '<space>:    <%s>\n' " "
<space>:    < >
$ printf '<NUL>:      <%b>\n' $'\0'
<NUL>:      <>

일련의 문자들을 "문자열" 또는 "문자열 리터럴"이라고 부른다. 유닉스 계열 운영체제에서는 널 문자와 슬래시 / 같은 몇몇 문자를 제외한 출력 가능하거나 출력 불가능한 모든 문자를 파일 이름에 사용할 수 있다. 또한 모든 문자열은 대소문자를 구분한다.[10]

배시는 다른 많은 프로그래밍 언어와 마찬가지로 0부터 시작하는 번호 매기기를 사용한다.

Control+키 조합

[편집]

Control+키 기능은 GNU readline에 의해 제공되며 상호작용 모드에서만 사용할 수 있다. 특정 키 누름 조합을 통해 사용자는 탭 완성 기능을 사용하거나 명령어 기록을 검색하는 등의 배시 조작이 가능하다.

  • Tab ↹ – 탭 완성 활성화
  • – 명령어 기록에서 위로(즉, 이전으로) 스크롤
  • – 명령어 기록에서 아래로(즉, 다음으로) 스크롤
  • Ctrl+r – 명령어 기록 검색

일부 키 조합은 사용자가 터미널 창 내에서 커서를 이동하거나 에뮬레이터 프로그램을 제어하기 위해 단말 에뮬레이터를 조작할 수 있게 해준다. 기본적으로 배시의 이러한 키 조합은 이맥스의 것을 반영한다.[11]

제어 코드를 위한 기본 키 바인딩은 다음과 같다:

  • Ctrl+f – 커서를 오른쪽으로 한 글자 이동
  • Ctrl+b – 커서를 왼쪽으로 한 글자 이동
  • Alt+f – 커서를 오른쪽으로 한 단어 이동
  • Alt+b – 커서를 왼쪽으로 한 단어 이동
  • Ctrl+a – 커서를 현재 명령줄의 시작 부분으로 이동
  • Ctrl+c – 현재 명령어를 취소하고 새로운 프롬프트를 표시
  • Ctrl+d – 현재 배시 인스턴스를 종료하며, 경우에 따라 터미널 에뮬레이터도 종료
  • Ctrl+e – 커서를 현재 명령줄의 끝 부분으로 이동
  • Ctrl+q – 터미널을 깨움; 이후 버퍼링된 키 입력이 처리됨
  • Ctrl+s – 터미널을 대기 상태로 전환
  • Ctrl+w – 커서 왼쪽의 한 단어를 제거
  • Ctrl+z – 포그라운드 프로세스를 정지

Vi 키 바인딩도 사용할 수 있으며, set -o vi를 실행하여 활성화할 수 있다.[12][13]

구문

[편집]

배시가 전체 명령줄을 읽을 때, 완성된 문자열은 토큰들로 분해된다. "토큰"은 메타문자를 사용하여 식별되고 서로 분리된다.

배시 5.3 기준으로, 10개의 메타문자는 공백, 탭, 개행 문자 및 다음 문자들이다: |&;()<>

"Blanks"는 순수하게 인용되지 않은 메타문자로 구성되며, "operators"는 각각 적어도 하나의 인용되지 않은 메타문자를 포함하고, "words"는 인용되지 않은 메타문자를 포함할 수 없다.

실제로 배시는 전체 명령어 문자열을 메타문자를 포함하는 토큰 또는 토큰 그룹과, 메타문자를 포함하지 않는 토큰 또는 토큰 그룹("words"라고 불림)으로 분해한다. 거기서부터 단어들을 명령어 이름, 변수 할당문 등 더 구체적이고 의미 있는 조각들로 더 분해한다.

두 가지 공백(Blanks)은 스페이스와 탭이다.

연산자

[편집]

제어 연산자(Control operators)는 제어 기능을 수행한다. 개행 문자이거나 다음 중 하나일 수 있다: ||, &&, &, ;, ;;, ;&, ;;&, |, |&, (, 또는 ).

리다이렉션 연산자(Redirection operators)는 입력 또는 출력 스트림을 재지정한다. 여기에는 <, >, &>, <<, <<< 등이 포함된다.

단어

[편집]

단어(word)는 셸에 의해 단일 단위로 취급되는 (메타문자가 아닌) 문자들의 시퀀스다. 예약어(reserved word)는 셸에 특별한 의미를 갖는 단어의 종류다.[14] 이름(name)은 예약어와는 구별되는 단어의 종류다. 이름은 오직 문자, 밑줄, 숫자로만 구성되며, 문자나 밑줄로 시작해야 하고 숫자로 시작할 수 없다. 식별자(identifiers)라고도 불리는 이름은 변수와 함수의 이름을 짓는 데 사용될 수 있다.

문자 또는 단어일 수 있는 22개의 "예약어" 중 16개는 다음과 같다:

'!' '[[' '{' ']]' '}' case in esac for do done if then elif else fi ...

이름은 오직 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_ 문자들만 포함할 수 있다.

다음 전체 명령어 문자열의 예에서, 메타문자 위에는 쉼표 ,가, 예약어 아래에는 캐럿 ^이, 그리고 다른 토큰 아래에는 백틱 `이 표시되어 있다.

$ #,  ,    ,   ,,    ,       ,,  ,
$   if echo foo; then bar=abc; fi
$ # ^^ ```` ```  ^^^^ ```````  ^^

서브셸

[편집]

"서브셸"(subshell)은 현재 셸 인스턴스에 의해 초기화된 셸의 추가 인스턴스다. "부모" 셸이 서브셸 또는 "자식" 셸을 생성할 때, 부모의 환경 정보에 대한 정확한 복사본이 다시 생성되어 서브셸의 환경이 된다.

배시의 비산술 문맥에서는 전체 명령어 문자열을 단일 괄호로 묶어 서브셸 사용을 강제할 수 있다.

$ echo foo
foo
$ ( echo foo )
foo
$

이 간단한 사례에서는 앞의 두 명령어가 동일하지만, 서브셸의 사용은 특정 예상치 못한 부작용을 일으킬 수 있다. 서브셸의 초기화를 유발할 수 있는 다양한 형태의 구문들이 존재한다.

확장

[편집]

데이터 구조

[편집]

배시는 데이터 구조로 변수와 배열을 제공하며, 각각 다양한 종류가 존재하지만 C자바와 같은 다른 언어에 비하면 데이터 구조가 상대적으로 단순하다.[15] 모든 데이터는 메모리에 문자열로 저장된다.

단어의 시작 부분에 달러 기호를 붙이는 것은 그 단어가 변수 또는 배열의 이름임을 나타낸다. 달러/변수 이름 구문을 큰따옴표로 감싸는 것이 항상 권장된다. 이 관행은 매개변수가 보유한 값이 원치 않는 부작용을 일으키는 것을 방지한다.

변수 이름을 중괄호 {}로 감싸는 것은 가독성과 변수 및 배열 간의 일관성을 위해 권장된다. 변수를 쓸 때 중괄호는 선택 사항이지만 대괄호를 쓰는 것은 구문 오류가 된다. 매개변수 이름은 항상 등호의 왼쪽에 오고 값은 항상 오른쪽에 온다.

변수

[편집]

변수는 name=value 구문을 사용하여 할당된다.

변수를 사용하려면 $name 또는 ${name} 구문을 사용하며, 이는 변수에 할당된 값으로 확장된다.

후자의 구문은 원치 않는 부작용을 방지하기 위해 특정 이름에 반드시 사용해야 한다. 예를 들어 $10${1}0으로 파싱되므로, ${10}을 사용하는 것이 의도한 대로 파싱됨을 의미한다.

대개 배시 스크립트로 전달되는 위치 매개변수(Positional parameters)는 $0부터 시작하는 숫자가 붙은 변수로 표시된다. 특수 매개변수(Special parameters)는 구두점 문자로 표시된다.[15] 예를 들어, $@는 첫 번째부터 마지막 위치 매개변수까지의 목록으로 확장된다.

환경 변수는 모두 대문자로 표시된다. 환경 변수에는 LESS_SIGUSR1 같은 유닉스 변수와 HOME 같은 본 셸 변수가 포함된다.[15] 스크립팅 변수는 모두 소문자 또는 카멜 케이스(CamelCase)로 표시된다. 이는 관례일 뿐이며, 어떤 변수든 export 명령어로 전달하여 환경 변수로 만들 수 있다.

배열

[편집]

배열은 여러 값을 보유하는 데이터 구조다.[16] 배열은 변수 이름 끝과 중괄호 안에 한 쌍의 대괄호를 둔다. 배열을 쓸 때는 중괄호와 대괄호가 필수적이다.

배열은 name=( 요소1 요소2 ... ) 구문을 사용하여 할당된다. 사용 사례에 따라 ${quux[@]}, ${quux[*]}, 또는 ${quux[1]}를 사용하여 확장한다.

각 매개변수 종류는 특정 명명 규칙에 의해 구별된다.[15]

배시 4.0부터는 연관 배열도 지원한다.[17]

이 문서에서 이 섹션의 변수 예시로는 ${foo}, PID, PWD, EUID, $$, ${quux} , ${zork} 등이 있다.

실행

[편집]

지정된 프로그램의 "실행"은 사용자(또는 다른 프로그램)가 운영체제에 해당 프로그램에 포함된 지침에 따라 행동하도록 요청할 때 발생한다.

기본적으로 배시는 사용자 코드를 한 번에 한 줄씩 읽고, 개행 문자나 세미콜론 ;을 현재 명령어의 끝으로 해석하며, 명령어를 순차적으로 실행한다. 상호작용형 명령어가 단말 에뮬레이터의 너비를 넘어서는 경우, 보통 계속 타이핑이 가능하며 명령어는 다음 줄로 넘어간다(wrap). 명령어를 개행 문자 너머 다음 줄로 연장하려면, 첫 번째 줄의 마지막 문자가 이스케이프되지 않은 백슬래시 \여야 하며, 이는 "줄 연속"(line continuation) 신호가 된다. 배시는 항상 한 전체 명령줄의 파싱과 실행을 마친 후에 다음 명령줄의 파싱을 시작한다.

$ foo=aa bar=bb quux=cc zork=dd; set -o xtrace
$ : "${foo}"; : "${bar}"
+ : aa
+ : bb
$ : "${quux}" \
> : "${zork}"
+ : cc : dd
$

명령줄의 첫 번째 단어는 "명령어 위치"(command position)라고 알려져 있다. 유닉스 관례에 따라 명령줄의 첫 번째 단어는 항상 일종의 명령어이며, 명령줄 문자열의 나머지 단어들은 해당 명령어의 옵션, 옵션의 인자, 또는 명령어가 작동할 대상인 입력값들이다. "옵션"은 "플래그"(flags), "스위치"(switches), 또는 더 공식적으로는 "연산자"(operators)라고도 불린다. 배시가 실행할 명령어를 찾을 때 검색하는 디렉터리들은 $PATH 변수에 나열된 것들과 현재 작업 디렉터리다.[18]

$ # [COMMAND POSITION] [OPTION] [ARGUMENTS]
$ # ,--^   ,------------^   ,----^
$ declare -p USER BASH_VERSION
declare -x USER="liveuser"
declare -- BASH_VERSION="5.2.37(1)-release"
$

사용자와 PS1

[편집]

사용자 계정은 사람 또는 프로그램 사용자를 위해 생성될 수 있다. 유닉스 계열 운영체제에는 "권한이 있는"(privileged) 사용자와 "일반"(regular) 사용자의 두 종류가 있다. 루트(root)나 운영체제 커널과 같은 권한 있는 사용자는 시스템에서 무엇이든 할 수 있다. 권한이 없는 사용자는 다양한 방식으로 제한된다.

상호작용형 셸 세션이 사용자 입력을 기다릴 때, 기본적으로 화면에 특정 문자열을 출력한다. 배시에서 이 대기 문자열의 은 셸 변수 $PS1에 보관된다. 일반 사용자의 경우 $PS1의 공통 기본값은 달러 기호 $다.[a] 슈퍼유저의 경우 공통 기본값은 해시태그(#)다.

$ sudo --login --user root
[sudo] password for liveuser:
# vim /home/liveuser/names.txt
# exit
$ grep -e bob ./names.txt
grep: ./names.txt: Permission denied

모드

[편집]

프로그래밍 패러다임

[편집]

대부분의 사용자는 셸을 상호작용형 명령 인터프리터로 생각하지만, 사실 셸은 각 문장이 명령을 실행하는 프로그래밍 언어다. 명령어 실행의 상호작용 측면과 프로그래밍 측면을 모두 만족시켜야 하기 때문에, 설계만큼이나 역사에 의해 형성된 기묘한 언어이기도 하다.

배시는 C로 작성되었다. 좋은 스타일과 신중한 설계를 통해 모듈식 스타일을 근사할 수 있다.[19] 배시는 종종 명령형 프로그래밍 또는 절차적 프로그래밍 스타일로 사용된다.

상호작용 및 비상호작용 모드

[편집]

명령어 프로세서로서 배시는 상호작용 또는 비상호작용의 두 가지 모드로 작동할 수 있다. 상호작용 모드에서 명령어는 대개 단말 에뮬레이터로부터 읽어 들인다. 자동화를 용이하게 하는 비상호작용 모드에서는 명령어는 대개 오늘날 셸 스크립트라고 알려진 이름 있는 파일로부터 읽어 들인다. 명령줄 인터페이스(CLI)에서 독립형 명령어로 실행될 때, 기본적으로 배시는 상호작용 모드에서 새 셸을 연다.

스크립트

[편집]

셸 스크립트코드(종종 명령어)를 포함하는 텍스트 파일로, 추가적인 사용자 상호작용 없이 비상호작용 모드의 일괄 처리에서 특정 인터프리터에 의해 읽히고 실행되도록 의도된 것이다. 해석되는 스크립트는 소스 코드컴파일할 필요가 없는 컴퓨터 프로그램이며, 모든 관련 소스 코드가 스크립트 내에 포함되어 있다. 스크립트 인터프리터 역할을 할 수 있는 프로그램은 , AWK 등 많이 있다. 해석되는 스크립트는 유닉스 셸용으로 가장 자주 작성된다.

(실행 가능한) 셸 스크립트의 첫 번째 줄의 처음 두 문자는 셔뱅이라고 불리는 것으로 시작한다. 문자 그대로 해시태그(#)와 느낌표(!)가 나란히 붙어 있는 형태다.

$ cat ./example.sh
#! /bin/env bash
echo foo
exit

$

스크립트가 명령줄에서 독립형 프로그램으로 사용자에 의해 실행되도록 의도된 경우, 이를 "실행 파일"이라고 부른다. 관례에 따라 실행 가능한 유닉스 셸 스크립트의 파일 이름은 접미사 .sh로 식별된다. "실행" 비트는 chmod 유틸리티를 사용하여 셸 스크립트에서 활성화할 수 있다.

$ ls -l ./example.sh
-rw-r--r--.1 liveuser liveuser 32 Aug  3 22:33 example.sh
$ ./example.sh
bash: ./example.sh: Permission denied
$ chmod 0744 ./example.sh
$ ls -l ./example.sh
-rwxr--r--.1 liveuser liveuser 32 Aug  3 22:33 example.sh
$ ./example.sh
foo
$

source 내장 명령어

[편집]

source 또는 동의어인 . 명령어를 통해 배시는 이름으로 지정된 텍스트 파일로부터 셸 명령어를 읽고 실행한다.[20]

로그인 및 비로그인 셸

[편집]

배시는 --login 옵션을 통해 상호작용 및 비상호작용 모드 모두에서 로그인 셸 또는 "세션 리더"로 실행될 수 있다. "로그인"에는 사용자 인증이 필요하다. 이러한 이유로 사용자 세션당 하나의 로그인 셸만 존재한다. GNU/리눅스에서 사용자의 로그인 셸은 /etc/passwd 파일에 식별되어 있다.

$ awk -F ':' '$1 ~ /root/' /etc/passwd
root:x:0:0:Super User:/root:/bin/bash

사람 사용자가 로그인 세션을 시작할 때, 이 절차는 종종 그래픽 사용자 인터페이스(GUI)에서 발생한다. 사용자가 단말 에뮬레이터를 열 때, 에뮬레이터는 사용자의 로그인 셸의 비로그인 인스턴스를 실행한다.

단말 에뮬레이터 내에서 셸 세션을 로그아웃하는 것은 exit 명령어를 사용하거나, 배시의 기본값인 Ctrl+d를 눌러 수행할 수 있다.

시작 source 파일

[편집]

배시가 시작될 때, source를 사용하여 다양한 도트 파일(아래 목록 참조)의 명령어들을 실행한다.[21] 이 도트 파일들은 셸 스크립트와 달리 일반적으로 실행 권한이 활성화되어 있지 않으며 셔뱅도 없다. 기본적으로 배시는 다음에 따라 다소 다른 파일 세트를 다른 순서로 읽어 들인다:[22]

  • 배시가 호출되는 방식: 상호작용, 비상호작용, sh라는 이름으로 호출됨
  • 사용된 옵션: --login, --rcfile, --norc, --posix
  • 정의된 환경 변수: BASH_ENV, ENV, 그리고
  • 존재하는 파일:
    • /etc/profile
    • ~/.bash_profile
    • ~/.bash_login
    • ~/.profile
    • ~/.bash_logout, 그리고
    • 기타 ~/.bashrc 등.

물론 모든 시작 파일은 다른 파일의 명령어를 실행할 수도 있다. 시작 파일은 셸 동작, 단말 에뮬레이터, X 윈도 시스템, 창 관리자 등에 영향을 줄 수 있다.

POSIX 모드

[편집]

POSIX IEEE 1003.1 표준은 모든 셸 시스템 애플리케이션(배시, dash, zsh 등)이 준수할 수 있는 공통 정의 세트를 규정한다. POSIX 지침에 맞춰 작성된 모든 셸 사용자 스크립트(./myscript.sh)는 POSIX 사양을 구현한 모든 셸 시스템 애플리케이션에서 실행 가능해야 한다. 결과적으로 POSIX 호환 스크립트는 POSIX 표준을 구현하는 모든 유닉스 또는 유닉스 계열 운영체제(리눅스, OpenBSD, 오라클 리눅스, HP-UX 등)에서 수정 없이 성공적으로 실행될 것으로 기대할 수 있다. 이러한 스크립트들은 있는 그대로 "이식성"이 있다고 간주된다. 셸과 명령줄 유틸리티에 적용되는 POSIX 부분은 단말기와 단말 에뮬레이터가 이식성 있게 작동하기 위해 어떻게 기능해야 하는지를 추가로 규정하는 더 큰 POSIX 표준 그룹의 하위 집합이다.

배시가 POSIX 모드로 작동할 때는 사용할 수 있는 기능이 적어지지만, 결과 코드는 더 다양한 운영체제에서 실행될 수 있다.

상호작용형 셸의 초기화 시 POSIX 모드를 활성화하려면 배시를 sh, bash --posix 또는 bash -o posix로 실행하면 된다.[23] 스크립트가 POSIX 모드에서 초기화되도록 하려면 셔뱅 #! /bin/env sh 또는 이식성이 떨어지는 #!/bin/sh를 사용한다. 배시 인스턴스가 POSIX 모드에서 작동 중일 때 환경 변수 $POSIXLY_CORRECT가 정의되며, 환경 변수 SHELLOPTS의 값에 posix 문자열이 포함된다.

$ declare -p POSIXLY_CORRECT
bash: declare: POSIXLY_CORRECT: not found
$ sh
$ declare -p POSIXLY_CORRECT
declare -- POSIXLY_CORRECT="y"
$

배시에서 사용할 수 있지만 POSIX에서 규정하지 않은 기능 목록은 상당히 방대하다.[24] 다음은 그중 일부다:

  • 위치 매개변수 배열 $@를 제외한 모든 배열은 POSIX가 아님
  • 이중 대괄호 확장 테스트 구문 [[...]]은 POSIX가 아님
    • [...]test는 POSIX임
  • 이중 괄호 산술 평가 구문 중 하나인 ((...))은 POSIX가 아님
    • $((...))은 POSIX임
  • 중괄호 확장 kernel{,-headers}은 POSIX가 아님
  • 매개변수의 동적 스코핑과 local 내장 명령어는 POSIX가 아님
  • 프로세스 치환 <(...), 은 POSIX가 아님
  • 매개변수 확장 시의 특정 문자열 조작 연산은 POSIX가 아님
  • 대부분의 배시 내장 명령어는 POSIX가 아님
    • enable -s 명령어는 POSIX인 본 셸 특수 내장 명령어 목록을 출력함
      $ enable -s | wc --lines
      16
      $ enable | wc --lines
      61
      
    • enable 내장 명령어 자체는 POSIX가 아님
    • 배시의 비 POSIX 모드에서 .source 내장 명령어는 동의어임
      • 하지만 . (즉, '점') 내장 명령어는 POSIX임
      • source 내장 명령어는 POSIX가 아님
  • $EPOCHSECONDS$EPOCHREALTIME 셸 변수는 POSIX가 아님

현대 유닉스 계열 운영체제에서 사용할 수 있고 POSIX에서도 규정된 시스템 명령어들은 POSIX 환경에서 옵션 플래그가 적거나 관련 환경 변수가 적을 수 있다. 대부분(예: ls)은 배시 내장 명령어가 아니라 /bin, /usr/bin, /sbin 또는 /usr/sbin 디렉터리에 있는 독립형 프로그램(리눅스에서는 일반적으로 GNU 코어 유틸리티 또는 비지박스에 의해 제공됨)이다.

이러한 차이점들 때문에 현대(버전 5) 배시 셸 스크립트가 본 셸이나 구형 콘셸 인터프리터에서 "있는 그대로" 실행되는 경우는 드물다. GNU/리눅스가 널리 보급됨에 따라 이식성을 고려한 스크립팅은 덜 일반적이 되고 있다.[23][25]

배시에서는 유효한 구문이지만 POSIX에서는 규정되지 않은 코드를 "bashism"이라고 부른다. checkbashisms 프로그램을 사용하여 스크립트가 데비안 리눅스에서 이식성 오류 없이 실행될 수 있는지 확인할 수 있다.[26] Vidar Holen의 shellcheck하스켈로 작성된 또 다른 정적 린터로, 배시, dash, ksh, 본 셸 중 어느 하나 또는 전부에 대한 호환성을 위해 스크립트 구문을 분석할 수 있다.[27]

각 셸의 구문 요구 사항은 조금씩 다르다. 예를 들어 데비안의 정책은 스크립트에서 일부 확장 기능(dash 셸에 있는 기능 등)을 허용하는 반면,[25] Autoconfconfigure처럼 POSIX 이전의 본 셸 지원을 의도하는 스크립트는 사용할 수 있는 기능이 훨씬 더 제한적이다.[28]

기타 모드

[편집]

제한 모드

[편집]

제한된 셸은 표준 셸보다 더 엄격하게 통제된 환경을 설정하는 데 사용된다. 제한된 셸은 다음을 포함한 수많은 작업이 허용되지 않거나 수행되지 않는다는 점을 제외하면 배시와 동일하게 작동한다:

  • cd 내장 명령어로 디렉터리 변경.
  • SHELL, PATH, HISTFILE, ENV, 또는 BASH_ENV 변수의 값 설정 또는 해제.
  • CLI에서 슬래시를 포함하는 명령어 이름 지정.
  • ., history, 또는 hash -p 명령어의 인자로 절대 경로명 사용.
  • . -p 또는 command -p로 경로 검색 지정.
  • 시작 시 셸 환경으로부터 함수 정의 가져오기 및 SHELLOPTS 값 파싱.
  • >, >, <>, >&, &>, 및 >> 리다이렉션 연산자를 사용하여 출력 재지정.
  • exec 내장 명령어를 사용하여 셸을 다른 명령어로 교체.
  • 셸 내장 명령어 수정.

일반적으로 제한 모드가 활성화되면 이를 비활성화할 수 없다. 이러한 제한은 시작 파일을 읽은 후에 적용되며 셸 스크립트에는 적용되지 않는다. 제한 모드는 거의 사용되지 않는다.

권한 모드

[편집]

배시에서 "권한 모드"(privileged mode)는 SVR4.2 유닉스 시스템 V 셸(1992년경)에서 상속된 거의 사용되지 않는 옵션이다.[29] set -p로 활성화하고 set +p로 비활성화할 수 있다.[30] 권한 모드가 활성화되면 SHELLOPTS 셸 변수에 "privileged" 문자열이 포함된다.

확장 디버깅 모드

[편집]

호출 시 bash --debugger를 사용하거나 상호작용 또는 비상호작용 모드 중에 shopt -s extdebug를 통해 활성화된다. 이는 bashdb라고 불리는 별도의 프로그램을 사용한다.[31] extdebug는 POSIX 모드에서는 사용할 수 없다. 자세한 내용은 문서를 참조하라. § 디버깅 섹션도 참조하라.

호환성 모드

[편집]

배시 4.0은 shopt 내장 명령어에 대한 옵션 세트(compat31, compat32, compat40, compat41 등)로 지정되는 셸 호환성 수준의 개념을 도입했다. 현재 호환성 수준은 단 하나만 존재하며, 각 옵션은 상호 배타적이다. 호환성 수준은 사용자가 스크립트를 현재 기능과 동작을 사용하도록 마이그레이션하는 동안, 새 버전과 호환되지 않는 이전 버전의 동작을 선택할 수 있도록 하기 위한 것이다. 이는 일시적인 해결책으로 의도되었다.[32]

Bash Reference Manual, 6.12 Shell Compatibility Mode

관찰 가능성

[편집]

xtrace 옵션

[편집]

xtrace가 활성화되면 간단한 디버깅 내용이 터미널에 출력된다. set -o xtrace 또는 set -x로 활성화하고, set +o xtrace, set +x 또는 set -로 비활성화할 수 있다. 이러한 옵션들은 명령줄이나 셔뱅에서도 허용된다: #!/bin/bash -x 등.

$ bash -x
$ echo $((  2 + 2  ))
+ echo 4
4
$ set -- 1 2 3
$ printf '<%s>\n' "$@"
+ printf '<%s>\n' 1 2 3
<1>
<2>
<3>
$

xtrace 셸 설정은 POSIX에 의해 규정되어 있다. § 디버깅 섹션도 참조하라.

verbose 옵션

[편집]

verbose 옵션은 문자열이 읽힐 때, 그리고 확장이 수행되기 전에 터미널에 문자열을 출력한다. 거의 사용되지 않는다.[33]

주석

[편집]

주석은 정보를 명확히 하거나, 스크립트 작성자의 의도나 맥락을 잘 모르는 다른 사람에게 스크립트 또는 소스 파일을 설명하는 가치 있는 방법이 될 수 있다.

배시의 표준 주석은 해시 문자 #로 표시된다. 해시 오른쪽부터 줄 끝까지의 모든 텍스트는 무시된다. 인라인 주석이 허용되지만, 해시 주석은 디버깅 중에 출력되지 않는다. § xtrace를 참조하라.

콜론 문자 :로 표시되는 주석은 톰프슨 셸에서 유래했다. 콜론 : 내장 명령어의 오른쪽에 있는 모든 인자는 무시된다. 인라인 주석은 불가능하지만, 콜론 주석은 디버깅 중에 출력되며 모든 매개변수는 확장된 상태가 된다.[34]

$ # foo 정의
$ foo=bar # 인라인 해시 주석은 명령어와 같은 줄에 위치함
$ set -x
$ # 일반 주석 (출력 없음)
$ : "${foo}"
+ : bar
$

종료 코드

[편집]

배시가 명령어를 실행할 때, 프로그램이 실행을 중단한 방식에 대한 통찰을 제공할 수 있는 "반환 코드"라고도 불리는 종료 상태 코드가 생성된다. 가장 최근에 캡처된 종료 코드의 값은 셸 매개변수 '물음표' $?에 보관된다. 비산술 문맥(즉, 대부분의 경우)에서 "참"의 수치적 또는 "" 값은 0이고, "거짓"의 값은 1이다.

시스템 명령어가 실행되었을 때, 종료 상태의 의도된 의미는 대개 해당 man page에서 찾을 수 있다. 보통 0은 성공을 나타내고 0이 아닌 종료 상태는 일종의 실패 조건 또는 부분적 성공을 나타낸다. ping은 0, 1, 2라는 세 가지 의미 있는 종료 코드를 갖는 잘 알려진 명령어다.

배시 내의 산술 문맥에서는 수치적 진릿값이 반대다: "참"은 1이고 "거짓"은 0이다. 산술 문맥은 대개 ((...)) 또는 $((...)) 구문으로 식별할 수 있다. 산술 문장이 정수 0으로 평가되면 문장은 "참"으로 간주되고 종료 코드는 1이 된다. 문장이 0 이외의 숫자로 평가되면 산술 문장은 "거짓"이고 종료 코드는 0이 된다.

모든 리눅스/유닉스 명령어가 0과 1 이상의 의미 있는 종료 코드를 제공하는 것은 아니며, 리눅스에서 종료 코드 정의에 대한 표준 시스템은 없다.

$ true; echo "$?" # 종료 코드는 "참"을 의미함
0
$ false; echo "$?"; echo # 종료 코드는 "거짓"을 의미함
1
$
$ bash -c 'exit 99'; printf 'exit-code: %d\n\n' "$?"
exit-code: 99
$
$ ((  1 - 1  )); printf '%d\n' "$?" # 이 종료 코드는 "참"을 의미함
1
$ ((  1 + 1  )); printf '%d\n' "$?" # ...그리고 이 종료 코드는 "거짓"을 의미함
0

작업 제어

[편집]

배시 셸에는 명령어 실행을 위한 두 가지 모드가 있다: 배치(비동기) 및 동시(동기). 배치 모드(즉, 순차적)로 명령어를 실행하려면 문자 ;로 구분하거나 별도의 줄에 작성해야 한다:

$ 명령어1; 명령어2
$ 명령어3
$

이 예시에서 명령어1이 끝나면 명령어2가 실행되고, 명령어2가 완료되면 명령어3이 실행된다. 명령어1백그라운드 실행은 실행 명령어 끝에 기호 &를 사용하여 수행할 수 있으며, 프로세스는 백그라운드에서 실행되는 동안 즉시 셸로 제어를 반환하여 계속해서 명령어를 실행할 수 있게 한다.

$ 명령어1 &
$

또는 명령어1 명령어2를 동시에 실행하려면 배시 셸에서 다음과 같은 방식으로 실행해야 한다:

$ 명령어1 & 명령어2
$

이 경우 명령어1은 백그라운드에서 실행되어(기호 &) 셸에 즉시 제어를 반환하고, 셸은 포그라운드에서 명령어2를 실행한다. 프로세스가 포그라운드에서 실행되는 동안 Ctrl+z를 타이핑하여 프로세스를 정지시키고 배시로 제어를 반환할 수 있다.[35] 백그라운드에 있거나 정지된 모든 프로세스의 목록은 jobs를 실행하여 얻을 수 있다:

$ jobs
[1]-  Running                  명령어1 &
$

출력에서 대괄호 안의 숫자는 작업 ID(job id)를 나타낸다. 더하기 기호는 bgfg의 기본 프로세스를 나타낸다. "Running"과 "Stopped" 텍스트는 프로세스 상태를 나타낸다. 마지막 문자열은 프로세스를 시작한 명령어다.

다양한 명령어를 사용하여 프로세스의 상태를 변경할 수 있다. fg 명령어는 프로세스를 포그라운드로 가져오고, bg는 정지된 프로세스를 백그라운드에서 실행되도록 설정한다. bgfg는 작동할 프로세스를 지정하기 위해 작업 ID를 첫 번째 인자로 받을 수 있다. 작업 ID가 없으면 jobs 출력에서 더하기 기호로 표시된 기본 프로세스를 사용한다. kill 명령어는 신호를 보내 프로세스를 조기에 종료하는 데 사용될 수 있다. 작업 ID는 퍼센트 기호 뒤에 지정해야 한다:

$ sleep 100 &
[1] 4904
$ kill %1
$ jobs
[1]+  Terminated                    sleep 100
$

"모니터 모드"라고도 알려진 작업 제어는 상호작용형 셸에서 기본적으로 활성화되어 있으며, set +m로 비활성화할 수 있다.

신호

[편집]

신호 전달프로세스 간 통신(IPC)의 한 수단이다. 때때로 명령줄 프로세스가 실행 중에 멈춘 것처럼 보일 수 있다. 이런 경우 어떤 프로세스가 차단되었는지 식별하고 문제가 되는 프로세스를 수동으로 종료해야 할 수도 있다.

상호작용형 터미널에서는 대개 Ctrl-c를 눌러 현재 포그라운드 프로세스를 종료하고 사용자 프롬프트로 제어를 반환하거나, Ctrl-z를 눌러 정지시키는 것으로 충분하다. 가끔 프로세스를 취소하려는 시도가 무응답일 때 프로세스를 정지시키려는 시도는 성공하기도 한다. 다른 경우에는 IPC 신호를 보내기 위해 kill 프로그램을 사용해야 할 수도 있다. 이 예제에서는 두 번째 터미널 화면에서 kill 명령어를 사용하여 PID 4331 프로세스를 종료한다.

$ tty # 터미널 1
/dev/pts/0
$ whoami
liveuser
$ sleep 1000 # 명령어가 멈춤
$ tty # 터미널 2
/dev/pts/1
$ whoami
liveuser
$ ps aux | grep -e sleep -e PID
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START    TIME COMMAND
liveuser    4331  0.0  0.0 230336  2312 pts/1    S+   11:19    0:00 sleep 1000
liveuser    4333  0.0  0.0 231248  2516 pts/0    S+   11:19    0:00 grep --color=auto -e sleep -e PID
$ kill 4331
$ ps aux | grep -e sleep -e PID # sleep 프로세스가 종료됨
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START    TIME COMMAND
liveuser    4333  0.0  0.0 231248  2516 pts/0    S+   11:19    0:00 grep --color=auto -e sleep -e PID
$
$ tty # 다시 터미널 1
/dev/pts/0
$ whoami
liveuser
$ sleep 1000
Terminated
$

유닉스 계열 운영체제에서 사용자는 커널에 자신이 소유한 프로세스로 신호를 보내도록 지시할 수 있다. 일반 사용자는 권한이 있는 프로세스에 신호를 보낼 수 없다. 신호는 kill 내장 명령어 또는 동일한 이름의 시스템 바이너리를 사용하여 프로세스에 전달될 수 있다.

$ whoami
liveuser
$ ps aux | awk '$2 ~ /\<1\>/' # 커널 프로세스인 1번 프로세스의 정보를 봄
root           1  0.0  0.2  37140 20440 ?        Ss   04:44    0:18 /usr/lib/systemd/systemd --switched-root --system --deserialize=53 rhgb
$ kill -s SIGKILL 1
bash: kill: (1) - Operation not permitted
$ type -a kill
kill is a shell builtin
kill is /usr/bin/kill
$ /usr/bin/kill -s SIGKILL 1
kill: sending signal to 1 failed: Operation not permitted
$

가장 흔히 사용되는 신호는 kill -L | head -n 4로 확인할 수 있다. 각 IPC 신호는 신호 번호와 연관되어 있지만, 종료 코드와 신호 코드는 서로 다른 것이다. 프로세스에 IPC 신호 9("KILL" 신호)를 보내면 거의 확실히 프로세스가 즉시 종료되지만, 그렇다고 해서 프로세스가 종료 코드 9를 반환하게 될 가능성은 매우 낮다.

배시의 내장 kill은 기본적으로 TERM("종료") 신호를 보낸다. 명령줄 유틸리티가 SIGTERM에 응답하여 정상적으로 시스템을 닫고 종료하는 것은 흔한 일이다. (TERM과 SIGTERM은 동일하며, 모든 신호 이름의 SIG- 접두사는 생략할 수 있다.) 배시에서 Ctrl-c 키 시퀀스는 포그라운드 프로세스에 SIGINT(인터럽트 신호)를 보낸다. Ctrl-z 키 시퀀스는 SIGSTOP(정지 신호)를 보낸다.[36] 프로세스가 SIGKILL을 받으면 프로세스는 즉시 비정상적으로 종료된다. SIGKILL은 최후의 수단으로만 사용하는 것이 권장된다.[37] SIGKILL 신호는 차단하거나 처리할 수 없다.

프로세스는 자신이 받는 IPC 신호를 "포착"(catch)하고 "처리"(handle)할 수 있다. 사용자는 kill 내장 명령어를 사용하여 다른 프로세스에 IPC 신호를 "보낼" 수 있다. 해당 대상 프로세스는 특정 신호를 받을 때(또는 포착할 때) 어떻게 응답할지에 대한 메커니즘이나 계획을 미리 설정해 둘 수 있다. 대상 프로그램이 응답하는 방식은 프로그램이 신호 수신을 어떻게 "처리"하느냐로 지칭된다. man page를 보면 일부 시스템 명령어들이 SIGHUP를 받을 때 터미널에 특정 정보를 출력하는 것을 볼 수 있다: 예를 들어 dd 명령어가 그러하다.[38]

배시가 상호작용 모드일 때, 트랩(trap)이 없는 경우 SIGTERM을 무시하고(그래야 kill 0이 상호작용 셸을 죽이지 않음), SIGINT를 포착하고 처리한다(그래야 wait 내장 명령어를 중단할 수 있음). 배시가 SIGINT를 받으면 실행 중인 루프에서 빠져나온다. 모든 경우에 배시는 SIGQUIT를 무시한다. 작업 제어가 유효한 경우, 배시는 SIGTTIN, SIGTTOU, SIGTSTP를 무시한다.[39]

bash(1)

기본적으로 배시 셸 스크립트는 자신에게 전송된 모든 IPC 신호를 받고 응답하지만, 배시 스크립트는 trap 내장 명령어를 사용하여 신호를 포착하고 처리할 수 있다.[40]

$ cat ./trap-example.sh
#! /usr/bin/env bash
trap umask EXIT
echo bar
exit 0
$ chmod 0700 trap-example.sh
$ ./trap-example.sh
bar
0077
$

오직 배시 내에서 GNU 확장으로만 사용 가능한 몇몇 신호들이 있다: ERR, EXIT, RETURN, DEBUG. 이 신호들은 디버깅에 유용할 수 있으며 셸 내장 명령어에 의해서만 전송되고 처리될 수 있다. § 디버깅 섹션도 참조하라.

매개변수의 값

[편집]

echo의 구현 방식은 매우 다양하다. 어떤 것은 -e 옵션이 있고 어떤 것은 없다.[41] 옵션 목록은 구현마다 동일하지 않지만, echoprintf는 모두 POSIX에 의해 규정되어 있다. 스크립트 작성자가 변수에 포함된 문자열의 정확한 값을 알고 싶다면 가장 일관된 방법은 printf를 사용하는 것이다.

문자(숫자 포함)를 포함하는 모든 문자열에 대해 형식 지정자는 %s다.

$ foo=abc bar=123
$ printf '<%s>\n' "${foo}" "${bar}"
<abc>
<123>
$

숫자 전용의 경우 형식 지정자는 %d다.

$ printf '<%d>\n' "${foo}" "${bar}"
bash: printf: abc: invalid number
<0>
<123>
$

printf를 사용하면 스크립트 작성자가 형식 문자열에 개행 문자를 포함하지 않는 한 출력에 개행 문자가 절대 포함되지 않는다. 아래 예제처럼 형식 문자열에서 개행 문자가 생략된 경우, PS1의 값은 이전 명령어의 출력과 같은 줄에 출력된다.

$ printf '<%s>' "${foo}" "${bar}"
<abc><123>$

또 다른 일관된 방법은 declare -p를 사용하는 것이다. declare -p의 출력은 입력으로 재사용할 수 있다. 그러나 모든 변수와 매개변수를 declare -p로 출력할 수 있는 것은 아니다. 예를 들어 특수 매개변수의 값은 출력할 수 없다. 특수 매개변수 해시태그 "$#"는 현재 정의된 위치 매개변수가 몇 개인지 보고한다.

$ declare -p foo bar
declare -- foo="abc"
declare -- bar="123"
$ declare -p "$#"
bash: declare: 0: not found
$

상호작용형 셸의 전체 입력 문자열에 대해...

$ declare -p #

...해시태그는 배시에 의해 인라인 주석으로 해석될 것이다. 주석과 그 오른쪽의 모든 텍스트가 제거된 상태에서 배시가 실행할 명령어는 declare -p가 된다. 이 명령어는 help declare에 따르면 "각 이름의 값과 속성을 표시"하며, "이름이 주어지지 않으면 모든 변수의 속성과 값을 표시"하므로 100줄 이상의 출력이 나올 수 있다.

반면 printf는 변수의 속성을 표시할 수 없다. § 디버깅 섹션도 참조하라.

$ readonly foo
$ declare -p foo
declare -r foo="abc"
$ printf '<%s>' "${foo}"
<abc>
$

환경

[편집]

구성 가능한 실행 환경:[42]

  • ~/.bashrc~/.profile 같은 셸 및 세션 시작 파일(도트 파일);
  • 셸 동작을 변경하는 설정(set 내장 명령어) 및 셸 옵션(shopt 내장 명령어).

셸 및 세션 시작 파일(일명 "도트 파일")

배시가 시작될 때 다양한 도트 파일의 명령어를 실행한다.[21] 배시 셸 스크립트와 달리 도트 파일은 일반적으로 실행 권한이 없으며 #!/bin/bash 같은 인터프리터 지시어도 없다.

  • 레거시 호환 배시 시작 예시

아래의 ~/.bash_profile 예시는 본 셸과 호환되며 ~/.bashrc~/.bash_login에 대해 csh와 유사한 시맨틱을 제공한다. [ -r filename ] && cmd는 파일이 존재하고 읽기 가능한지 테스트하여 그렇지 않으면 && 뒤의 부분을 건너뛰는 단락 평가다.

[ -r ~/.profile ] && ~/.profile             # 환경 설정, 한 번만, 본 셸 구문 전용
if [ -n "$PS1" ]; then                      # 상호작용형인가?
   [ -r ~/.bashrc     ] && ~/.bashrc        # 상호작용형 셸을 위한 tty/프롬프트/함수 설정
   [ -r ~/.bash_login ] && ~/.bash_login    # 로그인 셸 전용 로그인 작업
fi                                          # "if" 블록 끝
  • 배시 시작 시의 운영체제 문제

일부 유닉스리눅스 버전은 일반적으로 /etc 디렉터리 아래에 배시 시스템 시작 스크립트를 포함하고 있다. 배시는 표준 초기화의 일부로 이 파일들을 실행하지만, 다른 시작 파일들은 문서화된 배시 시작 순서와 다른 순서로 이 파일들을 읽을 수도 있다. 루트 사용자의 파일 기본 내용이나 시스템이 설정 시 새 사용자 계정에 제공하는 스켈레톤(skeleton) 파일에도 문제가 있을 수 있다. X 윈도 시스템을 실행하는 시작 스크립트도 창 관리자를 실행하기 전에 사용자 환경 변수를 설정하려는 시도 중에 사용자의 배시 시작 스크립트로 예기치 않은 동작을 할 수 있다. 이러한 문제는 종종 ~/.xsession 또는 ~/.xprofile 파일을 사용하여 ~/.profile을 읽게 함으로써 해결할 수 있는데, 이는 xterm이나 그놈 단말기 같이 창 관리자에서 생성된 배시 셸 창에 필요한 환경 변수를 제공한다.

표준 스트림

[편집]

표준 스트림 - STDIN, STDOUT, STDERR

명령어

[편집]

시스템 명령어

[편집]

별칭

[편집]

별칭(Aliases)은 입력에서 단순 명령의 첫 번째 단어가 올 수 있는 위치에 있는 단어를 다른 문자열로 치환할 수 있게 한다. 별칭은 이름과 그에 상응하는 값을 가지며, alias 및 unalias 내장 명령어를 사용하여 설정하고 해제한다.

GNU Bash Reference Manual, Ch 6.6 Aliases[43][44][45][46][47]

키워드와 예약어

[편집]
  • function
    • 이 특정 키워드를 포함하는 배시 함수 선언은 본/콘/POSIX 스크립트와 호환되지 않지만, 배시는 본, 콘 및 POSIX 준수 셸에서 사용되는 함수 선언 구문도 수용한다.

함수

[편집]

셸 함수는 나중에 그룹의 단일 이름을 사용하여 실행할 수 있도록 명령어들을 그룹화하는 방법이다. 이들은 "일반적인" 단순 명령어와 똑같이 실행된다. 단순 명령어 이름으로 셸 함수의 이름이 사용되면, 셸은 그 함수 이름과 연관된 명령어 목록을 실행한다. 셸 함수는 현재 셸 컨텍스트에서 실행되며, 이를 해석하기 위해 새 프로세스가 생성되지 않는다.

 GNU Bash Reference Manual, Ch 3.3 Shell Functions[48][49][50][51][52][53]

내장 명령어

[편집]
  • 다양한 내장 명령어:
    • POSIX 특수 내장 명령어:[54]
      • cd, pwd 등.
    • set[55]
      • Xtrace: [ set -x | set -o xtrace ]. 셸의 일차적인 디버깅 수단. xtrace와 verbose는 모두 set - 명령어로 동시에 끌 수 있다.
      • Verbose: [ set -v | set -o verbose ]. 배시가 명령어를 읽을 때 터미널에 출력한다. 배시는 if-fi나 case-esac 블록을 포함하는 복합 명령어 같은 구조를 한꺼번에 읽는다. 복합 명령어 내에 set -v가 포함된 경우, "verbose"는 배시가 다음에 코드를 입력으로 읽을 때, 즉 현재 실행 중인 구조가 끝난 후에 활성화된다.[56]
      • xtrace와 verbose는 모두 set - 명령어로 동시에 끌 수 있다.
    • shopt[57]
      • expand-aliases: 상호작용 셸에서 기본적으로 켜져 있다. 일부 개발자들은 스크립트에서의 사용을 권장하지 않는다.

PATH와 시스템 명령어

[편집]

셸이 외부 명령어를 찾을 때, 본 셸 변수 $PATH에 의존한다. $PATH는 콜론 :으로 구분된 디렉터리 목록을 포함한다. 가장 왼쪽 디렉터리부터 시작하여 왼쪽에서 오른쪽 방향으로 일치하는 항목을 찾을 때까지 각 디렉터리를 검색한다. 리눅스에서 사용자가 추가 명령어를 찾을 수 있도록, 배포판 관리자와 패키지 개발자가 /etc/profile.d 및 기타 위치에 소스 파일을 포함하여 최종 사용자의 $PATH 값을 변경하는 것이 일반적인 관행이다.

예를 들어 chmod 명령어를 찾을 때, 내부 명령어를 고려한 후 아무것도 찾지 못하면 배시는 $PATH의 디렉터리들을 검색하여 검색 문자열과 일치하는 베이스 이름을 가진 첫 번째 실행 파일의 절대 경로를 선택한다.[18]

$PATH에 나열된 디렉터리에 echo 명령어가 두 개 이상 있는 경우, 명령줄을 파싱하고 실행하는 과정에서 기본적으로 첫 번째로 발견된 명령어만 선택된다. $PATH 조회는 느리다. 셸은 해시 테이블에 명령어 위치를 기억함으로써 명령줄 실행 프로세스의 속도를 높인다. 해시 테이블의 간섭 없이 전체 $PATH 검색을 수행하려면 hash -r로 현재 테이블을 제거하고 type -a로 모든 종류의 명령어를 검색한다.

$ # 전체 경로 검색 강제
$ PATH=${PATH}:${HOME}
$ printf 'echo script_file: "$@"\n' > ./echo
$ chmod 0700 ./echo
$ hash -r; type -a echo
echo is a shell builtin
echo is /usr/bin/echo
echo is /home/liveuser/echo
$

$PATH 문자열에서 나중에 발견되는 명령어로 명령줄을 실행하려면 절대 경로를 지정하거나 현재 작업 디렉터리를 기준으로 경로 해결을 고정할 수 있다.

$ /home/liveuser/echo foo
script_file: foo
$ ./echo bar
script_file: bar
$

보안상의 이유로 PATH의 디렉터리들이 누구나 쓸 수 없거나(world-writeable), 루트 및 신뢰할 수 있는 사용자만 쓸 수 있도록 하는 것이 권장된다.

명령어 조회

[편집]
  • 명령어 위치: 확장 후 명령줄 전체 텍스트의 첫 번째 단어.
  • 명령어 이름 조회가 다음 순서로 수행된다:
  • 결과 문자열이 명령어로 실행된다.

제어 구조

[편집]
참고: 조건문을 위한 제어 구조단락 평가

서브셸

[편집]

서브셸: (...);

파이프라인

[편집]

하지만 파이프라인을 사용함으로써 여러 계산 주기에 동시에 참여할 수 있어 속도를 실질적으로 높일 수 있다. 파이프라인된 제어 장치에서는 서로 다른 명령어들이 동시에 프로세스를 통과하지만 시점은 서로 다르다. 한 명령어가 인출되는 동안 두 번째 명령어는 해독되는 식이다. 유닉스 스타일 파이프라인: |.

논리 연산자

[편집]
  • AND (&&)
  • OR (||)
  • NOT (!)

배시는 이전 명령어가 설정한 종료 상태에 따라 명령어 실행을 결정하는 "조건부 실행" 명령어 구분자를 제공한다. 예를 들어:

$ cd "$SOMEWHERE" && ./do_something || echo "An error occurred" >&2

여기서 ./do_somethingcd(디렉터리 변경) 명령어가 "성공"(종료 상태 0 반환)한 경우에만 실행되고, echo 명령어는 cd 또는 ./do_something 명령어가 "오류"(0이 아닌 종료 상태 반환)를 반환한 경우에만 실행된다.

반복

[편집]

반복(ITERATION): 때때로 프로그램은 무한히 또는 특정 결과에 도달할 때까지 반복된다. 지침을 실행할 때마다 "반복"이라고 한다.[58]

  • while, until, select 루프 복합 명령어;
  • 산술 C-스타일 및 목록 열거형 for 루프 복합 명령어; 그리고
  • continue, break, return, exit 흐름 제어 명령어.

복합 명령어

[편집]

복합(compound): 요소나 부분들의 결합으로 형성된 것.[59]

Merriam-Webster's Collegiate Dictionary

배시는 또한 if ... ficase ... esac 형태의 조건부 명령어 평가를 지원한다.[c]

테스트

[편집]

파일 속성 테스트, 문자열 및 정수 값 비교 등을 위한 내장 명령어:

  • 전통적인 test 명령어,
  • 전통적인 단일 대괄호 테스트: [,
  • 현대적인 이중 대괄호 테스트: ..., 다음 고급 기능을 포함:
    • 확장 정규 표현식 및 extglob 매칭
    • <>를 사용한 사전식 비교;
  • ((...)) 수치 평가 및 테스트; 산술 및 수치 비교를 위한 거의 모든 "C" 언어 연산자를 포함함;

모든 명령어에 대해 종료 상태는 특수 변수 $?에 저장된다.

정규 표현식

[편집]

배시 3.0은 을 연상시키는 구문을 사용하여 프로세스 내 정규 표현식 매칭을 지원한다.[61] 정규식 매칭은 [[..]] 확장 테스트 구문 내의 =~ 연산자 오른쪽에 있는 문자열로 제한된다.[62]

[[ $line =~ [[:space:]]*(a)?b ]]는 line의 값이 'aab', ' aaaaaab', 'xaby', ' ab'인 경우 모두 일치하며, 값의 어디든 'b'를 포함하는 줄과도 일치함을 의미한다.

코프로세스

[편집]

코프로세스(coprocess)는 coproc 예약어가 앞에 붙은 셸 명령어다. 코프로세스는 서브셸에서 비동기적으로 실행되며, 마치 명령어가 '&' 제어 연산자로 끝난 것처럼 작동하며, 실행 중인 셸과 코프로세스 사이에 양방향 파이프가 설정된다.[63]

Bash Reference Manual, 3.2.6 Coprocesses

데이터 조작

[편집]

단어 분할

[편집]

단어로 분리 (즉, 단어 분할)

인용

[편집]

의심스러울 때는 -- 인용하라![64]

Mastering Linux Shell Scripting, by Andrew Mallett

배시는 특정 인용 규칙을 갖는다:

  • 단일 인용부호 '...'
  • 이중 인용부호 "..."
  • 백슬래시 \
  • ANSI-C 인용 $'...'

§ 로캘, $"..."도 참조하라.

백틱 `...`: § 지원 중단된 구문도 참조하라.

유니코드

[편집]

echo -e 및 ANSI-C 인용에서의 유니코드 지원.

중괄호 확장

[편집]
$ echo kernel{,-headers}
kernel kernel-headers

교체라고도 불리는 중괄호 확장은 C 셸에서 복제된 기능이다. 이는 대안적인 조합 세트를 생성한다.[65] 생성된 결과가 파일로 존재할 필요는 없다. 각 확장된 문자열의 결과는 정렬되지 않으며 왼쪽에서 오른쪽 순서가 유지된다:

$ echo a{p,c,d,b}e
ape ace ade abe
$ echo {a,b,c}{d,e,f}
ad ae af bd be bf cd ce cf

본 셸은 동일한 출력을 생성하지 않으므로 사용자는 이식 가능한 셸 스크립트에서 중괄호 확장을 사용해서는 안 된다.

$ # 배시 셸
$/bin/bash -c 'echo a{p,c,d,b}e'
ape ace ade abe
$ # 전통적인 셸은 동일한 출력을 생성하지 않음
$ /bin/sh -c 'echo a{p,c,d,b}e'
a{p,c,d,b}e

중괄호 확장이 와일드카드와 결합되면 중괄호가 먼저 확장된 다음 결과 와일드카드가 정상적으로 대체된다. 따라서 현재 디렉터리의 JPEG 및 PNG 이미지 목록은 다음을 사용하여 얻을 수 있다:

ls *.{jpg,jpeg,png}    # *.jpg *.jpeg *.png로 확장된 후,
                       # 와일드카드가 처리됨
echo *.{png,jp{e,}g}   # echo는 확장 결과만 보여줌 –
                       # 중괄호 안의 중괄호도 가능함.

교체 외에도 중괄호 확장은 마침표 두 개로 구분된 두 정수 또는 문자 사이의 순차적 범위에 사용할 수 있다. 최신 버전의 배시에서는 증분 값을 지정하기 위해 세 번째 정수를 허용한다.

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
$ echo {01..10}
01 02 03 04 05 06 07 08 09 10
$ echo file{1..4}.txt
file1.txt file2.txt file3.txt file4.txt
$ echo {a..e}
a b c d e
$ echo {1..10..3}
1 4 7 10
$ echo {a..j..3}
a d g j

중괄호 확장이 변수 확장(일명 매개변수 확장 및 매개변수 치환)과 결합될 때, 변수 확장은 중괄호 확장 이후에 수행되며, 이는 경우에 따라 eval 내장 명령어의 사용을 필요로 할 수 있다:

$ start=1; end=10
$ echo {$start..$end} # 평가 순서 때문에 확장에 실패함
{1..10}
$ eval echo {$start..$end} # 변수 확장이 발생한 후 결과 문자열이 평가됨
1 2 3 4 5 6 7 8 9 10

틸드 확장

[편집]

매개변수 및 변수 확장

[편집]
  • 유형
  • 셸 매개변수
  • 환경 변수
  • 사용자 변수
  • 스코프
  • 배열
  • 매개변수 확장
    외부 유틸리티보다 특정 작업을 더 빠르게 수행할 수 있는 확장 구문들(일부 예시):
    • 패턴 치환
      • ${foo//x/y} (sed 's/x/y/g' 대용),
    • 일치하는 접두사 또는 접미사 패턴 제거
      • ${bar##[a-zA-Z0-9]*} (cut -c8- 대용),
    • 배열 키 열거
      • ${!array[@]}, 그리고
    • Null이거나 설정되지 않은 경우 오류 표시
      • ${var:?error message},

경로명 확장

[편집]

경로명 확장, 즉 *, ?, [...]를 사용한 셸 스타일 글로브패턴 매칭.[f]

로캘

[편집]

$"..." 인용 구문을 통한 로캘별 번역.[69]

프로세스 리다이렉션 및 파싱

[편집]

명령어 치환

[편집]

명령어 치환: $(...),

프로세스 치환

[편집]

프로세스 치환, <() 또는 >() (시스템이 지원하는 경우):

배시는 <(command)>(command) 구문을 사용한 프로세스 치환을 지원하며, 이는 일반적으로 파일 이름이 사용되는 위치에 명령어의 출력(또는 입력)을 대체한다. (이는 지원하는 시스템에서 /proc/fd/ 무명 파이프를 통해, 또는 필요한 경우 임시 명명된 파이프를 통해 구현된다.)

산술 확장

[편집]

산술 확장, ((...)) 또는 $((...)), 다음을 포함:

  • 2에서 64까지의 임의의 을 가진 정수 산술, 다만
  • 부동소수점 산술은 셸 자체 내에서는 사용할 수 없다(이 기능에 대해서는 최신 버전의 bcawk 등을 참조).

배시는 외부 프로세스를 생성하지 않고도 정수 계산("산술 평가")을 수행할 수 있다. 이를 위해 ((...)) 명령어와 $((...)) 변수 구문을 사용한다.

리다이렉션

[편집]

표준 입력, 표준 출력 및 표준 오류 데이터 스트림리다이렉션이 수행된다. 다음을 포함:

  • 파일 쓰기, >, 및 추가, >>,
  • 히어 도큐먼트, <<,
  • 매개변수를 입력으로 사용할 수 있게 하는 히어 스트링, <<<, 그리고
  • 셸의 noclobber 설정이 활성화되어 있을 때 파일 덮어쓰기를 강제할 수 있는 리다이렉션 연산자 >|.

배시의 구문은 입출력 리다이렉션을 단순화한다. 예를 들어, &> 연산자를 사용하여 표준 출력표준 오류를 동시에 재지정할 수 있다. 이는 본 셸의 상응하는 방식인 'command > file 2>&1'보다 입력하기 쉽다. 배시는 히어 도큐먼트를 지원한다. 버전 2.05b부터 배시는 <<< 연산자를 사용하여 "히어 스트링"으로부터 표준 입력을 재지정할 수 있다.

명령어 파싱

[편집]
  • (A) 인용되지 않은 #(해시)부터 같은 줄 끝까지의 주석은 무시된다;[70][71]
  • (B) 명령어는 한 번에 한 줄씩 파싱된다:
    • 제어 구조가 존중된다.
    • 줄 끝에서의 백슬래시 \ 이스케이프도 존중된다.
  • (C) 인용 규칙에 따라 단어로 분리된다(즉, 단어 분할).
    • ANSI-C 인용 $'...'을 포함한다.
  • (D) 결과 문자열에 대해 다음 순서로 일곱 가지 유형의 확장이 수행된다:
    1. (유형 1) 중괄호 확장 kernel{-headers},
    2. (유형 2) 틸드 확장 ~,
    3. 왼쪽에서 오른쪽 방향으로:
    4. 다시 단어 분할이 수행된다.
    5. (유형 7) 경로명 확장, 즉 *, ?, [...]를 사용한 셸 스타일 글로브패턴 매칭.[f]
    6. 인용부호 제거.
  • (E) 표준 입력, 표준 출력 및 표준 오류 데이터 스트림리다이렉션이 수행된다. 다음을 포함:
    • 파일 쓰기, >, 및 추가, >>,
    • 히어 도큐먼트, <<,
    • 히어 스트링, <<<, 그리고
    • 리다이렉션 연산자 >|.
  • (F) 명령어 이름 조회가 다음 순서로 수행된다:
    1. 셸 내부 명령어:
    2. 셸 외부 명령어:
  • (G) 결과 문자열이 명령어로 실행된다.

상호작용 전용 기능

[편집]

명령어 기록

[편집]

무제한 크기의 명령어 기록.[72] 이 기능은 상호작용 모드에서만 사용할 수 있다.

디렉터리 스택

[편집]

디렉터리 스택(pushdpopd 내장 명령어) 기능은 상호작용 모드에서만 사용할 수 있다.

프로그래밍 가능한 완성

[편집]

"탭 완성" 또는 "명령줄 자동 완성"이라고도 알려진 이 기능은 사용자가 상호작용형 명령 셸 내에서 Tab을 누를 때, 배시가 사용 가능한 완성 스크립트를 자동으로 사용하여 부분적으로 입력된 프로그램 이름, 파일 이름 및 변수 이름을 제안하는 기능이다.[73][4] 배시의 명령줄 완성 시스템은 매우 유연하고 사용자 정의가 가능하며, 종종 특정 프로그램 및 작업을 위한 인자와 파일 이름을 완성하는 함수와 함께 패키징된다.

배시는 내장된 complete, compopt, compgen 명령어를 통해 프로그래밍 가능한 완성을 지원한다.[74] 이 기능은 2000년에 출시된 2.04 베타 버전부터 제공되었다.[75] 이러한 명령어들은 명령어(즉, 설치된 프로그램), 함수, 변수 및 파일 이름에 대해 복잡하고 지능적인 완성 사양을 가능하게 한다.[76]

completecompopt 두 명령어는 readline 입력에서 사용 가능한 일부 명령어 또는 옵션의 인자가 어떻게 나열될지 지정한다. 버전 5.1 기준으로 명령어 또는 옵션의 완성은 대개 이름을 입력한 후 Tab 키를 눌러 활성화된다.[76] 이 기능은 상호작용 모드에서만 사용할 수 있다.

프롬프트

[편집]

구성 가능한 프롬프트. 이 기능은 상호작용 모드에서만 사용할 수 있다.

문서화

[편집]

사용자 매뉴얼

[편집]

배시를 위한 사용자 매뉴얼은 GNU 프로젝트에서 제공한다. 이는 때때로 man page보다 더 사용자 친화적인 문서로 간주된다. "시스템의 /usr/share/doc/bash, /usr/local/share/doc/bash 또는 이와 유사한 디렉터리를 찾아봄으로써 배시에 관한 정보를 찾을 수도 있다."[77] GNU/리눅스 시스템에서 info 프로그램을 사용할 수 있는 경우, 설치된 버전에 맞는 GNU 매뉴얼을 info bash에서 볼 수 있다.[78][79]

Man page

[편집]

최신 기술 매뉴얼 또는 'man page'는 배시가 작동하는 방식을 이해하기 위한 권위 있는 설명 기술 문서로 의도되었다. GNU/리눅스 시스템에서 설치된 버전에 맞는 문서는 대개 man 프로그램을 통해 man bash에서 확인할 수 있다.[78][39][80]

help 내장 명령어

[편집]

최신 버전의 배시에서는 터미널 프롬프트에서 help, help [내장 명령어 이름] 또는 man builtins를 실행하여 셸 내장 명령어에 대한 정보를 찾을 수 있다.

printf 명령어는 env를 통해 호출함으로써 셸의 검색 경로를 통해 발견된 프로그램을 실행하고 셸 별칭이나 내장 함수가 실행되지 않도록 보장할 수 있다: env printf --help.[81]

POSIX 사양

[편집]

서로 다른 운영체제에서 실행되는 서로 다른 셸 프로그램 간의 상호 운용성을 위해 POSIX 사양은 현대의 유닉스 계열 셸이 작성되는 방식에 영향을 미친다. 배시는 "IEEE POSIX 사양(IEEE Standard 1003.1)의 IEEE POSIX '셸 및 유틸리티' 부분을 준수하는 구현으로 의도되었다."[82] 이 표준의 최신 간행물(2024년)은 온라인에서 확인할 수 있다.[83]

배시의 기반이 되는 표준인 POSIX 표준, 또는 IEEE Std 1003.1 등은 특히 많은 정보를 담고 있다.[84]

추가 자료

[편집]

"프로젝트 유지 관리자는 자주 묻는 질문(FAQ)을 포함하는 배시 페이지를 운영하고 있다."[77][85][86] 이 FAQ는 배시 버전 5.1 기준이며 더 이상 업데이트되지 않는다.

비공식적인 지원 채널은 libera.chat의 IRC #bash 채널에서 이용 가능하며, 메일링 리스트는 Bash - GNU 프로젝트 - 자유 소프트웨어 재단에서 확인할 수 있다.

보안 및 취약점

[편집]

루트 스크립트

[편집]

루트 사용자로 셸 스크립트를 실행하는 것은 수년 동안 나쁜 보안 관행으로 널리 비판받아 왔다. 흔히 언급되는 한 가지 이유는 스크립트가 루트로 실행될 때 스크립트 내의 버그로 인한 부정적인 영향이 루트의 승격된 권한에 의해 확대되기 때문이다.

흔한 예시로, 스크립트에 rm -rf ${dir}/ 명령어가 포함되어 있지만 $dir 변수가 정의되지 않은 경우가 있다. 리눅스에서 이 스크립트가 일반 사용자에 의해 실행되었다면 셸은 rm -rf / 명령어를 일반 사용자로 실행하려고 시도할 것이고 명령어는 실패할 것이다. 그러나 스크립트가 루트 사용자에 의해 실행되었다면 명령어는 성공하여 파일 시스템이 삭제될 가능성이 높다.

대신 명령어 단위로 sudo를 사용하는 것이 권장된다.

CGI 스크립트

[편집]

CGI 스크립트는 중대한 취약점의 원천이다.[87][88][89]

내장 명령어 eval

[편집]

"eval 명령어는 매우 강력하며 남용하기 매우 쉽다."[90]

입력 유효성 검사

[편집]

"입력 유효성 검사는 데이터가 데이터 클렌징을 거쳐 정확하고 유용한 데이터 품질을 갖추었음을 보장하는 프로세스다."

입력 유효성 검사는 제대로 형성된 데이터만 정보 시스템의 워크플로에 입력되도록 하여, 잘못된 데이터가 데이터베이스에 남거나 다양한 다운스트림 구성 요소의 오작동을 유발하는 것을 방지하기 위해 수행된다. 입력 유효성 검사는 데이터 흐름에서 가능한 한 빨리, 가급적이면 외부 당사자로부터 데이터를 받는 즉시 이루어져야 한다.[91]

OWASP Input Validation Cheat Sheet

셸쇼크

[편집]

2014년 9월, 프로그램에서 보안 버그가 발견되었다.[92] 이는 "셸쇼크"라고 명명되었다. 공개적 노출은 곧바로 인터넷 전반에 걸친 다양한 공격으로 이어졌다.[93][94][95]

취약점 악용을 통해 특정 버전의 배시에서 실행 가능한 CGI 스크립트 내에서 임의 코드 실행이 가능해질 수 있었다. 이 버그는 배시가 환경 변수를 통해 서브셸에 함수 정의를 전달하는 방식과 관련이 있었다.[96] 이 버그는 1989년 8월(버전 1.03)부터 소스 코드에 존재해 왔으며,[97] 2014년 9월(버전 4.3)에 패치되었다.

버그가 확인된 직후 버그를 수정하기 위한 패치가 제공되었다. 최신 버전으로 업그레이드하는 것이 강력히 권장된다.

이 버그에는 다른 것들 중에서도 CVE 식별자 CVE-2014-6271, CVE-2014-6277 CVE-2014-7169 등이 할당되었다. CVSS Metrics 2.x 및 3.x에서 이 버그는 각각 "높음" 및 "심각"으로 간주된다.

지원 중단된 구문

[편집]
  • 백틱 스타일 명령어 치환: `...`는 다음으로 인해 지원 중단되었다:
    • $(...);
  • test/[/[[ 명령어에서의 -a 또는 -o 사용,
    • 예를 들어 [ -r ./file -a ! -l ./file ]는 다음으로 인해 지원 중단되었다:
      • [ -r ./file ] && ! [ -l ./file ];
  • 산술 구문 $[...]의 사용은 다음으로 인해 지원 중단되었다:
    • $((...)) 또는
    • 상황에 따라 ((...));
  • 파이프라인으로서의 ^ 사용은 |를 위해 지원 중단되었다;
  • expr 또는 let의 모든 사용.

디버깅

[편집]

기능 일람표

[편집]
디버깅 중에 유용할 수 있는 배시 기능.[4][57][98]
기능 POSIX 2024 설명 배시 버전
문법 유형 공식 명칭 구문
특수 내장 유틸리티set / xtrace set -x 셸의 주요 디버깅 수단.

"명령어를 확장한 후 실행하기 전에 각 명령어에 대한 추적 정보를 표준 오류에 기록한다."

?
특수 매개변수종료 상태 "$?" "가장 짧은 10진수 종료 상태 표현으로 확장된다." ?
매개변수 확장Null 또는 설정되지 않음 표시 "${parameter:?[word]}" "[word](오류 메시지나 줄 번호 등)의 확장이 표준 오류에 기록되고 셸이 0이 아닌 종료 코드로 종료된다." ?
특수 매개변수호출된 셸의 PID "$$" "호출된 셸의 가장 짧은 10진수 프로세스 ID 표현으로 확장된다." ?
특수 내장 유틸리티set / verbose set -v "입력을 읽는 대로 표준 오류에 기록한다." ?
특수 내장 유틸리티set / pipefail set -o pipefail "파이프라인의 종료 상태를 마지막(가장 오른쪽) 명령어뿐만 아니라 파이프라인 내 모든 명령어의 종료 상태로부터 도출한다." ?
특수 내장 유틸리티set / nounset set -u 활성화되면 설정되지 않은 변수 확장을 만날 때 셸이 오류 메시지와 함께 종료된다.

사용 시 여러 가지 직관에 반하는 함정이 있다.

?
특수 내장 유틸리티set / errexit set -e Errexit는 활성화되면 매우 특정한 조건 하에서 셸이 0이 아닌 종료 코드를 받을 때마다 오류 메시지 없이 종료되도록 하는 설정이다.

그 사용 여부는 다소 논란이 있는데, 지지자들은 스크립트가 "절대 실패해서는 안 되는" 상황에서 검증 가능성을 보장한다고 주장한다. 그러나 반대자들은 그 사용이 신뢰할 수 없고, 기만적으로 단순하며, 매우 직관에 어긋나고, 수많은 함정이 있으며 본질적으로 "보안 연극"이라고 주장한다. 수많은 배시 개발자들이 이 설정의 사용을 강력히 반대해 왔다.

?
특수 내장 유틸리티trap / EXIT trap '[arg]' EXIT "신호 지정자가 0 또는 EXIT이면, 셸이 종료될 때 [arg]가 실행된다." 만약 [arg]가 확장을 포함한다면 단일 인용부호로 감싸야 한다. ?
유틸리티printf printf '<%s>\n' "${var}" 변수의 내용을 신뢰할 수 있게 출력하는 수단. ?
배시 변수BASHPID "${BASHPID}" 아니요 "현재 배시 프로세스의 프로세스 ID로 확장된다."[99] ?
배시 변수BASH_ARGC "${BASH_ARGC[@]}" 아니요 "현재 배시 실행 콜 스택의 각 프레임에 있는 매개변수 수의 값을 갖는 배열 변수."[100] ?
배시 변수BASH_ARGV "${BASH_ARGV[@]}" 아니요 "현재 배시 실행 콜 스택의 모든 매개변수를 포함하는 배열 변수."[101] ?
배시 변수BASH_LINENO "${BASH_LINENO[@]}" 아니요 ""${FUNCNAME[@]}"의 각 해당 멤버가 호출된 소스 파일의 줄 번호를 멤버로 하는 배열 변수."[102] ?
배시 변수BASH_REMATCH "${BASH_REMATCH[@]}" 아니요 "[[ 조건부 명령어에 대해 =~ 이진 연산자에 의해 할당된 멤버들을 갖는 배열 변수."[103] ?
배시 변수BASH_SOURCE "${BASH_SOURCE[@]}" 아니요 ""${FUNCNAME[@]}" 배열 변수의 해당 셸 함수 이름이 정의된 소스 파일 이름들을 멤버로 하는 배열 변수."[104] ?
배시 변수BASH_XTRACEFD "${BASH_XTRACEFD}" 아니요 "유효한 파일 서술자에 해당하는 정수로 설정되면, 배시는 set -x가 활성화될 때 생성되는 추적 출력을 해당 파일 서술자에 기록한다."[105] ?
배시 변수EPOCHREALTIME "${EPOCHREALTIME}" 아니요 "이 매개변수가 참조될 때마다, 마이크로초 단위 정밀도의 부동소수점 값으로 유닉스 시간(에포크, time(3) 참조) 이후의 초 수로 확장된다."[106] ?
배시 변수FUNCNAME "${FUNCNAME[@]}" 아니요 "현재 실행 콜 스택에 있는 모든 셸 함수의 이름을 포함하는 배열 변수."[107] ?
배시 변수LINENO "${LINENO}" 아니요 "이 매개변수가 참조될 때마다, 셸은 스크립트나 함수 내에서 현재 순차적인 줄 번호(1부터 시작)를 나타내는 10진수로 치환한다."[108] ?
배시 변수PIPESTATUS "${PIPESTATUS[@]}" 아니요 "가장 최근에 실행된 포그라운드 파이프라인(단일 명령어만 포함할 수 있음)의 프로세스들로부터의 종료 상태 값 목록을 포함하는 배열 변수."[109] ?
배시 변수PPID "${PPID}" 아니요 "셸 부모의 프로세스 ID."[110] ?
배시 변수PS4 "${PS4}" 아니요 "이 매개변수의 값은 PS1과 같이 확장되며, 그 값은 실행 추적 중에 배시가 각 명령어를 표시하기 전에 출력된다."[111] ?
셸 내장 명령어set / restricted set -r 아니요 제한 모드는 기계에 물리적으로 접근 가능한 악의적인 사람으로부터 개별 셸 인스턴스의 보안을 개선하기 위한 의도다.

위협 모델이 변화함에 따라 예전보다 덜 흔하게 사용된다.

?
셸 내장 명령어shopt / extdebug shopt -s extdebug 아니요 "디버거에 의해 사용되도록 의도된 동작." ?
셸 내장 명령어trap / DEBUG trap '[arg]' DEBUG 아니요 "sigspec이 DEBUG이면, 명령어 arg가 특정 종류의 명령어 실행 전에 실행된다." ?
셸 내장 명령어trap / ERR trap '[arg]' ERR 아니요 "sigspec이 ERR이면, 명령어 arg가 특정 종류의 명령어가 0이 아닌 종료 상태를 반환할 때마다 실행된다(ErrExit와 유사한 제한 사항이 적용됨)." ?
셸 내장 명령어trap / RETURN trap '[arg]' RETURN 아니요 "sigspec이 RETURN이면, . 또는 source 내장 명령어로 실행된 셸 함수나 스크립트가 실행을 마칠 때마다 명령어 arg가 실행된다." ?
  • POSIX에 의해 규정된 셸 기능:
    • 매개변수 확장:[112]
    • 특수 매개변수:[113][114]
    • 특수 내장 유틸리티 set:[115][116]
    • 특수 내장 유틸리티 trap:[116][117]
      • POSIX는 trap 내장 명령어의 특정 사용법을 규정한다.
    • 유틸리티 printf: 변수 내용을 신뢰할 수 있게 출력하는 수단.
  • POSIX에 의해 규정되지 않은 배시 기능:
    • 배시 변수:[118][119]
    • 셸 내장 명령어 set:[115][116]
    • 셸 내장 명령어 shopt:[120][116]
    • 셸 내장 명령어 trap:[117][116]
      • POSIX가 trap 내장 명령어의 특정 사용법을 규정하지만, 다음 신호 지정은 배시 확장 기능이다: ...
  • 제3자 디버깅 유틸리티:
    • ShellCheck: 셸 스크립트 분석 도구;[121][27]
    • devscripts-checkbashisms: /bin/sh 스크립트에 배시 전용 구문이 포함되어 있는지 확인;[122][26]
    • kcov: 특별한 컴파일 옵션 없이 사용하는 코드 커버리지 도구;[123]
    • Bashdb: 배시 기호 디버거.[31][124]

예시

[편집]

"${var:?}" 매개변수 확장을 사용하면 설정되지 않았거나 null인 변수가 스크립트를 중단시킬 수 있다.

$ cat ex.sh
#!/bin/bash
bar="foo is not defined"
echo "${foo:?$bar}"
echo this message doesn't print

$ ./ex.sh
./ex.sh: line 3: foo: foo is not defined
$

공백과 개행 문자를 포함하는 배열의 내용을 먼저 이식 가능한 구문으로 출력한 후, 배시에서 동일하게 수행하는 방법. POSIX에는 명명된 배열이 없으며 오직 set 내장 명령어로 재설정할 수 있는 인자 목록 "$@"만 있음에 유의하라.

$ # POSIX 셸에서:
$ set -- "a" " b" "
>  c "
$ printf ',%s,\n' "$@"
,a,
, b,
,
 c,

배시에서는 개행 문자 전의 공백 수가 명확해진다는 점에 유의하라.

$ # 배시에서:
$ array=( "a" " b" "
>  c " )
$ declare -p array
declare -a array=([0]="a" [1]=" b" [2]=$' \n c ')

문제가 발생했을 때 오류 메시지를 출력하는 방법.

$ cat error.sh
#!/bin/env bash
if ! lsblk | grep sdb
then
  echo Error, line "${LINENO}"
fi
$ ./error.sh
Error, line 130

xtrace 사용 예시. 만약 errexit가 활성화되어 있었다면 echo quux는 실행되지 않았을 것이다.

$ cat test.sh
#!/bin/env bash
set -x
foo=bar; echo "${foo}"
false
echo quux
$ ./test.sh
+ foo=bar
+ echo bar
bar
+ false
+ echo quux
quux

참고: $BASHPID는 재초기화가 필요 없는 서브셸과 같은 특정 상황에서 $$와 다르다.

$ echo $(echo $BASHPID $$)   $$    $BASHPID
              25680    16920 16920 16920
#             |        |     |     |
#             |        |     |     \-- 서브셸 외부의 $BASHPID
#             |        |     \-- 서브셸 외부의 $$
#             |        \-- 서브셸 내부의 $$
#             \-- 서브셸 내부의 $BASHPID

버그 보고

[편집]

bashbug라는 외부 명령어는 배시 셸 버그를 보고한다. 명령어가 호출되면 사용자의 기본 편집기가 양식과 함께 나타난다. 양식을 작성하여 배시 유지 관리자(또는 선택적으로 다른 이메일 주소)에게 메일로 보낸다.[125][126]

역사

[편집]

셸 스크립트 기능은 같은 이름의 1963년 매크로 프로세서를 참조한 "RUNCOM"이라는 파일에서 유래했다. 접미사 "rc"는 "runcom"의 약자다.[127] "셸"이라는 용어는 1964년 또는 1965년에 Louis Pouzin에 의해 만들어졌으며, 그의 1965년 논문 "The SHELL, A Global Tool for Calling and Chaining Procedures in the System"에 등장했다. 이 논문은 나중에 많은 유닉스 셸에서 발견되는 많은 기능을 설명하고 있다.[128][129] 문자 인코딩을 위한 ASCII 표준은 1969년 RFC 20이라는 문서에서 정의되었다.[130]

타임라인

[편집]

배시 역사상의 중요한 사건들은 다음과 같다:

같이 보기

[편집]

각주

[편집]
  1. Chet Ramey (2025년 7월 5일). Bash-5.3-release available (영어). 2025년 7월 5일에 확인함.
  2. GNU Bash. 자유 소프트웨어 재단. GNU 프로젝트. 2019년 4월 26일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함. Bash is free software, distributed under the terms of the [GNU] General Public License as published by the Free Software Foundation, version 3 of the License (or any later version).
  3. bash-1.11. oldlinux.org. 2021년 10월 15일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함. See test.c for GPL-2.0-or-later
  4. 1 2 3 4 BashFAQ/061: Is there a list of which features were added to specific releases (versions) of Bash?. wooledge.org. 2021년 3월 2일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  5. bash-1.05. oldlinux.org. 2021년 5월 6일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  6. Is there a way to download the presumably initial bash source bash-0.99?. unix.stackexchange.com. 2025년 8월 8일에 확인함.
  7. 1 2 3
  8. Bash - GNU Project - Free Software Foundation. www.gnu.org.
  9. 1 2 Morris, Richard (2015년 12월 14일). Chet Ramey: Geek of the Week. Simple Talk. 2020년 7월 31일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  10. Michael, Randal (2008). Mastering Unix Shell Scripting 2판. Indianapolis, Indiana: Wiley. 3쪽. ISBN 978-0-470-18301-4. 2025년 8월 16일에 확인함. UNIX is case sensitive. Because UNIX is case sensitive, our shell scripts are also case sensitive.
  11. GNU Bash Manual: 8.2.1 Readline Bare Essentials. GNU 프로젝트. 자유 소프트웨어 재단. 2025년 8월 8일에 확인함.
  12. GNU Bash Manual: 8.5 Readline vi mode. GNU 프로젝트. 자유 소프트웨어 재단. 2025년 8월 8일에 확인함.
  13. Rippee, Scott (2012년 10월 5일). Getting started with BASH: A Bash Tutorial. hypexr.org. 2021년 3월 2일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  14. Bash Reference Manual, D.2 Index of Shell Reserved Words. 2025년 8월 18일에 확인함.
  15. 1 2 3 4 Bash Reference Manual. www.gnu.org.
  16. Arrays (Bash Reference Manual). www.gnu.org.
  17. Huber, Mathias. Bash 4.0 Introduces Associative Arrays » Linux Magazine. Linux Magazine.
  18. 1 2 3.2.1. The path. Introduction to Linux. 리눅스 문서화 프로젝트. 2025년 8월 13일에 확인함.
  19. Modular data structures in C. dartmouth.edu. 다트머스 대학교. 2025년 8월 15일에 확인함.
  20. 4.1 Bourne Shell Builtins. gnu.org. 자유 소프트웨어 재단. 2025년 8월 26일에 확인함.
  21. 1 2 Stevens, Al (2021년 7월 1일). I Almost Get a Linux Editor and Compiler. Dr. Dobbs' Journal. 2021년 3월 2일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함. But virtually all the configure and install scripts that come with open-source programs are written for bash, and if you want to understand those scripts, you have to know bash.
  22. Bash reference manual, 6.2 Bash startup files. GNU 프로젝트. 자유 소프트웨어 재단. 2025년 8월 12일에 확인함.
  23. 1 2 Cooper, Mendel. 36.9: Portability Issues. Advanced Bash Scripting Guide. 리눅스 문서화 프로젝트. 2012년 1월 27일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함 The Public's Library and Digital Archive 경유.
  24. Ramey, Chet. 6.11 Bash and POSIX. 케이스 웨스턴 리저브 대학교. 2025년 8월 8일에 확인함.
  25. 1 2 10 – Files. Debian Policy Manual v4.5.0.2. 데비안 프로젝트. 2020년 5월 12일에 원본 문서에서 보존된 문서. 2020년 5월 11일에 확인함.
  26. 1 2 checkbashisms(1)  리눅스 General Commands Manual
  27. 1 2 shellcheck(1)  리눅스 General Commands Manual
  28. GNU 프로젝트. 11: Portable Shell. Autoconf. 자유 소프트웨어 재단. 2021년 3월 2일에 원본 문서에서 보존된 문서. 2020년 1월 20일에 확인함.
  29. GNU 프로젝트. B.1 Implementation Differences from the SVR4.2 Shell. Bash Reference Manual. 자유 소프트웨어 재단. 2025년 8월 13일에 확인함. In a questionable attempt at security, the SVR4.2 shell, when invoked without the -p option, will alter its real and effective UID and GID....
  30. GNU 프로젝트. 4.3.1 The Set Builtin. Bash Reference Manual. 자유 소프트웨어 재단. 2025년 8월 13일에 확인함. In this mode, the $BASH_ENV and $ENV files are not processed, shell functions are not inherited from the environment, and the SHELLOPTS, BASHOPTS, CDPATH and GLOBIGNORE variables, if they appear in the environment, are ignored.
  31. 1 2 BASH Debugger. 소스포지. 2025년 8월 18일에 확인함.
  32. GNU 프로젝트. 6.12 Shell Compatibility Mode. Bash Reference Manual. 자유 소프트웨어 재단. 2025년 8월 5일에 확인함.
  33. 문서의 set -v를 참조하라.
  34. 오픈 그룹. 2.15 Special Builtins: colon - null utility. opengroup.org. Base Specifications Issue 8: IEEE Std 1003.1-2024. 2025년 8월 8일에 확인함.
  35. Bash Reference Manual: 7.1 Job Control Basics. 자유 소프트웨어 재단. GNU 프로젝트. 2018년 3월 15일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  36. Michael, Randal (2008). Mastering Unix Shell Scripting, 2e. Wiley Publishing, Inc., Indianapolis, Indiana. 25쪽. ISBN 978-0-470-18301-4. 2025년 8월 16일에 확인함. 19 :: SIGSTOP :: Stop, usually Ctrl + z
  37. Newham, Cameron (2005년 3월 29일). Learning the bash Shell: Unix Shell Programming. O'Reilly Media, Inc. 205쪽. ISBN 978-0-596-55500-9. 2025년 8월 16일에 확인함. Use KILL only as a last resort!
  38. dd(1). www.man7.org. 2025년 10월 19일에 확인함.
  39. 1 2 Bash(1). case.edu. 케이스 웨스턴 리저브 대학교. 2025년 8월 8일에 확인함.
  40. Sending and Trapping Signals. wooledge.org. 2025년 8월 5일에 확인함.
  41. Michael, Randal (2008). Mastering Unix Shell Scripting, 2e. Wiley Publishing, Inc., Indianapolis, Indiana. 20쪽. ISBN 978-0-470-18301-4. 2025년 8월 16일에 확인함. In Korn shell the echo command recognizes these command options by default. In Bash shell we must add the -e switch to the echo command, echo -e "\n" for one new line.
  42. Bash Reference Manual: 3.7.3: Command Execution Environment. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  43. Bash Reference Manual, 6.6 Aliases. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 14일에 확인함. Aliases allow a string to be substituted for a word that is in a position in the input where it can be the first word of a simple command. Aliases have names and corresponding values that are set and unset using the alias and unalias builtin commands.
  44. alias - define or display aliases. opengroup.org. 오픈 그룹. 2025년 8월 14일에 확인함.
  45. Cooper, Mendel. Advanced Bash Scripting Guide, Ch 25. Aliases. 리눅스 문서화 프로젝트. 2025년 8월 14일에 확인함.
  46. Commands and Arguments: Aliases. wooledge.org. 2025년 8월 14일에 확인함.
  47. Compound Commands: Aliases. wooledge.org. 2025년 8월 14일에 확인함.
  48. Bash Reference Manual, 3.3 Shell Functions. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 14일에 확인함. Shell functions are a way to group commands for later execution using a single name for the group. They are executed just like a "regular" simple command. When the name of a shell function is used as a simple command name, the shell executes the list of commands associated with that function name. Shell functions are executed in the current shell context; there is no new process created to interpret them.
  49. 2.9.5 Function Definition Command. opengroup.org. 오픈 그룹. 2025년 8월 14일에 확인함.
  50. Cooper, Mendel. Advanced Bash Scripting Guide, Ch 24. Functions. 리눅스 문서화 프로젝트. 2025년 8월 14일에 확인함.
  51. Compound Commands, 4. Functions. wooledge.org. 2025년 8월 14일에 확인함.
  52. Bash Programming, 2. Basic Concepts, 7. Functions. wooledge.org. 2025년 8월 14일에 확인함.
  53. Bash Weaknesses, 13. Functions. wooledge.org. 2025년 8월 14일에 확인함.
  54. Bash Reference Manual: 4.1: Bourne Shell Builtins. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  55. Bash Reference Manual: 4.3.1: The Set Builtin. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  56. bug-bash archives, Re: Document that set -v inside case statements is special (메일링 리스트). bug-bash (GNU 프로젝트). 2021년 4월 20일. 2025년 8월 8일에 확인함.
  57. 1 2 Bash changes. bash-hackers.org. 2019년 9월 23일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  58. Glossary of Coding Terms for Beginners: iteration. syracuse.edu. 시러큐스 대학교. 2020년 1월 13일. 2025년 8월 15일에 확인함.
  59. compound - noun (1). merriam-webster.com. Merriam-Webster's Collegiate Dictionary. 2025년 8월 15일에 확인함.
  60. Stephen R Bourne (2015년 6월 12일). Early days of Unix and design of sh (PDF). bsdcan.org. BSDcan 2015: The Technical BSD Conference. 2025년 8월 8일에 확인함.
  61. Advanced Bash Scripting Guide: 37.2: Bash, version 3. 리눅스 문서화 프로젝트. Section 37.2 (Bash, version 3). 2017년 5월 5일에 원본 문서에서 보존된 문서. 2017년 3월 5일에 확인함.
  62. GNU Bash Manual: 3.2.5.2: Conditional Constructs. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  63. Bash Reference Manual, 3.2.6 Coprocesses. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 15일에 확인함.
  64. Mallett, Andrew (2015년 12월 24일). Mastering Linux Shell Scripting. Packt Publishing, Ltd. 56쪽. ISBN 978-1-78439-759-3. 2025년 8월 16일에 확인함. Learning this now can save us a lot of pain and heartache later, especially....
  65. Bash Reference Manual: 5.3.1 Brace Expansion. 자유 소프트웨어 재단. GNU 프로젝트. 2018년 3월 15일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  66. Advanced Bash Scripting Guide: 37.3: Bash, version 4. 리눅스 문서화 프로젝트. 2018년 7월 1일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  67. Update bash to version 4.0 on OSX. apple.stackexchange.com. 2018년 6월 25일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  68. Bash Reference Manual: 6.7: Arrays. 자유 소프트웨어 재단. GNU 프로젝트. 2018년 7월 11일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  69. Bash Reference Manual, 3.1.2.5 Locale-Specific Translation. 자유 소프트웨어 재단. 자유 소프트웨어 재단. 2025년 8월 16일에 확인함. Prefixing a double-quoted string with a dollar sign $, such as $"hello, world", causes the string to be translated according to the current locale. The gettext infrastructure performs the lookup and translation, using the $LC_MESSAGES, $TEXTDOMAINDIR, and $TEXTDOMAIN shell variables.
  70. The Bash Parser. wooledge.org. 2025년 8월 15일에 확인함.
  71. Ramey, Chet. The Architecture of Open Source Applications (Volume 1): The Bourne-Again Shell. aosabook.org. 2025년 8월 15일에 확인함.
  72. Bash Reference Manual: 9.2: Bash History Builtins. 자유 소프트웨어 재단. GNU 프로젝트. 2019년 9월 15일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  73. Bash Reference Manual: 8.6: Programmable Completion. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  74. Bash Reference Manual: 8.6 Programmable completion. case.edu. 케이스 웨스턴 리저브 대학교. 2025년 8월 8일에 확인함.
  75. Index of /gnu/bash. swin.edu.au. Swinburne University of Technology. 2020년 3월 8일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  76. 1 2 Advanced Bash Scripting Guide: Appendix J: An Introduction to Programmable Completion. 리눅스 문서화 프로젝트. 2022년 1월 21일에 확인함.
  77. 1 2 Bash. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  78. 1 2 자유 소프트웨어 재단. GNU Bash manual. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  79. Bash Reference Manual. case.edu. 케이스 웨스턴 리저브 대학교. 2025년 8월 8일에 확인함.
  80. git: index: bash.git. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  81. GNU Coreutils manual v.9.7, 15.2 printf: Format and print data. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 11일에 확인함.
  82. GNU Bash Manual: 1.1: What is Bash?. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  83. 오픈 그룹. POSIX 2024. 자유 소프트웨어 재단. 2025년 7월 30일에 확인함.
  84. The Open Group Base Specifications Issue 7, 2018 edition. opengroup.org.
  85. 1 2 The GNU Bourne-Again Shell, Top Page. case.edu. 케이스 웨스턴 리저브 대학교. 2025년 8월 8일에 확인함.
  86. Frequently Asked Questions. case.edu. 케이스 웨스턴 리저브 대학교. 2025년 8월 8일에 확인함.
  87. CVE-2024-2448: Authenticated Command Injection In Progress Kemp LoadMaster. rhinosecuritylabs.com. Rhino Security Labs, Inc. 2024년 4월 23일. 2025년 8월 17일에 확인함.
  88. CGI-BIN Specific Vulnerabilities. ucdavis.edu. 캘리포니아 대학교 데이비스. January 1999. 2025년 8월 17일에 확인함.
  89. CGI Security. BITS: computing and communications news. Los Alamos National Laboratory. March 1996. 2000년 4월 16일에 원본 문서에서 보존된 문서. 2025년 8월 17일에 확인함.
  90. Eval command and security issues. wooledge.org. 2025년 7월 21일에 원본 문서에서 보존된 문서. 2025년 8월 17일에 확인함.
  91. Input Validation Cheat Sheet. owasp.org. OWASP. 2025년 8월 17일에 확인함.
  92. Juliana, Cino (2017년 6월 10일). Linux bash exit status and how to set exit status in bash - Techolac. techolac.com. 2019년 6월 21일에 원본 문서에서 보존된 문서. 2019년 6월 21일에 확인함.
  93. Leyden, John (2014년 9월 24일). Patch Bash NOW: 'Shell Shock' bug blasts OS X, Linux systems wide open. theregister.co.uk. The Register. 2014년 10월 16일에 원본 문서에서 보존된 문서. 2014년 9월 25일에 확인함.
  94. Perlroth, Nicole (2014년 9월 25일). Security Experts Expect 'Shellshock' Software Bug in Bash to Be Significant. The New York Times. 2019년 4월 5일에 원본 문서에서 보존된 문서. 2014년 9월 25일에 확인함.
  95. Seltzer, Larry (2014년 9월 29일). Shellshock makes Heartbleed look insignificant. zdnet.com. ZDNet. 2016년 5월 14일에 원본 문서에서 보존된 문서.
  96. Sidhpurwala, Huzaifa (2014년 9월 24일). Bash specially-crafted environment variables code injection attack. redhat.com. Red Hat. 2014년 9월 25일에 원본 문서에서 보존된 문서. 2014년 9월 25일에 확인함.
  97. Chazelas, Stephane (2014년 10월 4일). oss-sec mailing list archives. seclists.org. 2014년 10월 6일에 원본 문서에서 보존된 문서. 2014년 10월 4일에 확인함.
  98. Advanced Bash Scripting Guide: 2.3: Debugging Bash scripts. 리눅스 문서화 프로젝트. 2018년 11월 4일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  99. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. BASHPID. 2025년 8월 8일에 확인함.
  100. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. BASH_ARGC. 2025년 8월 8일에 확인함.
  101. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. BASH_ARGV. 2025년 8월 8일에 확인함.
  102. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. BASH_LINENO. 2025년 8월 8일에 확인함.
  103. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. BASH_REMATCH. 2025년 8월 8일에 확인함.
  104. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. BASH_SOURCE. 2025년 8월 8일에 확인함.
  105. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. BASH_XTRACEFD. 2025년 8월 8일에 확인함.
  106. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. EPOCHREALTIME. 2025년 8월 8일에 확인함.
  107. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. FUNCNAME. 2025년 8월 8일에 확인함.
  108. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. LINENO. 2025년 8월 8일에 확인함.
  109. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. PIPESTATUS. 2025년 8월 8일에 확인함.
  110. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. PPID. 2025년 8월 8일에 확인함.
  111. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. PS4. 2025년 8월 8일에 확인함.
  112. Bash Reference Manual: 3.4.2: Special Parameters. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  113. Shell Command Language. opengroup.org.
  114. 1 2
  115. 1 2 3 4 5 Bash(1), Shell builtin commands. case.edu. 케이스 웨스턴 리저브 대학교. 2025년 8월 8일에 확인함.
  116. 1 2 Bourne Shell Builtins (Bash Reference Manual). 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  117. Bash Reference Manual: 5.2: Bash Variables. 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  118. Bash(1), Special parameters. case.edu. 케이스 웨스턴 리저브 대학교. 2025년 8월 8일에 확인함.
  119. The Shopt Builtin (Bash Reference Manual). 자유 소프트웨어 재단. GNU 프로젝트. 2025년 8월 8일에 확인함.
  120. Debian -- Details of package devscripts in sid. debian.org.
  121. Kcov - code coverage. github.io.
  122. [Bashdb-devel] Re: [PATCH] fix bashdb script handling of tmp directory (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  123. bashbug(1). die.net. 2017년 10월 21일. 2018년 10월 2일에 원본 문서에서 보존된 문서.
  124. bashbug(1) Mac OS X Manual Page. apple.com. 2014년 6월 4일. 2014년 10월 6일에 원본 문서에서 보존된 문서.
  125. In Unix, what do some obscurely named commands stand for?. iu.edu. Indiana University. 2009년 2월 5일. 2010년 6월 10일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  126. Louis Pouzin (2000년 11월 25일). The Origin of the Shell. multicians.org.
  127. The SHELL, A Global Tool for Calling and Chaining Procedures in the System (PDF). mit.edu.
  128. Cerf, Vint (1969년 10월 16일). ASCII Format for Network Interchange. ietf.org. UCLA, Network Working Group. 2025년 8월 8일에 확인함.
  129. 1 2 Stallman, Richard; Ramey, Chet (1988년 2월 10일). GNU + BSD = ?. google.com (뉴스그룹: comp.unix.questions). Usenet: 2362@mandrill.CWRU.Edu. 2021년 12월 28일에 원본 문서에서 보존된 문서. 2021년 12월 28일에 확인함. For a year and a half, the GNU shell was "just about done". The author made repeated promises to deliver what he had done, and never kept them. Finally I could no longer believe he would ever deliver anything. So Foundation staff member Brian Fox is now implementing an imitation of the Bourne shell.
  130. Stallman, Richard (2010년 10월 3일). About the GNU Project. 자유 소프트웨어 재단. GNU 프로젝트. 2011년 4월 24일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함. Free Software Foundation employees have written and maintained a number of GNU software packages. Two notable ones are the C library and the shell. ... We funded development of these programs because the GNU Project was not just about tools or a development environment. Our goal was a complete operating system, and these programs were needed for that goal.
  131. Fox, Brian; Tower Jr., Leonard H. (1989년 6월 8일). Bash is in beta release!. google.com (뉴스그룹: gnu.announce). 2013년 5월 4일에 원본 문서에서 보존된 문서. 2010년 10월 28일에 확인함.
  132. Evolution of shells in Linux. ibm.com. IBM. 2011년 12월 9일.
  133. Torvalds, Linus (1991년 8월 26일). What would you like to see most in Minix?. google.com (뉴스그룹: comp.os.minix). 2025년 8월 8일에 확인함. To make things really clear - yes I can run gcc on it, and bash, and most of the gnu [bin/file]utilities
  134. January 1993 GNU's Bulletin. google.com (뉴스그룹: gnu.announce). 1993년 4월 20일. Usenet: gnusenet930421bulletin@prep.ai.mit.edu. 2021년 3월 2일에 원본 문서에서 보존된 문서. 2010년 10월 28일에 확인함.
  135. Ramey, Chet (1994년 8월 1일). Bash – the GNU shell (Reflections and Lessons Learned). linuxjournal.com. Linux Journal. 2008년 12월 5일에 원본 문서에서 보존된 문서. 2008년 11월 13일에 확인함.
  136. Ramey, Chet (2010년 10월 31일), Dates in your Computerworld interview, scribd.com, 2012년 7월 20일에 원본 문서에서 보존된 문서, 2010년 10월 31일에 확인함
  137. Bresnahan, Christine; Blum, Richard (April 2015). CompTIA Linux+ Powered by Linux Professional Institute Study Guide: Exam LX0-103 and Exam LX0-104 3판. John Wiley & Sons, Inc. 5쪽. ISBN 978-1-119-02122-3. 2021년 3월 2일에 원본 문서에서 보존된 문서. 2016년 6월 6일에 확인함. In Linux, most users run bash because it is the most popular shell.
  138. Danesh, Arman; Jang, Michael (February 2006). Mastering Linux. John Wiley & Sons, Inc. 363쪽. ISBN 978-0-7821-5277-7. 2021년 3월 2일에 원본 문서에서 보존된 문서. 2016년 6월 6일에 확인함. The Bourne Again Shell (bash) is the most common shell installed with Linux distributions.
  139. Debian Wiki: Shell. debian.org.
  140. Ramey, Chet (2000년 9월 14일). Re: Line-Edit mode is lost if "set -o vi" is in any files sourced on login. (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  141. Ramey, Chet (2001년 4월 9일). Bash-2.05 available for FTP (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  142. Essential Mac OS S Panther Server Administration, pg 189
  143. Foster-Johnson, Eric; Welch, John C.; Anderson, Micah (April 2005). Beginning Shell Scripting. John Wiley & Sons, Inc. 6쪽. ISBN 978-0-7645-9791-6. 2021년 3월 2일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함. Bash is by far the most popular shell and forms the default shell on Linux and Mac OSX systems.
  144. Bash-3.0 available for FTP (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  145. Bash-3.1 released (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  146. Bash-3.2 available for FTP (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  147. Bash-4.0 available for FTP (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  148. Bash-4.1 available for FTP (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  149. Bash-4.2 available for FTP (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  150. User Environment Feature Changes. oracle.com. Oracle Corporation. 2018년 6월 12일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  151. Bash-4.3 available for FTP (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  152. CVE-2014-6271. cve.org. 2025년 8월 8일에 확인함. GNU Bash through 4.3 processes trailing strings after function definitions in the values of environment variables, which allows remote attackers to execute arbitrary code via a crafted environment, as demonstrated by vectors involving the ForceCommand feature in OpenSSH sshd, the mod_cgi and mod_cgid modules in the Apache HTTP Server, scripts executed by unspecified DHCP clients, and other situations in which setting the environment occurs across a privilege boundary from Bash execution, aka "ShellShock."
  153. CVE-2014-7169. cve.org. 2025년 8월 8일에 확인함.
  154. Bash 3.0 Official Patch 1 (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  155. Briegel, Armin (2019년 6월 5일). Moving to zsh. scriptingosx.com. 2025년 8월 8일에 확인함.
  156. Apple Support – Use zsh as the default shell on your Mac. apple.com. 2019년 12월 2일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  157. Warren, Tom (2019년 6월 4일). Apple replaces bash with zsh as the default shell in macOS Catalina. theverge.com. The Verge. 2019년 6월 10일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함. The bash binary bundled with macOS has been stuck on version 3.2 for a long time now. Bash v4 was released in 2009 and bash v5 in January 2019. The reason Apple has not switched to these newer versions is that they are licensed with GPL v3. Bash v3 is still GPL v2.
  158. Hughes, Matthew (2019년 6월 4일). Why does macOS Catalina use Zsh instead of Bash? Licensing (미국 영어). The Next Web. 2020년 12월 31일에 원본 문서에서 보존된 문서. 2025년 8월 8일에 확인함.
  159. Bash-5.0 release available (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
  160. Bash-5.1 release available (메일링 리스트). bug-bash (GNU 프로젝트). 2025년 8월 8일에 확인함.
내용주
  1. 셸 변수 $$와 혼동하지 말 것
  2. 1 2 셸 스크립트는 실행 전 컴파일이 필요 없으며, 특정 요건이 충족되면 파일 이름을 사용하여 명령어로 호출할 수 있다.
  3. ALGOL 68에서 유래한 개념;[60]
  4. 배시 4는 또한 라이선스를 GPL-3.0-or-later로 전환한다.
  5. 2009년 2월,[66] 배시 4.0[d][67]에서 연관 배열 지원을 도입했다.[4] 연관 배열 인덱스는 AWKTcl과 유사한 방식의 문자열이다.[68] 이들은 다차원 배열을 에뮬레이트하는 데 사용될 수 있다.
  6. 1 2 패턴 매칭에서의 대괄호 사용 [...]과 테스트 명령어에서의 대괄호 사용 [ ... 는 각각 서로 다른 것이다.
  7. 이 기능에 대해서는 최신 버전의 bcawk 등을 참조.

외부 링크

[편집]
  • 위키미디어 공용에 배시 관련 미디어 분류가 있습니다.
  • 배시 위키데이터에서 편집하기 - 공식 웹사이트