nginx 시작 스 크 립 트 분석
87401 단어 nginx
nginx 스 크 립 트 작성
논리 적 사 고 를 정리 하고 nginx 시작 스 크 립 트 를 만 들 려 면 무엇이 필요 합 니까?
nginx 서비스의 조작 은 nginx 서비스의 지원 이 필요 합 니 다. 즉, 서버 에 nginx 서 비 스 를 컴 파일 해 야 합 니 다 .
nginx 시작 스 크 립 트 는 nginx 서비스 시작, 닫 기, 상태 조회, 열 수정 에 편리 한 스 크 립 트 파일 입 니 다.
의존 하 는 파일 몇 개
nginx 스 크 립 트 는 nginx 의 바 이 너 리 시스템 프로그램 파일 에 의존 합 니 다. / usr / sbin / nginx (원본 코드 를 컴 파일 할 때 위 치 를 사용자 정의 하지만 Bash 에서 찾 아야 합 니 다) nginx 는 네트워크 서비스 에 속 하기 때문에 네트워크 카드 정보 총 파일 에 도 의존 합 니 다. / etc / sysconfig / network nginx 서비스 시작 스 크 립 트 는 리 눅 스 커 널 함 수 를 사 용 했 습 니 다. 필요: / etc / rc. d / init. d / functions 함수 파일
다섯 번 째 단 계 를 진행 하기 전에 우 리 는 몇 개의 변 수 를 정의 해 야 한다.
nginx = / usr / sbin / nginx: nginx 바 이 너 리 시스템 파일 정의 prog = ` basename $nainx `: nginx 이름 정의 NGINX_CONFIG_FILE: nginx 메 인 프로필 을 정의 합 니 다. 파일 에 문법 오류 가 있 는 지 확인 하 는 데 사 용 됩 니 다 LOCK_FILE: nginx 잠 금 파일
먼저, 거의 모든 service 시작 스 크 립 트 는 하나의 case 구문 + 몇 가지 함수 입 니 다. 사용자 / 관리자 가 service 서 비 스 를 사용 할 때 $1 인 자 를 전달 하여 서비스 에 대한 다른 조작 을 선택 합 니 다. 즉, start | stop | restart | reload | status 등 입 니 다. 따라서 nginx 도 예외 가 아 닙 니 다. 이 함 수 를 편집 한 다음 에 case 구문 에 추가 합 니 다.
start 함수: nginx 서 비 스 를 시작 합 니 다. 실질 적 으로 nginx 의 바 이 너 리 시스템 파일 에서 nginx 를 시작 합 니 다.
stop 함수: nginx 서 비 스 를 중단 합 니 다. 실질 적 으로 functions 의 killproc 함수 입 니 다.
restart 함수: 서 비 스 를 다시 시작 합 니 다. 실질 적 으로 stop + start 입 니 다.
reload 함수: stop 서 비 스 를 하지 않 는 전제 에서 다시 불 러 옵 니 다. 실질 적 으로 functions 중의 killproc 함수 입 니 다.
status 함수: nginx 운행 상 태 를 봅 니 다. 실질 적 으로 functions 의 함수 를 사 용 했 습 니 다.
force_reload 함수: 강제로 다시 불 러 옵 니 다. 실질 적 으로 stop + start 입 니 다.
case 문장: 명령 행 인자 $1 을 받 아들 이 고 $1 값 에 따라 다른 조작 을 합 니 다 configtest: nginx 메 인 프로필 에 문법 오류 가 있 는 지 확인 하고 다음 단계 로 넘 어 갈 수 있 습 니 다
말 이 많 지 않 으 면 바로 대본 에 올 려 라.
[root@rs2 mnt]# cat nginx_.sh
# chkconfig: - 85 15
# description: nginx is a World Wide Web server. It is used to serve
#
. /etc/rc.d/init.d/functions
#
. /etc/sysconfig/network
#
[[ "$NETWORKING" = "no" ]] && exit 0
#
nginx=/usr/sbin/nginx
prog=$(basename $nginx)
NGINX_CONFIG_NAME="/etc/nginx/nginx.conf"
LOCKFILE="/var/lock/nginx/nginx.lock"
# nginx
configtest() {
$nginx -t
}
#
start() {
configtest
#-x: nginx ,
test -x $nginx || exit 5
#-f: nginx ,
test -f $NGINX_CONFIG_NAME || exit 6
# pid 、lock ,
mkdir -p /var/run/nginx
mkdir -p /var/lock/nginx
# , nginx
echo -n $"Starting $prog :"
# nginx nginx
daemon $nginx -c $NGINX_CONFIG_NAME
# nginx , retval
retval=$?
echo
# 0. ,
test $retval -eq 0 && touch $LOCKFILE
return $retval
}
#
stop() {
# , nginx
echo "Stoping $prog :"
# functions killproc , nginx
killproc $prog -QUIT
# nginx , retval( )
retval=$?
echo
# 0 ,
[ $retval -eq 0 ] && rm -f $LOCKFILE
return $retval
}
#
restart() {
configtest || return $?
stop
sleep 3
start
}
#
reload() {
configtest || return $?
echo -n $"Reloading $prog :"
# stop, ,
killproc $nginx -HUP
retval=$?
echo
}
#
force_reload() {
restart
}
#
rt_status() {
#functions status ,
status $prog
# runing, ,
[ $? -eq 0 ] && echo -n `configtest`
}
case $1 in
status)
rt_status
;;
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reload)
reload
;;
force_reload)
force_reload
;;
*)
# $1 ,
echo "Usage:$prog {start|stop|status|reload|force_reload|restart}"
exit 1
;;
esac
몇 가지 함수 의 분석
셸 스 크 립 트 를 실행 할 때 - x 옵션 을 추가 하면 구체 적 인 커 널 실행 절 차 를 볼 수 있 습 니 다.
start
[root@rs2 mnt]# bash -x nginx_.sh start
+ . /etc/rc.d/init.d/functions # functions
++ TEXTDOMAIN=initscripts
++ umask 022
++ PATH=/sbin:/usr/sbin:/bin:/usr/bin
++ export PATH
++ '[' 2020 -ne 1 -a -z '' ']'
++ /bin/mountpoint -q /cgroup/systemd
++ /bin/mountpoint -q /sys/fs/cgroup/systemd
++ case "$0" in
++ '[' -z '' ']'
++ COLUMNS=80
++ '[' -z '' ']'
++ '[' -c /dev/stderr -a -r /dev/stderr ']'
+++ /sbin/consoletype
++ CONSOLETYPE=pty
++ '[' -z '' ']'
++ '[' -z '' ']'
++ '[' -f /etc/sysconfig/i18n -o -f /etc/locale.conf ']'
++ . /etc/profile.d/lang.sh
++ unset LANGSH_SOURCED
++ '[' -z '' ']'
++ '[' -f /etc/sysconfig/init ']'
++ . /etc/sysconfig/init
+++ BOOTUP=color
+++ RES_COL=60
+++ MOVE_TO_COL='echo -en \033[60G'
+++ SETCOLOR_SUCCESS='echo -en \033[0;32m'
+++ SETCOLOR_FAILURE='echo -en \033[0;31m'
+++ SETCOLOR_WARNING='echo -en \033[0;33m'
+++ SETCOLOR_NORMAL='echo -en \033[0;39m'
++ '[' pty = serial ']'
++ __sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
++ '[' '' = 1 ']'
+ . /etc/sysconfig/network # network
++ HOSTNAME=rs2
+ [[ '' =
\o ]] # , network NETWORKING
+ nginx=/usr/sbin/nginx # nginx
++ basename /usr/sbin/nginx # nginx
+ prog=nginx # prog
+ NGINX_CONFIG_NAME=/etc/nginx/nginx.conf # nginx
+ LOCKFILE=/var/lock/nginx/nginx.lock # lock
+ case $1 in # case
+ start # start , start
+ configtest #start , configtest
+ /usr/sbin/nginx -t #configtest nginx
#
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
+ test -x /usr/sbin/nginx #
+ test -f /etc/nginx/nginx.conf # nginx
+ mkdir -p /var/run/nginx # /var/run/nginx
+ echo -n 'Starting nginx :' #
# nginx nginx
Starting nginx :+ daemon /usr/sbin/nginx -c /etc/nginx/nginx.conf
+ local gotbase= force= nicelevel corelimit
+ local pid base= user= nice= bg= pid_file=
+ local cgroup=
+ nicelevel=0
+ '[' /usr/sbin/nginx '!=' /usr/sbin/nginx ']'
+ '[' -z '' ']'
+ base=nginx
+ __pids_var_run nginx ''
+ local base=nginx
+ local pid_file=/var/run/nginx.pid
+ pid=
+ '[' -f /var/run/nginx.pid ']'
+ return 3
+ '[' -n '' -a -z '' ']'
+ corelimit='ulimit -S -c 0'
+ '[' -n '' ']'
+ '[' -n '' ']'
+ '[' color = verbose -a -z '' ']'
+ '[' -z '' ']'
+ /bin/bash -c 'ulimit -S -c 0 >/dev/null 2>&1 ; /usr/sbin/nginx -c /etc/nginx/nginx.conf'
+ '[' 0 -eq 0 ']'
+ success 'nginx startup'
+ '[' color '!=' verbose -a -z '' ']'
+ echo_success
+ '[' color = color ']'
+ echo -en '\033[60G'
+ echo -n '['
[+ '[' color = color ']'
+ echo -en '\033[0;32m'
+ echo -n ' OK ' //
OK + '[' color = color ']'
+ echo -en '\033[0;39m'
+ echo -n ']'
]+ echo -ne '\r'
+ return 0
+ return 0 # 0
+ retval=0 # retval
+ echo # ,
+ test 0 -eq 0 # 0, 0
+ touch /var/lock/nginx/nginx.lock # lock
+ return 0 # 0,
stop
[root@rs2 mnt]# bash -x nginx_.sh stop
+ . /etc/rc.d/init.d/functions
++ TEXTDOMAIN=initscripts
++ umask 022
++ PATH=/sbin:/usr/sbin:/bin:/usr/bin
++ export PATH
++ '[' 2020 -ne 1 -a -z '' ']'
++ /bin/mountpoint -q /cgroup/systemd
++ /bin/mountpoint -q /sys/fs/cgroup/systemd
++ case "$0" in
++ '[' -z '' ']'
++ COLUMNS=80
++ '[' -z '' ']'
++ '[' -c /dev/stderr -a -r /dev/stderr ']'
+++ /sbin/consoletype
++ CONSOLETYPE=pty
++ '[' -z '' ']'
++ '[' -z '' ']'
++ '[' -f /etc/sysconfig/i18n -o -f /etc/locale.conf ']'
++ . /etc/profile.d/lang.sh
++ unset LANGSH_SOURCED
++ '[' -z '' ']'
++ '[' -f /etc/sysconfig/init ']'
++ . /etc/sysconfig/init
+++ BOOTUP=color
+++ RES_COL=60
+++ MOVE_TO_COL='echo -en \033[60G'
+++ SETCOLOR_SUCCESS='echo -en \033[0;32m'
+++ SETCOLOR_FAILURE='echo -en \033[0;31m'
+++ SETCOLOR_WARNING='echo -en \033[0;33m'
+++ SETCOLOR_NORMAL='echo -en \033[0;39m'
++ '[' pty = serial ']'
++ __sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
++ '[' '' = 1 ']'
+ . /etc/sysconfig/network
++ HOSTNAME=rs2
+ [[ '' =
\o ]]
+ nginx=/usr/sbin/nginx
++ basename /usr/sbin/nginx
+ prog=nginx
+ NGINX_CONFIG_NAME=/etc/nginx/nginx.conf
+ LOCKFILE=/var/lock/nginx/nginx.lock
+ case $1 in
+ stop
+ echo 'Stoping nginx :'
Stoping nginx :
+ killproc nginx -QUIT # killproc , nginx
+ local RC killlevel= base pid pid_file= delay try
+ RC=0
+ delay=3
+ try=0
+ '[' 2 -eq 0 ']'
+ '[' nginx = -p ']'
+ '[' nginx = -d ']'
+ '[' -n -QUIT ']'
+ killlevel=-QUIT
+ base=nginx
+ __pids_var_run nginx ''
+ local base=nginx
+ local pid_file=/var/run/nginx.pid
+ pid=
+ '[' -f /var/run/nginx.pid ']'
+ return 3
+ RC=3
+ '[' -z '' ']'
+ '[' -z '' ']'
++ __pids_pidof nginx
++ pidof -c -m -o 2827 -o 2020 -o %PPID -x nginx
+ pid='2826 2824'
+ '[' -n '2826 2824' ']'
+ '[' color = verbose -a -z '' ']'
+ '[' -z -QUIT ']'
+ checkpid 2826 2824
+ local i
+ for i in '$*'
+ '[' -d /proc/2826 ']'
+ return 0
+ kill -QUIT 2826 2824
+ RC=0
+ '[' 0 -eq 0 ']'
+ success 'nginx -QUIT'
+ '[' color '!=' verbose -a -z '' ']'
+ echo_success
+ '[' color = color ']'
+ echo -en '\033[60G'
+ echo -n '['
[+ '[' color = color ']'
+ echo -en '\033[0;32m'
+ echo -n ' OK '
OK + '[' color = color ']'
+ echo -en '\033[0;39m'
+ echo -n ']'
]+ echo -ne '\r'
+ return 0
+ return 0
+ '[' -z -QUIT ']'
+ return 0
+ retval=0
+ echo
+ '[' 0 -eq 0 ']'
+ rm -f /var/lock/nginx/nginx.lock
+ return 0
여기 포 인 트 는 killproc 함수 입 니 다.
# .
# :
# killproc [-p pidfile] [-d delay] [-signal]
# -p: pid , /var/run/xxx.pid
# -d:
# -signal:
# A function to stop a program.
killproc() {
local RC killlevel= base pid pid_file= delay
# , 。
RC=0; delay=3 # 3 ,
# Test syntax. # , 。
if [ "$#" -eq 0 ]; then
echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]“
# , 。
return 1 # 。
fi
if [ "$1" = "-p" ]; then
# 1, -p , :
# pid_file 。 /var/run/XXX.pid
pid_file=$2
shift 2
fi
if [ "$1" = "-d" ]; then
delay=$2
# 。 ,
# SIGKILL 。
shift 2
fi
# check for second arg to be kill level
# , 。
[ -n "${2:-}" ] && killlevel=$2
# Save basename. # 。
base=${1##*/} # , *** 。
####################################################################
# PID
# Find pid.
__pids_var_run "$1" "$pid_file"
# :__pids_var_run 。
# :PID 。
if [ -z "$pid_file" -a -z "$pid" ]; then
# pidfile , pid 。
# $base PID 。
pid="$(__pids_pidof "$1")"
fi
#####################################################################
# Kill it.
# ,
if [ -n "$pid" ] ; then
# $PID , 。 then
[ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
if [ -z "$killlevel" ] ; then
# , then
if checkpid $pid 2>&1; then
# :checkpid :$PID
# 。 checkpid $PID, /proc
# $PID
# TERM first, then KILL if not dead
kill -TERM $pid >/dev/null 2>&1
# $PID -15 。 ,
# 。
usleep 100000 # 100000
if checkpid $pid && sleep 1 &&
# checkpid , ,
# 1 ,
checkpid $pid && sleep $delay &&
# checkpid , ,
# ,
checkpid $pid ; then
# ,
#checkpid ,
# , 。
kill -KILL $pid >/dev/null 2>&1
# $PID -9 , 。
usleep 100000
fi
fi
checkpid $pid # , $PID 。
RC=$?
# checkpid 。
# :0 $PID 。
[ "$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown"
# checkpid , RC=$((! $RC))
# RC , , , 。
# use specified level only
# :killproc else
else # killproc ,
# else
# , -HUP 。
if checkpid $pid; then # checkpid , $PID ,
kill $killlevel $pid >/dev/null 2>&1
# $PID
RC=$? # checkpid 。
[ "$RC" eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
# $RC $PID
elif [ -n "${LSB:-}" ]; then
RC=7 # Program is not running
fi
fi
###########################
else
if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
RC=7 # Program is not running
else
failure $"$base shutdown"
RC=0
fi
fi
# Remove pid file if any.
if [ -z "$killlevel" ]; then
rm -f "${pid_file:-/var/run/$base.pid}"
fi
return $RC
}
status
[root@rs2 mnt]# bash -x nginx_.sh status
+ . /etc/rc.d/init.d/functions
++ TEXTDOMAIN=initscripts
++ umask 022
++ PATH=/sbin:/usr/sbin:/bin:/usr/bin
++ export PATH
++ '[' 2020 -ne 1 -a -z '' ']'
++ /bin/mountpoint -q /cgroup/systemd
++ /bin/mountpoint -q /sys/fs/cgroup/systemd
++ case "$0" in
++ '[' -z '' ']'
++ COLUMNS=80
++ '[' -z '' ']'
++ '[' -c /dev/stderr -a -r /dev/stderr ']'
+++ /sbin/consoletype
++ CONSOLETYPE=pty
++ '[' -z '' ']'
++ '[' -z '' ']'
++ '[' -f /etc/sysconfig/i18n -o -f /etc/locale.conf ']'
++ . /etc/profile.d/lang.sh
++ unset LANGSH_SOURCED
++ '[' -z '' ']'
++ '[' -f /etc/sysconfig/init ']'
++ . /etc/sysconfig/init
+++ BOOTUP=color
+++ RES_COL=60
+++ MOVE_TO_COL='echo -en \033[60G'
+++ SETCOLOR_SUCCESS='echo -en \033[0;32m'
+++ SETCOLOR_FAILURE='echo -en \033[0;31m'
+++ SETCOLOR_WARNING='echo -en \033[0;33m'
+++ SETCOLOR_NORMAL='echo -en \033[0;39m'
++ '[' pty = serial ']'
++ __sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
++ '[' '' = 1 ']'
+ . /etc/sysconfig/network
++ HOSTNAME=rs2
+ [[ '' =
\o ]]
+ nginx=/usr/sbin/nginx
++ basename /usr/sbin/nginx
+ prog=nginx
+ NGINX_CONFIG_NAME=/etc/nginx/nginx.conf
+ LOCKFILE=/var/lock/nginx/nginx.lock
+ case $1 in
+ rt_status
+ status nginx
+ local base pid lock_file= pid_file=
+ '[' 1 = 0 ']'
+ '[' nginx = -p ']'
+ '[' nginx = -l ']'
+ base=nginx
+ '[' '' = 1 ']'
+ __pids_var_run nginx ''
+ local base=nginx
+ local pid_file=/var/run/nginx.pid
+ pid=
+ '[' -f /var/run/nginx.pid ']'
+ return 3
+ RC=3
+ '[' -z '' -a -z '' ']'
++ __pids_pidof nginx
++ pidof -c -m -o 2984 -o 2020 -o %PPID -x nginx
+ pid='2983 2981'
+ '[' -n '2983 2981' ']'
+ echo 'nginx (pid 2983 2981) is running...'
nginx (pid 2983 2981) is running...
+ return 0
+ '[' 0 -eq 0 ']'
++ configtest
++ /usr/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
+ echo -n
여기 서 포 인 트 는 status 함수 입 니 다:
# :
# :
status [-p pidfile] {program}
status() {
local base pid pid_file=
# Test syntax. # 。
if [ "$#" = 0 ] ; then
echo $"Usage: status [-p pidfile] {program}"
# : ,
# 。 :1
return 1
fi
if [ "$1" = "-p" ]; then
pid_file=$2
shift 2
fi
base=${1##*/} # $base 。
# First try "pidof"
__pids_var_run "$1" "$pid_file"
# :__pids_var_run 。
RC=$?
if [ -z "$pid_file" -a -z "$pid" ]; then
# status , pidfile , PID
pid="$(__pids_pidof "$1")"
# , PID
# /var/run/$base.pid 。 __pids_pidof PID
fi
####################################################################
if [ -n "$pid" ]; then
# PID , 。
echo $"${base} (pid $pid) is running..."
return 0
fi
case "$RC" in
# :__pids_var_run , 。
0)
echo $"${base} (pid $pid) is running..."
return 0
;;
1)
echo $"${base} dead but pid file exists"
# :__pids_var_run :1 , ....
return 1
;;
esac
#####################################################################
# See if /var/lock/subsys/${base} exists # *** 。
if [ -f /var/lock/subsys/${base} ]; then
echo $"${base} dead but subsys locked"
return 2
fi
echo $"${base} is stopped"
return 3
reload
kilproc 함 수 를 중점적으로 사 용 했 습 니 다.
기타 세부 사항
service 에 추가 하려 면:
chkconfig 명령 추가 스 크 립 트 는 지정 한 위치 에 두 어야 합 니 다: / etc / rc. d / init. d 디 렉 터 리 에 있 고 이름 은 nginx (실행 권한 부여 주의) 입 니 다.
스 크 립 트 에는 service 알림 정보 (있어 야 합 니 다!!) 스 크 립 트 에 다음 두 줄 의 데 이 터 를 추가 합 니 다:
# chkconfig: - 85 15
# description: nginx is a World Wide Web server. It is used to serve
chkconfig 명령 을 실행 하고 서비스 추가
[root@rs2 mnt]# cp nginx_.sh /etc/rc.d/init.d/nginx
[root@rs2 mnt]# chmod +x /etc/rc.d/init.d/nginx
[root@rs2 mnt]# chkconfig --add /etc/rc.d/init.d/nginx
테스트 해 보기:
[root@rs2 ~]# service nginx status
nginx.service - SYSV: nginx is a World Wide Web server. It is used to serve
Loaded: loaded (/etc/rc.d/init.d/nginx)
Active: active (running) since Sat 2018-07-14 02:11:24 CST; 17s ago
Process: 3217 ExecStart=/etc/rc.d/init.d/nginx start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/nginx.service
├─3223 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.c...
└─3225 nginx: worker process
Jul 14 02:11:24 rs2 systemd[1]: Starting SYSV: nginx is a World Wide Web se.....
Jul 14 02:11:24 rs2 nginx[3217]: nginx: the configuration file /etc/nginx/n...ok
Jul 14 02:11:24 rs2 nginx[3217]: nginx: configuration file /etc/nginx/nginx...ul
Jul 14 02:11:24 rs2 nginx[3217]: Starting nginx :[ OK ]
Jul 14 02:11:24 rs2 systemd[1]: Started SYSV: nginx is a World Wide Web ser...e.
Jul 14 02:11:35 rs2 systemd[1]: Started SYSV: nginx is a World Wide Web ser...e.
Hint: Some lines were ellipsized, use -l to show in full.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
자신 이 쓴 스 크 립 트 가 가득 한 스타일...
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
간단! Certbot을 사용하여 웹 사이트를 SSL(HTTPS)화하는 방법초보자가 인프라 주위를 정돈하는 것은 매우 어렵습니다. 이번은 사이트를 간단하게 SSL화(HTTP에서 HTTPS통신)로 변경하는 방법을 소개합니다! 이번에는 소프트웨어 시스템 Nginx CentOS7 의 환경에서 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.