주로 대표 참조 를 참고해 공부 및 기록 목적으로 작성한 포스팅으로, 현재 맡은 프로젝트에서 필요했던 내용이 추가로 포함되어 있습니다.
Ubuntu 20.04.4 기준 기본 쉘로 dash 를 사용하고 있다
아래 command 를 통해 "/bin/sh" 은 dash 쉘에 링크를 걸어둠을 알 수 있다
$ ls -al /bin/sh
lrwxrwxrwx 1 root root 4 Apr 23 2020 /bin/sh -> dash
하지만 여전히 bash 쉘도 사용되고 있는데,
개발용 shell sctipt 등 상당 수 스크립트가 아직 #!/bin/bash
를 달고 있고, 로그인은 dash 대신 bash 쉘을 사용하고 있기 때문이다.
# 로그인 쉘로 bash 사용함을 확인
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
dash 와 bash 가 각자 사용되어지는 기능을 더 자세히 알고자 하면 아래 참조를 참고하자
또한 기본 쉘을 bash 로 바꾸는 방법은 아래 참조를 참고하자
echo
> 문장을 출력하는데 자동으로 줄바꿈 됨
printf
> C언어와 비슷
#!/usr/bin/env bash
echo "hello world"
printf "hello world"
printf "%s %s" hello world
#으로 시작
string_test() {
echo "string test"
}
function string_test2() {
echo "string test 2"
echo "인자값: ${@}"
}
string_test
string_test2
# 함수에 인자값 전달하기(공백의로 뛰어서 2개의 인자값을 넘김)
string_test2 "hello" "world"
변수 사용시에는 "=" 기호 앞뒤로 공백이 없이 입력하면 대입연산자가 됨
선언된 변수는 기본적으로 전역 변수(global variable)
함수 안에서만 지역 변수(local variable) 사용 가능 -> 그 외에 사용하려면 변수 명 앞에 local
을 붙여주면 됨
변수 명 앞에 export
을 붙여주면 환경 변수(environment variable) 로 설정되어 자식 스크립트에서 사용 가능
-> 환경 변수 사용시 예약 변수 (reserved variable) 에 주의, 환경 변수는 .bash_profile
에서 정의
# 전역 변수 지정
string="hello world"
echo ${string}
# 지역 변수 테스트 함수
string_test() {
# 전역 변수와 동일하게 사용함. 만약 local 뺀다면 전역 변수에 덮어씌어지게 됨
local string="local"
echo ${string}
}
# 지역 변수 테스트 함수 호출
string_test
# 지역 변수 테스트 함수에서 동일한 변수 명을 사용했지만 값이 변경되지 않음
echo ${string}
# 환경 변수 선언
export hello_world="hello world..."
# 자식 스크립트 호출은 스크립트 경로을 쓰면된다.
/home/export_test.sh
#환경 변수를 테스트하기 위해 export_test.sh 파일을 만들고 선언한 변수를 확인해본다.
echo ${hello_world}
HOME
: 사용자의 홈 디렉토리PATH
: 실행 파일을 찾을 경로LANG
: 프로그램 사용 시 기본 지원되는 언어PWD
: 사용자의 현재 작업중인 디렉토리FUNCNAME
: 현재 함수 이름SECONDS
: 스크립트가 실행된 초 단위 시간SHLVL
: 쉘 레벨 (중첩된 깊이를 나타냄)SHELL
: 로그인해서 사용하는 쉘PPID
: 부모 프로세스의 PIDBASH
: BASH 실행 파일 경로BASH_ENV
: 스크립트 실행 시 BASH 시작 파일을 읽을 위치 변수BASH_VERSION
: 설치된 BASH 버전BASH_VERSINFO
: BASH_VERSINFO[0]
~ BASH_VERSINFO[5]
배열로 상세 정보 제공MAIL
: 메일 보관 경로MAILCHECK
: 메일 확인 시간OSTYPE
: 운영체제 종류TERM
: 로긴 터미널 타입HOSTNAME
: 호스트 이름HOSTTYPE
: 시스템 하드웨어 종류MACHTYPE
: 머신 종류 (HOSTTYPE
과 같은 정보지만 조금 더 상세하게 표시됨)LOGNAME
: 로그인 이름UID
: 사용자 UIDEUID
: su
명령에서 사용하는 사용자의 유효 아이디 값 (UID
와 EUID
값은 다를 수 있음)USER
: 사용자의 이름GROUPS
: 사용자 그룹(/etc/passwd
값을 출력)HISTFILE
: history
파일 경로HISTFILESIZE
: history
파일 크기HISTSIZE
: history
저장되는 개수HISTCONTROL
: 중복되는 명령에 대한 기록 유무DISPLAY
: X 디스플레이 이름IFS
: 입력 필드 구분자 (기본값:
-빈칸)VISUAL
: VISUAL 편집기 이름EDITOR
: 기본 편집기 이름COLUMNS
: 현재 터미널이나 윈도우 터미널의 컬럼 수LINES
: 터미널의 라인 수LS_COLORS
: ls
명령의 색상 관련 옵션PS1
: 기본 프롬프트 변수 (기본값:bash\$
)PS2
: 보조 프롬프트 변수 (기본값: >
), 명령을 "\" 를 사용하여 명령행을 연장시 사용됨PS3
: 쉘 스크립트에서 select
사용 시 프롬프트 변수 (기본값: \?
)PS4
: 쉘 스크립트 디버깅 모드의 프롬프트 변수 (기본값: +
)TMOUT
: 0
이면 제한이 없으며 time
시간 지정 시 지정한 시간 이후 로그아웃$0
: 실행된 스크립트 이름$1
: $1 $2 ... ${10}
인자 순서대로 번호가 부여된다. 10번째 부터는 "{}" 감싸야 함$*
: 전체 인자 값$@
: 전체 인자 값 ($*
동일하지만 쌍따옴표로 변수를 감싸면 다른 결과가 나옴)$#
: 매개 변수의 총 개수$$
: 현재 스크립트의 PID$?
: 최근에 실행된 명령어, 함수, 스크립트 자식의 종료 상태$!
: 최근에 실행한 백그라운드(비동기) 명령의 PID$-
: 현재 옵션 플래그$_
: 지난 명령의 마지막 인자로 설정된 특수 변수예시 변수 : string
= "abc-efg-123-abc"
${변수}
: ${변수}
와 동일하지만 {}
사용해야만 동작하는 것들이 있음 (예: echo ${string}
)${변수:위치}
: 위치 다음부터 문자열 추출 (예: echo ${string:4}
)${변수:위치:길이}
: 위치 다음부터 지정한 길이 만큼의 문자열 추출 (예: echo ${string:-HELLO}
)${변수:-단어}
: 변수 미선언 혹은 NULL 일때 기본값 지정, 위치 매개 변수는 사용 불가 ( 예: echo ${string:-HELLO}
)${변수:=단어}
: 변수 미선언 혹은 NULL 일때 기본값 지정, 위치 매개 변수 사용 가능 (예: ehco ${string:=HELLO}
)${변수=단어}
: 변수 미선언 시만 기본값 지정, 위치 매개 변수 사용 가능 (예: echo ${string=HELLO}
${변수:?단어}
: 변수 미선언 혹은 NULL 일때 단어 출력 후 스크립트 종료 (예: echo ${string:?HELLO}
${변수?단어}
: 변수 미선언 시만 단어 출력 후 스크립트 종료${변수:+단어}
: 변수 선언시만 단어 사용 리눅스 쉘 로컬변수
와 환경변수
로 설정된 변수들의 설정을 해제할 수 있는 쉘내부명령어
즉, 로컬변수와 환경변수 및 설정된 함수들의 설정을 메모리에서 제거하는 명령어
unset [-fv] [변수명 ...]
-> 변수명의 사용이 끝나, 그 변수명을 제거하기 위해 사용되는 명령어 (쉘 상태에서도 사용되지만, 주로 쉘스크립트 내에서 사용)
-> 읽기전용 변수에 대해서는 unset
명령어로 제거 불가
-> unset
사용 시 -f
옵션을 사용하면, shell function 의 정의를 제거함
쉘 상태 또는 쉘스크립트 내에서 특정 변수명에 그 값을 할당하기 위해 사용하는 명령어
즉, export
로 할당된 변수들에 대해 unset
은 그 변수를 제거하여 사용하지 못하도록 함
옵션 지정하지 않을 시 -s
옵션과 동일하게 출력 (커널 이름)
-a
옵션은 시스템의 전체 정보를 확인
$ uname -a
Linux ooo 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
>>
or >
https://twpower.github.io/114-difference-between-single-and-double-greater-than-sign
# 출처 : https://blog.gaerae.com/2015/01/bash-hello-world.html
# 배열의 크기 지정없이 배열 변수로 선언
# 'declare -a' 명령으로 선언하지 않아도 배열 변수 사용 가능함
declare -a array
# 4개의 배열 값 지정 (배열 변수 사용은 반드시 괄호를 사용해야 한다.)
array=("hello" "test" "array" "world")
# 기존 배열에 1개의 배열 값 추가(순차적으로 입력할 필요 없음)
array[4]="variable"
# 기존 배열 전체에 1개의 배열 값을 추가하여 배열 저장(배열 복사 시 사용)
array=(${array[@]} "string")
# 위에서 지정한 배열 출력
echo "hello world 출력: ${array[0]} ${array[3]}"
echo "배열 전체 출력: ${array[@]}"
echo "배열 전체 개수 출력: ${#array[@]}"
printf "배열 출력: %s\n" ${array[@]}
# 배열 특정 요소만 지우기
unset array[4]
echo "배열 전체 출력: ${array[@]}"
# 배열 전체 지우기
unset array
echo "배열 전체 출력: ${array[@]}"
Bash 변수는 타입을 구분하지 않고 기본적으로 문자열이다. (단, 문맥에 따라 연산 처리)
declare
, typeset
으로 타입 지정 명령을 지원하지만, 불완전한 형태이므로 주석처리 된 문법을 사용하는 것이 좋다.
# 읽기 전용
# readonly string_variable="hello world"
declare -r string_variable
# 정수
# numver_variable=10
declare -i number_variable=10
# 배열
# array_variable=()
declare -a array_variable
# 환경 변수
# export export_variable="hello world"
declare -x export_variable="hello world"
# 현재 스크립트의 전체 함수 출력
declare -f
# 현재 스크립트에서 지정한 함수만 출력
declare -f 함수이름
문 자 | 설 명 |
---|---|
&& , -a | 논리 AND |
| | , -o | 논리 OR |
산술 연산자는 python 과 동일
문 자 | 설 명 |
---|---|
+ | 더하기 |
- | 빼기 |
* | 곱하기 |
/ | 나누기 |
** | 누승(exponentiation), 거듭제곱(power) |
% | modulo 나 mod (정수 나누기에서 나머지 값) |
+= | 상수값 만큼 증가 (plus-equal) |
-= | 상수값 만큼 감소 (minus-equal) |
*= | 상수값을 곱함 (times-equal) |
/= | 상수값으로 나눔 (slash-equal) |
%= | 상수값으로 나눈 나머지 값(mod-equal) |
문 자 | 설 명 |
---|---|
<< | 비트 왼쪽 쉬프트 ( 쉬프트 한 번당 2를 곱하는 것과 동일 ) |
<<= | left-shift-equal |
>> | 비트 오른쪽 쉬프트 (쉬프트 한 번당 2로 나눔) |
>>= | right-shift-equal(<<=와 반대) |
& | 비트 and |
&= | 비트 and-equal |
| | 비트 OR |
` | =` |
~ | 비트 negate |
! | 비트 NOT |
^ | 비트 XOR |
^= | 비트 XOR-equal |
문 자 | 설 명 |
---|---|
. | 콤마 연산자(comma operator), 2개 이상의 산술 연산을 묶어줌 |
문 자 | 설 명 |
---|---|
-eq | 같음 |
-ne | 같지 않음 |
> , -gt | 더 큼 (> 이중 소괄호에서 사용 가능) |
>= , -ge | 더 크거나 같음 (>= 이중 소괄호에서 사용 가능) |
< , -lt | 더 작음 (< 이중 소괄호에서 사용 가능) |
<= , -le | 더 작거나 같음 (<= 이중 소괄호에서 사용 가능) |
문 자 | 설 명 |
---|---|
= , == | 같음 |
!= | 같지 않음 |
< | ASCII 알파벳 순서에 더 작음 |
> | ASCII 알파벳 순서에 더 큼 |
-z | 문자열이 NULL, 길이가 0인 경우 |
-n | 문자열이 NULL 이 아님 |
문 자 | 설 명 |
---|---|
-e | 파일이 존재 |
-f | 파일이 존재하고 일반 파일인 경우 (디렉토리 혹은 장치파일이 아닌 경우) |
-s | 파일이 존재하고 0보다 큰 경우 |
-d | 파일이 존재하고 디렉토리인 경우 |
-b | 파일이 존재하고 블록장치 파일인 경우 |
-c | 파일이 존재하고 캐릭터 장치 파일인 경우 |
-p | 파일이 존재하고 FIFO 인 경우 |
-h | 파일이 존재하고 한 개 이상의 심볼릭 링크가 설정된 경우 |
-L | 파일이 존재하고 한 개 이상의 심볼릭 링크가 설정된 경우 (위와 동일) |
-S | 파일이 소켓 디바이스인 경우 |
-t | 파일 디스크립터가 열려있고, 터미널 디바이스와 연관이 있음 |
-r | 파일이 존재하고 읽기가 가능한 경우 |
-w | 파일이 존재하고 쓰기가 가능한 경우 |
-x | 파일이 존재하고 실행 가능한 경우 |
-g | 파일이 존재하고 SetGID 가 설정된 경우 |
-u | 파일이 존재하고 SetUID 가 설정된 경우 |
-k | 파일이 존재하고 Sticky bit 가 설정된 경우 |
-O | 자신이 소유자임 |
-G | 그룹 아이디가 자신과 같음 |
-N | 마지막으로 읽힌 후에 변경 됐음 |
file1 -nt file2 | file1 파일이 file2 파일보다 최신임 |
file1 -ot file2 | file1 파일이 file2 파일보다 예전것임 |
file1 -ef file2 | file1 파일과 file2 파일이 같은 파일을 하드 링크하고 있음 |
! | 조건이 안 맞으면 참 (예: ! -e file ) |
_FILE:="/home/Documents/temp.py"
if [ ! -f "$_FILE" ]; then
echo "Missing Python script, ${_FILE}"
return 22
fi
조건은 [ ]
로 감싸준 후 ;
로 마무리
'[' 사이에 공백(스페이스바) 필수
then
뒤 실행 문장 없을 시 오류 발생
fi
작성 시 조건문 종료
https://blog.gaerae.com/2015/01/bash-hello-world.html
https://www.linux.co.kr/bbs/board.php?bo_table=lecture&wr_id=2168&sst=wr_datetime&sod=desc&sop=and&page=24
break
: 반복문을 빠져나갈 때continue
: 현재 반복문이나 조건 건너뜀# 지정된 범위 안에서 반복문 필요 시
for string in "hello" "world" "..."; do
echo ${string}
done
# 수행 조건이 true 일때 실행 (실행 횟수 지정이 필요하지 않은 반복문 필요 시)
count=0
while [ ${count} -le 5 ]; do
echo ${count}
count=$(( ${count}+1 ))
done
# 수행 조건이 false 일때 실행됨 (실행 횟수 지정이 필요하지 않은 반복문 필요 시 좋음)
count2=10
until [ ${count2} -le 5 ]; do
echo ${count2}
count2=$(( ${count2}-1 ))
done
bash script, shell script 관계 없이
for in
/ while
/ until
... do
... done
형식으로 동일하다
Shell Script 반복문 참조
Bash 반복문 참조