- [리눅스 한 학기 살기 #2] curl과 Makefile 제대로 쓰기: 주요 옵션부터 jq 연동·자동 변수까지2025년 03월 17일 23시 42분 44초에 업로드 된 글입니다.작성자: kugorang
TL;DR — 3줄 핵심 요약
• 문제: 서버에 요청을 보내고 응답을 확인하는 일, 소스를 컴파일하는 일은 매번 반복된다. 이 두 반복을 명령 한 줄로 줄이는 도구가 curl과 make다.
• 기술/원인: curl은 libcurl로 URL에 요청을 보내고 응답 바이트를 출력하거나 파일로 저장한다. make는 Makefile의 규칙(타겟: 의존성 → 명령)을 읽고, 의존성 파일의 수정 시각이 더 최신일 때만 명령을 실행한다.
• 해결/인사이트: curl은 -s(조용히) -f(HTTP 오류를 실패로) -L(리다이렉트 추적) -o(파일 저장) 조합과 jq 파이프가 실무 기본형이다. make는 변수·자동 변수($@, $<, $^)·패턴 규칙·.PHONY를 알면 대부분의 빌드를 짧게 쓸 수 있다.
curl: URL에 요청을 보내는 도구

Dash! Do you know curl? Do you know make? 1996년 다니엘 스텐버그가 IRC에서 환율 정보를 자동으로 받기 위해 만든 도구가 시작이다. 처음 이름은 httpget, urlget이었고 지금은 200개가 넘는 옵션과 HTTP/1.1·2·3, HTTPS, FTP, SMTP 등을 지원한다.
curl https://example.com이 한 줄은 TCP 연결 → TLS 협상 → GET 요청 → 응답 수신 → 표준 출력의 순서로 진행된다. 서버가 보낸 본문이 터미널에 그대로 찍힌다.
자주 쓰는 옵션
- -o 파일: 본문을 파일로 저장, -O: URL의 파일명으로 저장
- -X POST: 메서드 지정, -d 'a=1': 본문 전송, -H 'Content-Type: application/json': 헤더 추가
- -u 아이디:비밀번호: 기본 인증
- -v: 요청·응답 헤더와 TLS 과정을 자세히 출력
- -I: 헤더만 받는다
- -L: 3xx 리다이렉트를 따라간다
- -k: 인증서 검증 생략(테스트 전용)
- -s: 진행 표시를 끈다
- -f: HTTP 4xx·5xx를 실패로 처리(스크립트 필수)
- -C -: 중단된 다운로드 이어받기
jq와 조합
curl -s https://api.github.com/repos/flutter/flutter \ | jq '{name, stars: .stargazers_count, forks: .forks_count}'curl은 바이트를 그대로 넘기고 jq가 JSON을 해석해 필요한 필드만 뽑는다. 로그를 남기지 않고 값만 확인할 때 유용하다.
여러 URL 병렬 처리와 성능 측정
cat urls.txt | xargs -P 10 -n 1 curl -O curl -s -w "DNS: %{time_namelookup} Connect: %{time_connect} TTFB: %{time_starttransfer} Total: %{time_total}\n" -o /dev/null https://example.comxargs -P는 동시에 실행할 프로세스 수를 정한다. -w는 각 단계의 시간을 초 단위로 출력하므로, 느린 구간이 DNS인지 연결인지 서버 응답인지 구분할 수 있다.
make: 바뀐 것만 다시 빌드하는 도구
규칙의 구조
타겟: 의존성 명령어 # 반드시 탭으로 시작make는 타겟 파일과 의존성 파일의 수정 시각을 비교한다. 의존성이 더 최신이면 명령을 실행하고, 아니면 아무것도 하지 않는다. 그래서 소스 하나를 고쳐도 전체를 다시 컴파일하지 않는다.
CC = gcc CFLAGS = -Wall -Wextra -Werror OBJS = main.o util.o TARGET = program $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $@ $^ %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f $(OBJS) $(TARGET) .PHONY: clean자동 변수
- $@: 현재 타겟 이름
- $<: 첫 번째 의존성
- $^: 모든 의존성(중복 제거)
- $?: 타겟보다 최신인 의존성만
위 예에서 $(CC) ... -o $@ $^는 "컴파일러로 타겟 이름 파일을 만들고, 의존성 전부를 입력으로 준다"는 뜻이다. 이름을 바꿔도 규칙은 그대로 쓸 수 있다.
자주 쓰는 옵션
- -j4: 4개 작업을 병렬 실행
- -n: 실행할 명령만 보여준다(드라이런)
- -B: 무조건 다시 빌드
- -C 디렉터리: 그 디렉터리에서 실행
- -f 파일: 다른 이름의 Makefile 사용
실무 Makefile의 뼈대
.PHONY: all clean test all: $(TARGET) test: $(TARGET) ./$(TARGET) --test clean: rm -rf obj bin.PHONY는 clean처럼 파일이 아닌 이름을 타겟으로 쓸 때 필요하다. 같은 이름의 파일이 있으면 make가 "이미 최신"이라며 명령을 건너뛰기 때문이다.
함께 쓰는 예: 배포와 상태 확인
deploy: build curl -fsS -X POST -H "Content-Type: application/json" \ -d '{"text":"deploy done"}' $$SLACK_WEBHOOK_URL health: curl -fsS http://localhost:8080/health || (echo "down"; exit 1)빌드는 make가, 배포 알림과 상태 확인은 curl이 맡는다. 실패하면 -f 덕분에 종료 코드가 0이 아니게 되어 CI가 그 단계에서 멈춘다.
자주 묻는 질문 (FAQ)
Q1. curl과 wget은 무엇이 다른가요?
A. wget은 다운로드와 재귀 미러링에 강하고 기본이 파일 저장이다. curl은 요청 구성(메서드·헤더·본문)과 다양한 프로토콜, API 테스트에 강하고 기본이 표준 출력이다. API를 다루면 curl, 사이트 통째로 받으면 wget이 편하다.
Q2. Makefile 명령에서 "missing separator" 오류가 납니다.
A. 명령 줄이 탭이 아니라 공백으로 들여쓰기되어 있다. make는 탭만 명령으로 인식한다. 편집기에서 탭을 공백으로 바꾸는 설정이 켜져 있는지 확인한다.
Q3. make가 아무것도 하지 않고 "up to date"라고만 나옵니다.
A. 타겟이 의존성보다 최신이라고 판단한 것이다. 실제로 바뀐 것이 없다면 정상이다. 강제로 다시 빌드하려면 make -B를 쓰고, 타겟 이름이 파일과 겹치는 문제라면 .PHONY에 추가한다.
728x90728x90'시스템 & 인프라 > Linux & DevOps' 카테고리의 다른 글
다음글이 없습니다.이전글이 없습니다.댓글