curl در مقابل wget: کدوم رو کِی استفاده کنیم
حدود ۴ دقیقه مطالعه
اگه تا حالا تو ترمینال یه فایل دانلود کردی یا یه API رو تست کردی، احتمالاً با هر دوی این ابزارها برخورد داشتی. هر دو کارشون رفتن سراغ یه URL و گرفتن داده از اونه، و تو خیلی از موارد ساده، هر کدوم رو که استفاده کنی فرقی نمیکنه. ولی وقتی پای موارد پیچیدهتر وسط بیاد، این دو تا فلسفهی کاملاً متفاوتی دارن که دونستنش از انتخاب اشتباه و کلنجار رفتن با فلگهای اضافه جلوگیری میکنه.
فلسفهی طراحی این دو فرق داره
wget از اول برای یه کار مشخص ساخته شده: دانلود فایل، بهخصوص دانلودهای بزرگ و طولانی که ممکنه قطع بشن. به همین خاطر ویژگیهایی مثل ادامه دادن دانلود ناقص، دانلود recursive (گرفتن یه سایت کامل با تمام لینکهاش)، و کار کردن بدون نیاز به یه session تعاملی جزو ذات wget هستن.
curl از اول یه چیز دیگه بود: یه ابزار برای انتقال داده با هر پروتکلی که میتونی تصورش کنی (HTTP، HTTPS، FTP، SFTP، حتی SMTP و IMAP)، با تمرکز روی کنترل کامل روی request. برای همین امروز curl تبدیل شده به ابزار پیشفرض برای تست کردن API ها، چون بهت اجازه میده هر جزئیات یه HTTP request رو (method، header، body، auth) دقیق کنترل کنی.
دانلود سادهی یه فایل
# wget
wget https://example.com/file.zip
# curl (باید صراحتاً بگی خروجی رو تو یه فایل ذخیره کنه)
curl -O https://example.com/file.zip
اینجا فرق مهمی هست: wget بهصورت پیشفرض خروجی رو تو یه فایل ذخیره میکنه، ولی curl بهصورت پیشفرض محتوا رو مستقیم تو ترمینال چاپ میکنه، مگه اینکه با فلگ -O (ذخیره با همون اسم فایل تو URL) یا -o filename (ذخیره با اسم دلخواه) بهش بگی که فایل رو ذخیره کنه. این تفاوت دقیقاً از همون فلسفهی طراحی میاد؛ wget برای دانلود ساخته شده، curl برای انتقال و بازی با داده.
کار با API و HTTP request های پیچیده
اینجا جاییه که curl واقعاً میدرخشه. فرض کن میخوای یه POST request با JSON body و یه auth header بفرستی:
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"name": "Ali", "email": "ali@example.com"}'
با curl میتونی method رو با -X مشخص کنی، هر تعداد header دلخواه با -H اضافه کنی، body رو با -d بفرستی، و حتی response headers رو با -i ببینی. wget هم میتونه بعضی از این کارها رو انجام بده (مثلاً --header و --post-data)، ولی سینتکسش برای اینجور کارها اصلاً طراحی نشده و خیلی زود دستوپاگیر میشه. برای همین تقریباً هیچوقت نمیبینی کسی wget رو برای تست API پیشنهاد بده.
دانلود recursive و آینه کردن یه سایت
اینجا برعکس میشه. اگه بخوای یه سایت کامل یا یه پوشه از فایلها رو recursive دانلود کنی:
wget --recursive --level=2 --no-parent https://example.com/docs/
این دستور تمام لینکهای داخل صفحه رو تا عمق دو سطح دنبال میکنه و دانلود میکنه، بدون اینکه از مسیر والد بره بیرون. curl اصلاً همچین قابلیتی نداره؛ چون از پایه برای گرفتن یه URL مشخص طراحی شده، نه دنبال کردن ساختار یه سایت.
ادامه دادن دانلود قطعشده
هر دو ابزار این قابلیت رو دارن، ولی رفتار پیشفرضشون فرق داره:
# wget: با -c دانلود ناقص رو از همونجا ادامه میده
wget -c https://example.com/large-file.iso
# curl: با -C - همین کار رو میکنه
curl -C - -O https://example.com/large-file.iso
هر دو این کار رو با چک کردن سایز فایل موجود و فرستادن یه Range header انجام میدن، ولی wget این رفتار رو سادهتر و با کانتکست دانلود فایل طراحی کرده (مثلاً retry خودکار در صورت قطع شدن اتصال با --tries).
جمعبندی: کدوم رو کِی استفاده کنیم
اگه داری یه API رو تست میکنی، یه request سفارشی با header و body خاص میفرستی، یا میخوای response رو دقیق بررسی کنی، curl انتخاب درسته؛ کنترلی که رو جزئیات HTTP بهت میده رقیب نداره.
اگه هدفت دانلود یه فایل بزرگ (مخصوصاً تو یه اسکریپت یا کرونجاب بدون نظارت مستقیم)، یا گرفتن recursive یه سایت یا یه ساختار پوشهست، wget انتخاب راحتتریه؛ چون همین کارها دقیقاً چیزیه که براش ساخته شده و نیازی به فلگهای اضافه برای رفتار پایه نداره.
نکتهی آخر اینکه تو خیلی از distro های لینوکس امروز، هر دو ابزار از قبل نصب هستن، پس هزینهی نگهداشتن هر دو تو ابزارهای روزمرهت تقریباً صفره؛ لازم نیست حتماً یکیشون رو انتخاب کنی و کنار بذاری.
