Shell Function
shell
함수는 sh -c
형태로 프로세스를 생성하여 shell 명령을 실행합니다
( 실행할 명령이 하나일 경우는 직접 실행 ).
명령 실행 결과 stdout
출력이 반환값이 되는데
이때 make 에 의해 newline 이 모두 space 로 변경되어 하나의 라인으로 됩니다.
trailing newline 이 있을경우 제거되고
stderr
출력은 변경없이 그대로 출력됩니다.
.SHELLFLAGS
변수 설정값도 동일하게 shell 함수 실행시 적용됩니다.
make 4.2.1 버전에 새로 추가된 .SHELLSTATUS
변수를 이용하면 종료 상태 값도 확인할 수 있습니다.
$(info $(shell find /bin/ -name 'p*'))
####### 실행 결과 ######
sh$ find /bin/ -name 'p*'
/bin/pwd
/bin/ping6
/bin/plymouth
/bin/ping4
/bin/pidof
/bin/ps
/bin/ping
sh$ make # stdout 출력은 newline 이 모두 space 로 변경된다.
/bin/pwd /bin/ping6 /bin/plymouth /bin/ping4 /bin/pidof /bin/ps /bin/ping
$(info $(shell date -@; date)) # 오류를 위한 'date -@' 명령
$(info $(.SHELLSTATUS))
$(info ----------------------------)
.SHELLFLAGS += -e # errexit 쉘 옵션 추가
$(info $(shell date -@; date))
$(info $(.SHELLSTATUS))
####### 실행 결과 ######
date: invalid option -- '@' # stderr 출력은 변경없이 그대로 출력된다.
Try 'date --help' for more information.
Sat 08 Jun 2019 07:54:04 PM KST # 두 번째 date 명령은 정상 종료가 되므로
0 # 종료 상태 값은 0 이된다.
----------------------------
date: invalid option -- '@'
Try 'date --help' for more information. # errexit 쉘 옵션 설정에 의해 첫 번째 명령에서
# 쉘이 종료되어 두 번째 date 명령은 실행되지 않는다.
1 # 종료 상태 값은 1 이된다.
multi-line variable 을 사용하더라도 shell 함수에서는
newlne 이 적용되지 않으므로 ;
문자를 사용해야 합니다.
define foo define foo
echo 11111 echo 11111; # ';' 문자를 사용해야 한다.
echo 22222 echo 22222;
echo 33333 echo 33333
endef endef
$(shell { $(foo) ;} >&2) $(shell { $(foo) ;} >&2)
###### 실행 결과 ###### ###### 실행 결과 ######
11111echo 22222echo 33333 11111
22222
33333
만약에 stdout
출력도 newline 을 포함해 그대로 출력하고 싶으면
다음과 같은 방법을 사용할 수 있습니다.
bel != printf '\007'
define nl
endef
$(info aaa$(nl)bbb)
$(info $(subst $(bel),$(nl),$(shell { find /bin/ -name 'p*' ;} | tr '\n' '\a' )))
######## 실행 결과 ########
sh$ make
aaa
bbb
/bin/pwd
/bin/ping6
/bin/plymouth
/bin/ping4
/bin/pidof
/bin/ps
/bin/ping