오픈 소스 비영리 기관 'Open Source Initiative'의 로고. https://opensource.org/
본 글은 학교 '오픈소스 소프트웨어 입문' 과목을 수강하며 실습(또는 공부)한 내용을 정리한 글입니다.
개인 기록 용도로 작성한 글이라, 직접 이 글을 보고 실습을 따라하기엔 어려움이 많을 것으로 예상됩니다.
혹시 본 글을 보며 Linux를 공부하실 목적이라면, 일단 키워드 위주로 AI에게 물어봐가면서, 본인의 Linux 터미널에서 직접 타이핑해가며 공부하시기를 추천드립니다.
질문이나 의견이 있다면 자유롭게 댓글 달아주세요!
# 250410 Execution 복습
foss110@ajousw:~$ mkdir lab0410 ; cd lab0410
foss110@ajousw:~/lab0410$ cd ..
foss110@ajousw:~$ mkdir lab0410 ; cd lab0410
mkdir: cannot create directory ‘lab0410’: File exists
foss110@ajousw:~/lab0410$
-> 결국, ;는 앞에 꺼가 성공하든 안성공하든(에러가 나든 안나든)
앞에 명령어 실행이 끝나면 뒤의 명령어를 무조건 실행한다!
foss110@ajousw:~$ mkdir lab0410 && cd lab0410
mkdir: cannot create directory ‘lab0410’: File exists
foss110@ajousw:~$ mkdir lab0410 || cd lab0410
mkdir: cannot create directory ‘lab0410’: File exists
foss110@ajousw:~/lab0410$
-> &&와 ||는 각각 앞에 꺼가 성공해야, 앞에 꺼가 실패해야 뒤에 꺼도 실행
이걸 응용하면, ls lab0410 && rmdir lab0410 이런 식으로도 가능.
---
sleep 2 ; sleep 3 ; sleep 4 ; echo end
-> 얘는 9초 걸려야 echo가 실행됨.
앞에 꺼가 끝나야 실행되니까.
sleep 2 & sleep 3 & sleep 4 & echo end
-> 얘는 바로 echo가 실행됨!!
백그라운드 프로세스가 & 붙을 때마다 하나씩 더 생겨나는 것.
sleep 2 & sleep 3 & sleep 4 ; echo end
-> 이러면 4초 뒤에 echo 실행됨.
sleep 2 ; sleep 3 & sleep 4 ; echo end
-> 얘는 sleep 2가 fg로 되면서 그거 끝난 뒤에,
sleep 3가 bg로 돌기 시작하면서 동시에 sleep 4 fg 실행.
{ sleep 2 ; sleep 3 ; echo 5sec ; } & { sleep 4 ; echo end 4sec ; } &
-> 이러면 5초짜리와 4초짜리 백그라운드 작업이 두 개 도는 거임. 동시에 돌기 시작.
그리고 뒤에 echo가 먼저 실행됨.
# 250410 실습시작! Execution부터 복습
vi simple.sh
echo VVV is $VVV
foss110@ajousw:~/lab0410$ VVV=100 source simple.sh
VVV is 100
foss110@ajousw:~/lab0410$echo $VVV
-> 이렇게 쓰는 걸, '한정적 변수'라고 함.
foss110@ajousw:~/lab0410$VVV=100 ; source simple.sh
VVV is 100
foss110@ajousw:~/lab0410$ echo $VVV
100
-> 아까랑 달리, 얘는 세미콜론을 썼기에 한정적 변수 문법이 적용되지 않음.
! 중간고사 !
simple.sh 파일이 다음과 같았다.
저렇게 실행했을 때,
echo $VVV 실행 결과를 쓰시오.
-> VVV is 100
-> 그 다음은 상황에 맞게 안 쓰거나 100.
# Quote and Variable 복습
# Variable
foss110@ajousw:~/lab0410$ A=100 a=200
foss110@ajousw:~/lab0410$ echo $A
100
foss110@ajousw:~/lab0410$ echo $a
200
변수 저렇게 여러 개 한꺼번에 설정 가능.
세미콜론 넣어도 상관은 없음.
변수 지우는 두 가지 방법이 있음.
1. A=""
-> 이건 사실 지워진 게 아님. null string을 설정한 변수가 된 것.
2. unset하기 - 이게 진짜 지우는 거.
2.1. unset -v A (Variable only)
2.2. unset A (Variable or function)
-> 내가 저걸 변수로 지정했는지 함수로 지정했는지 헷갈릴 땐 알아서 골라서 써라. 변수일 때만 지우고 싶으면 위에 꺼 쓰던가.
compgen -A variable
-> list all name
compgen -A variable | grep PWD
-> 이런 식으로 grep 사용 가능
foss110@ajousw:~/lab0410$ PWD="/tmp"
foss110@ajousw:/tmp$ pwd
/home/course/foss/foss110/lab0410
foss110@ajousw:/tmp$ ls
simple.sh
PWD="/tmp"
-> 이게 cd 명령어임.
cd는 누가 짜둔 게 아니라, bash에 '음~ cd하고 path가 나오면,
그게 실제 있는 디렉토리고 permission이 있으면,
PWD를 그 path로 바꿔놓자~' 하고 짜둔 거임.
근데, 위처럼 보면 쉘 프롬포트상으론 cd가 일어난 것 같으나,
pwd와 ls를 쳐 보면, cd가 실제론 일어나지 않았다는 걸 알 수 있음.
그래서 좀 이상해지니까 쓰지 마라. 잘못 쓰면 문제가 발생할 수 있으니, built-in command들은 직접 set하지 마라.
echo $PWD 하면 /tmp가 뜨긴 하나, cd가 일어나진 않은거. 왜냐면 ls는 원래 그거 뜨니까.
다시 cd . 하면 lab0410으로 돌아옴.
여기서 알 수 있는건, PWD 변수 값을 가지고 쉘 프롬포트를 구성한다는 것.
---
진도 시작
# Value : $ - $에 대해 공부해보자.
## expansion
우리가 어떤 값을 볼 건데, 고쳐 보고 싶을 때 expansion을 사용.
### 1. ${ } - Variable expansion : FOO="foo.cpp"; echo ${FOO%.cpp} # foo
변수 확장을 하는 거. $F00 하던 거에 뭔가 추가적으로 적용을 하고 싶다. 묶어준 거임.
좀 더 유연하고 강력하게 변수를 다룰 수 있게 해줌.
%.cpp는 .cpp를 떼어내고, 그 나머지를 출력하겠다.
### 2. $(( )) - Numerical expansion : echo $((100+200))
숫자적으로 expansion을 한다.
!중간고사!
foss110@ajousw:~/lab0410$ echo $VVV
100
foss110@ajousw:~/lab0410$ VVV=$VVV+$VVV
foss110@ajousw:~/lab0410$ echo $VVV
100+100
즉, 변수는 문자열로 저장됨.
근데 이걸 숫자 확장을 하고 싶으면?
foss110@ajousw:~/lab0410$ VAL=$VVV+$VVV
foss110@ajousw:~/lab0410$ echo $VAL
100+100
foss110@ajousw:~/lab0410$ echo $(( $VAL ))
200
foss110@ajousw:~/lab0410$ echo $VAL
100+100
여기서 출력된 200은 숫자 200이 아닌, 문자열 "200"임.
foss110@ajousw:~/lab0410$ VAL=$(( $VVV+$VVV ))
foss110@ajousw:~/cfile$ echo $VAL
200
이렇게도 가능.
foss110@ajousw:~/lab0410$ echo $(( 200 + 300 * 5 ))
1700
foss110@ajousw:~/lab0410$ echo $(( 200 + $VVV * 5 ))
700
foss110@ajousw:~/lab0410$ echo $(( 200 + $VVV * 0.5 ))
-bash: 200 + 100 * 0.5 : syntax error: invalid arithmetic operator (error token is ".5 ")
이렇게 다양한 사칙연산 가능.
단, floating point 지원 x.
### 3. $( ) - Command substitution : a=$(date) # a=`date`
stdout으로 출력될 그 명령어의 결과물을, 잡아서 쓸 수 있게 만들어주는 거임.
date
-> 시스템에 설정된 시간을 보여줍니다.
근데, 그 결과를 변수에 저장하고 싶으면?
D=$( date )
foss110@ajousw:~/lab0410$ D=$( date )
foss110@ajousw:~/lab0410$ echo $D
Thu 10 Apr 2025 09:28:41 AM KST
foss110@ajousw:~/lab0410$ D=`date`
foss110@ajousw:~/lab0410$ echo $D
Thu 10 Apr 2025 09:29:01 AM KST
이렇게 ``처럼 백틱으로 감싸도 가능.
이거 다음처럼 유용하게 쓸 수 있음.
foss110@ajousw:~/lab0410$ which cc
/usr/bin/cc
foss110@ajousw:~/lab0410$ ls -l `which cc`
lrwxrwxrwx 1 root root 20 Jul 26 2024 /usr/bin/cc -> /etc/alternatives/cc
foss110@ajousw:~/lab0410$ ls -l $( which cc )
lrwxrwxrwx 1 root root 20 Jul 26 2024 /usr/bin/cc -> /etc/alternatives/cc
이렇게 해도 동일.
### 4. $' ' - processing escape expansion # echo -e "aa\nbb" == echo $'aa\nbb'
문자열 안의 이스케이프 시퀀스를 자동으로 해석해주는 확장 방식
나 두 줄로 출력하고 싶은데, 또는 두 줄짜리 변수를 할당하고 싶으면 저 $'\' 쓰면 됨
저거 왼쪽처럼 큰따옴표에 -e ""도 가능(시험x)
'$ '랑 다른 거임에 유의
## Special Values
특별하게 설정되어 있는 변수들이 있음.
$? - previous exit status # 직전에 실행한 명령어의 종료 상태(exit status)
$! - PID of last bg jobs # 마지막으로 실행된 백그라운드 프로세스의 PID
$$ - PID of current shell # 현재 셸의 프로세스 ID (PID)
$0 - Filename of shell script # 실행된 셸스크립트의 이름 (명령어 자체)
$1~n - Arguments # 스크립트에 넘겨준 인자(argument), argv
$* # 모든 인자를 "한 문자열로" 처리
$@ # 모든 인자를 각각 독립된 문자열로 취급
$# - Number of Argument # 넘겨진 인자의 개수, argc
$_ - Last argument # 직전에 실행한 명령의 마지막 인자
$- - Shell settings enabled # 현재 셸의 옵션 상태 (set으로 설정된 것들)
!중간고사!
다음을 출력하는 쉘 스크립트를 짜보시오.
vi special.sh
echo '$?: ' $? # 직전에 실행한 멸령어의 exit status
echo '$!: ' $! # 마지막으로 실행된 bg의 pid
echo '$$: ' $$ # 현재 쉘의 pid
echo '$0: ' $0 # 쉘스크립트 이름
echo 'ARGS :' $1 $2 $3 $4 $5 # 넘겨준 인자
echo 'ALL ARGS $* :' $* # 모든 인자를 한 문자열로 처리
echo 'ALL ARGS $@ :' $@ # 각 인자를 독립된 몬자열로 처리
echo 'argc :' $# # 넘겨준 인자 개수
echo 'LAST $_' $_ # 직전 실행 명령의 마지막 인자
echo 'shopt : ' $- # 현재 쉘의 옵션 상태
foss110@ajousw:~/lab0410$ sleep 1 &
[1] 145436
foss110@ajousw:~/lab0410$ ls
mid simple.sh special.sh
[1]+ Done sleep 1
foss110@ajousw:~/lab0410$ source special.sh
$?: 0
$!: 145436
$$: 139589
$0: -bash
ARGS :
ALL ARGS $* :
ALL ARGS $@ :
argc : 0
LAST $_ 0
shopt : himBHs
foss110@ajousw:~/lab0410$ls vbb
ls: cannot access 'vbb': No such file or directory
foss110@ajousw:~/lab0410$ source special.sh
$?: 2 # 오류 났음. 2: Misuse of shell builtins (내장 명령어 오용 등)
$!: 145436
$$: 139589
$0: -bash
ARGS :
ALL ARGS $* :
ALL ARGS $@ :
argc : 0
LAST $_ 0
shopt : himBHs
foss110@ajousw:~/lab0410$sleep 100 &
[1] 146798
foss110@ajousw:~/lab0410$ source special.sh
$?: 0
$!: 146798
$$: 139589
$0: -bash
ARGS :
ALL ARGS $* :
ALL ARGS $@ :
argc : 0
LAST $_ 0
shopt : himBHs
-> 가장 최근에 실행한 bg pid 알 수 있다.
foss110@ajousw:~/lab0410$chmod 755 special.sh
foss110@ajousw:~/lab0410$ ./special.sh
$?: 0
$!: 146798
$$: 146966
$0: ./special.sh # -bash가 아닌 이게 나옴.
ARGS :
ALL ARGS $* :
ALL ARGS $@ :
argc : 0
LAST $_ 0
shopt : hBH
! 중간고사 ! - 1
./special.sh aaa bbbb ccc
-> argc 값?
foss110@ajousw:~/lab0410$ ./special.sh aaa bbbb ccc
$?: 0
$!: 146798
$$: 147260
$0: ./special.sh
ARGS : aaa bbbb ccc
ALL ARGS $* : aaa bbbb ccc
ALL ARGS $@ : aaa bbbb ccc
argc : 3 # 인자 개수 3개
LAST $_ 3 # 여기서 이게 3이 나온 건, echo 'argc :' $#이라는 명령어의 마지막 인자가 3이었기 때문임. 'argc :'라는 문자열과, $#의 결과인 3 총 두 개가 인자로 echo에 전달된 거.
shopt : hBH
!중간고사! - 2 (1 다음 바로 이거 나옴)
./special.sh "aaa bbbb ccc"
-> argc 값?
foss110@ajousw:~/lab0410$ ./special.sh "aaa bbbb ccc"
$?: 0
$!: 146798
$$: 149378
$0: ./special.sh
ARGS : aaa bbbb ccc
ALL ARGS $* : aaa bbbb ccc
ALL ARGS $@ : aaa bbbb ccc
argc : 1 # 1이 나옴.
LAST $_ 1
shopt : hBH
### shopt 간단 확인
shopt -> 쉘 설정 값이 나옴.
echo $- 결과가 지금 shopt hBH가 나왔잖음. 저게 교수도 뭔 진 모름.
보면
globstar off
가 되어 있음.
이러면 ** 패턴이 제대로 작동하지 않음.
shopt -s globstar
shopt globstar
globstar on
근데 사실 지금 우리 쉘에서는 off되어있어도 잘 작동함. 내 로컬에서도. 왠지는 모르겠다.
shopt말고 다른 쉘 세팅도 있다.
set -l 어쩌고? -> 나중에 배우셈 ppt에 있음.
아마 그걸 hBH가 말하는 것 같다.
수업 나중에 다시 해주겠다.
'Tools and Utilities > Linux' 카테고리의 다른 글
[Shell Script 실습] Ch5. 글로빙 및 shopt와 중괄호 확장(Globbing, shopt and Curly bracket(brace) Expansion) (0) | 2025.04.16 |
---|---|
[Linux] Windows 11에서 WSL2 설치하고 VSCode 연동하기 (0) | 2025.04.14 |
[Shell Script 실습] Ch3. 실행과 그룹핑(Execution and Grouping) (0) | 2025.04.10 |
[Shell Script 실습] Ch2. 따옴표와 변수 설정(Quote and Variable) (0) | 2025.04.10 |
[Shell Script 실습] Ch1. 배쉬 쉘 스크립트 기초들(Bash Shell Script Basics) (0) | 2025.04.09 |