wget
파일을 다운로드하는 데 사용됩니다. 예:
# 下载首页html
wget http://ayqy.net
# 下载多个文件
wget http://www.example.com http://ayqy.net
위의 예에서 www가 없는 주소는 301을 반환하며, wget은 자동으로 이를 추적하여 index.html을 다운로드하고 현재 디렉토리에 저장합니다. 기본 파일명은 동일하며, 이미 존재할 경우 자동으로 접미사가 붙습니다.
2가지 URL 형식을 지원합니다:
# http
http://host[:port]/directory/file
# ftp
ftp://host[:port]/directory/file
# 带用户名密码验证的
http://user:password@host/path
ftp://user:password@host/path
# 或者
wget --user=user --password=password URL
저장할 파일명은 -O 옵션으로 지정합니다:
# 输出到文件
wget http://ayqy.net -O page.html
# -表示标准输出
wget http://ayqy.net -O -
주의: 반드시 대문자 O여야 합니다. 소문자 o는 진행 정보 및 오류 메시지를 지정된 로그 파일에 기록함을 의미합니다. 지정된 파일이 이미 존재하면 덮어쓰게 됩니다.
기타 자주 사용되는 옵션:
# POST
wget --post-data 'a=1&b=2' http://www.example.com
# 或者
wget --post-file post-body.txt http://www.example.com
# 断点续传
wget -c http://www.example.com
# 错误重试3次
wget -t 3 http://www.example.com
# 下载限速1k,避免占满带宽
wget --limit-rate 1k http://www.example.com
# 限制总下载量,避免占太多磁盘空间
wget -Q 1m http://www.example.com http://www.example.com
P.S. 총 다운로드 용량 제한은 서버에서 제공하는 Content-Lengt에 의존하며, 제공되지 않으면 제한할 수 없습니다.
또한 wget에는 매우 강력한 크롤러 기능이 있습니다:
# 递归爬取所有页面,逐个下载
wget --mirror http://www.ayqy.net
# 指定深度1级,要和-r递归选项一起使用
wget -r -l 1 http://www.ayqy.net
증분 업데이트도 가능하여 새 파일(로컬에 없거나 마지막 수정 시간이 갱신된 파일)만 다운로드할 수 있습니다:
# -N比较时间戳增量更新,只下载新文件
wget -N http://node.ayqy.net
서버 파일이 변경되지 않으면 다음번에 다운로드하지 않고 다음과 같이 표시됩니다:
Server file no newer than local file `index.html' -- not retrieving.
P.S. 물론 증분 업데이트는 서버에서 제공하는 Last-Modified에 의존하며, 제공되지 않으면 증분 업데이트를 할 수 없고 기본적으로 다운로드하여 덮어씁니다.
P.S. wget에 대한 더 자세한 정보는 GNU Wget 1.18 Manual을 확인하세요.
curl
wget보다 강력하며, 파일 다운로드뿐만 아니라 요청(GET/POST/PUT/DELETE/HEAD 등) 전송, 요청 헤더 지정 등이 가능하며 HTTP, HTTPS, FTP 등 다양한 프로토콜과 Cookie, UA, 인증(Authentication) 등을 지원합니다.
RESTful API 테스트에 자주 사용됩니다:
# 增
curl -X POST http://localhost:9108/user/ayqy
# 删
curl -X DELETE http://localhost:9108/user/ayqy
# 改
curl -X PUT http://localhost:9108/user/ayqy/cc
# 查
curl -X GET http://localhost:9108/user/ayqy
POST 폼 제출:
# 模拟表单提交
curl -d 'a=1&b=2' --trace-ascii /dev/stdout http://www.example.com
# 请求头和请求体
=> Send header, 148 bytes (0x94)
0000: POST / HTTP/1.1
0011: Host: www.example.com
0028: User-Agent: curl/7.43.0
0041: Accept: */*
004e: Content-Length: 7
0061: Content-Type: application/x-www-form-urlencoded
0092:
=> Send data, 7 bytes (0x7)
0000: a=1&b=2
-d는 --data-ascii를 의미하며, 다른 3가지 방식은 --data-raw, --data-binary, --data-urlencode가 있습니다. 그중 --data-urlencode는 매개변수 값을 인코딩합니다.
--trace-ascii는 요청/응답 헤더와 본문을 출력하는 데 사용되거나, 프록시 도구를 통해 요청 내용을 확인하는 데 사용됩니다:
# -x或者--proxy走代理,否则抓不着
curl -d 'a=1&b=2' -x http://127.0.0.1:8888 http://www.example.com
wget처럼 파일을 다운로드할 수도 있지만, 기본적으로 파일에 쓰는 대신 표준 출력으로 출력합니다:
# 直接输出响应内容
curl http://ayqy.net
301 리다이렉트 페이지를 받게 되며 curl은 자동으로 추적하지 않습니다. 이를 이용해 리다이렉션을 추적할 수 있습니다(물론 직접 패킷을 캡처해서 보는 것이 더 직관적입니다).
파일 다운로드는 출력 리다이렉션 또는 -o 옵션을 통해 수행할 수 있습니다:
# 写入文件,默认会输出进度信息
curl http://ayqy.net > 301.html
# 或者
curl http://ayqy.net -o 301.html
# 使用URL中的文件名
curl http://ayqy.net/index.html -O
# URL中没有文件名的话无法下载
curl http://ayqy.net -O
# 静默下载,不输出进度信息
curl http://ayqy.net --silent -o 301.html
흥미로운 명령 하나:
# curl安装nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
매개변수 o의 값이 -이면 표준 출력으로 리다이렉션됨을 의미하며, 파이프를 통해 bash 명령에 전달되어 실행됩니다. 전체 줄의 역할은 온라인 bash 스크립트를 가져와 실행하는 것입니다.
wget의 경우도 유사합니다:
# wget安装nvm
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
-q 옵션은 메시지 출력을 억제하여 결과가 깔끔하게 나오도록 하고, -O -는 표준 출력으로 리다이렉션하여 bash 명령으로 전달합니다.
curl의 강력한 점은 요청 헤더 필드 값을 수정할 수 있다는 것입니다:
# 指定referer字段
curl --referer http://ayqy.net http://node.ayqy.net
# 设置cookie
curl -v --cookie 'isVisted=true' http://localhost:9103
# 或者,用-H设置任意头字段
curl -v -H 'Cookie: isVisted=true' http://localhost:9103
curl -v -H 'Cookie: isVisted=true' -H 'Referer: http://a.com' http://localhost:9103
# 把返回的cookie写入文件
curl http://localhost:9103 -c cookie.txt
# 设置UA
curl -v -A 'hello, i am android' 'http://localhost:9105'
기타 특성 및 옵션:
# 显示下载进度条
curl http://ayqy.net --progress -o 301.html
# 断点续传
# 手动指定偏移量,跳过15个字节,DOCTYPE声明被跳过了
curl http://node.ayqy.net -C 15
# 自动计算偏移量(类似于wget -c)
curl http://node.ayqy.net -C -
# 下载限速(不重定向到文件的话,输出到标准输出也会限速)
curl http://www.ayqy.net > ayqy.html --limit-rate 1k
# 限制总下载量
curl http://node.ayqy.net --max-filesize 100
# 用户名密码验证
curl -v -u username:password http://example.com
# 只输出响应头
# www少很多字段
curl -I http://node.ayqy.net
curl -I http://www.ayqy.net
이미지 일괄 다운로드
curl을 이용하면 다음과 같은 간단한 작업을 쉽게 완료할 수 있습니다:
#!/bin/bash
# 批量下载图片
# 参数数量检查
if [ $# -ne 3 ];
then
echo 'Usage: -d <dir> <url>'
exit 1
fi
# 取出参数
for i in {1..3};
do
case $1 in
-d) shift; dir=$1; shift;;
*) url=${url:-$1}; shift;;
esac
done
# 截取基url
baseurl=$(echo $url | egrep -o 'https?://[a-z.]+')
# 取源码,滤出img,提取src
tmpFile="/tmp/img_url_$$.tmp"
curl $url --silent \
| egrep -o '<img\s.*src="[^"]+\"[^>]*>' \
| sed 's/.*src="\([^"]*\)".*/\1/g' \
> $tmpFile
echo "save image urls to $tmpFile"
# 相对根路径转绝对路径
sed -i '' "s;^/;$baseurl;g" "$tmpFile"
# 创建目录
mkdir -p $dir
cd $dir
# 下载图片
while read imgUrl;
do
filename=${imgUrl##*/}
curl $imgUrl --silent > "$filename"
echo "save to $dir/$filename"
done < "$tmpFile"
echo 'done'
위의 스크립트를 실행하여 Pengfu(捧腹) 이미지를 가져옵니다:
./imgdl.sh http://www.pengfu.com -d imgs
핵심 부분은 매우 간단합니다. 소스 코드를 가져와 img 태그를 찾고 src를 추출한 뒤 순회하며 다운로드합니다. 매개변수를 가져오는 부분에 팁이 하나 있습니다:
# 取出参数
for i in {1..3};
do
case $1 in
-d) shift; dir=$1; shift;;
*) url=${url:-$1}; shift;;
esac
done
여기서 shift 명령은 명령 매개변수($1...n)의 첫 번째 요소를 꺼내는 데 사용되며, 다른 언어에서 배열의 shift 메서드와 동일한 의미를 가집니다. 첫 번째 요소를 제거하고 나머지 요소들을 앞으로 당기므로, 루프 안에서 첫 번째 요소인 $1만 판단하면 됩니다. case로 매개변수 이름과 값을 매칭하며, 하나 읽고 하나 삭제하는 방식으로 매번 첫 번째를 읽습니다. 예를 들어 매개변수가 -d <dir>와 같은 키-값 쌍 형식이라면, 먼저 shift로 -d를 제거하고 이어서 <dir>를 읽은 뒤, 읽기가 끝난 <dir>도 shift로 제거하고 다음 매개변수를 읽으러 갑니다.
이렇게 매개변수를 읽는 것의 장점은 매개변수 순서에 제한이 없다는 것입니다. 물론 키-값 쌍 형식의 매개변수는 붙어 있어야 하지만, 각 매개변수 간의 순서는 상관없습니다.
여기서 ${url:-$1}은 변수 url이 존재하고 비어 있지 않으면 url 값을 사용하고, 그렇지 않으면 $1 값을 사용함을 의미합니다. 이 기능은 매개변수 확장(parameter expansion)이라고 합니다:
${parameter:-word}
parameter가 정의되지 않았거나 비어 있으면 word 값을 취하고, 그렇지 않으면 parameter 값을 취합니다.
${parameter:=word}
기본값을 설정하는 데 사용됩니다. parameter가 정의되지 않았거나 비어 있으면 word 값을 parameter에 할당합니다. 위치 매개변수(positional parameters, 예: $0, $1, $2..$n)와 특수 매개변수에는 이러한 할당이 허용되지 않습니다(읽기 전용이기 때문).
${parameter:?word}
변수가 정의되지 않았거나 비어 있는 오류를 확인하는 데 사용됩니다. parameter가 정의되지 않았거나 비어 있으면 word를 표준 오류에 그대로 출력하고(예: parameter: word, word가 주어지지 않으면 parameter null or not set 출력), 대화형 시나리오가 아니라면 스크립트를 즉시 종료합니다. parameter가 존재하고 비어 있지 않으면 parameter 값을 취합니다.
${parameter:+word}
변수의 존재 여부를 확인하는 데 사용됩니다. parameter가 정의되지 않았거나 비어 있으면 빈 값을 취하고, 그렇지 않으면 word 값을 취합니다.
또한 :이 없는 4가지 버전이 더 있는데, 이는 parameter가 비어 있을 수 있음을 의미합니다.
P.S. 매개변수 확장에 대한 더 자세한 정보는 Bash Reference Manual: Shell Parameter Expansion을 확인하세요.
아직 댓글이 없습니다