주로 대표 참조 를 참고해 공부 및 기록 목적으로 작성한 포스팅으로, 현재 맡은 프로젝트에서 필요했던 내용이 추가로 포함되어 있습니다.

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 반복문 참조