نحوه انتقال فایل از طریق SSH و دستور wget

برای انتقال فایل به سرور از طریق SSH، در بیشتر موارد یکی از این سه ابزار کارتان را راه می‌اندازد: scp برای کپی ساده و یک‌باره، rsync برای حجم‌های بزرگ یا انتقال‌های تکرارشونده، و sftp برای کار تعاملی و فایل‌به‌فایل. اما اگر فایل از قبل روی یک آدرس اینترنتی قرار دارد و می‌خواهید مستقیم داخل خود سرور دانلود شود، ابزار درست wget یا curl است، نه scp.

تفاوت اصلی همین‌جاست: scp و rsync و sftp فایل را از کامپیوتر شما به سرور می‌برند و ترافیک از اینترنت خانگی یا اداری شما عبور می‌کند؛ در مقابل wget و curl فایل را از یک URL و با پهنای باند خودِ سرور می‌گیرند. برای فایلی چندگیگابایتی که روی یک مخزن یا فضای ابری موجود است، روش دوم معمولاً به‌مراتب سریع‌تر تمام می‌شود.

پیش‌نیاز: یک دسترسی SSH سالم

همه این روش‌ها روی پوسته امن (SSH) سوار می‌شوند، پس باید نام کاربری، آی‌پی یا دامنه و پورت SSH را در اختیار داشته باشید. پورت پیش‌فرض ۲۲ است، ولی بسیاری از مدیران سرور آن را تغییر می‌دهند و دادن پورت اشتباه به خطای اتصال ختم می‌شود. روی یک VPS یا سرور اختصاصی معمولاً دسترسی کامل شل در اختیار خودتان است و هر چهار ابزار بالا کار می‌کنند.

scp؛ ساده‌ترین راه کپی کردن

scp دقیقاً مثل دستور cp عمل می‌کند، با این تفاوت که یک سرِ مسیر روی ماشین دیگری است:

scp /home/user/backup.tar.gz root@203.0.113.10:/root/

اگر پورت SSH پیش‌فرض نیست، آن را با -P بدهید. حواستان باشد که در scp حرف پورت بزرگ است و در خود ssh کوچک؛ این یکی از رایج‌ترین اشتباه‌هاست:

scp -P 2222 backup.tar.gz root@203.0.113.10:/root/

برای یک پوشه از -r استفاده کنید و برای گرفتن فایل از سرور، فقط جای مبدأ و مقصد را عوض کنید:

scp -r ./public_html root@203.0.113.10:/var/www/
scp root@203.0.113.10:/root/backup.tar.gz .

سوئیچ -p کوچک زمان و سطح دسترسی فایل را حفظ می‌کند. یک نکته فنی: در OpenSSH نسخه ۹ به بعد، scp پشت صحنه از پروتکل SFTP استفاده می‌کند؛ خط فرمان همان است ولی رفتار آن در برخی حالت‌های خاص با گذشته فرق دارد.

rsync؛ انتخاب درست برای حجم زیاد

هر جا انتقال بیش از چند صد مگابایت است یا قرار است چند بار تکرار شود، rsync گزینه بهتری است؛ چون فقط تفاوت‌ها را می‌فرستد و اگر ارتباط قطع شود، اجرای دوباره همان دستور کار را از جایی که مانده ادامه می‌دهد:

rsync -avzP -e "ssh -p 2222" /home/user/site/ root@203.0.113.10:/var/www/site/

در این دستور -a حالت آرشیو است (حفظ مجوزها، زمان‌ها و لینک‌های نمادین)، -v گزارش کار می‌دهد، -z داده را حین انتقال فشرده می‌کند و -P ترکیبی از نمایش پیشرفت و نگه‌داشتن فایل ناتمام است. اگر فایل‌ها از قبل فشرده‌اند (مثل tar.gz یا تصاویر)، -z فقط پردازنده را مشغول می‌کند و سودی ندارد.

به اسلش انتهای مسیر مبدأ دقت کنید: site/ یعنی «محتویات پوشه» و site بدون اسلش یعنی «خود پوشه» که داخل مقصد ساخته می‌شود. همچنین پیش از هر اجرای جدی، یک بار با --dry-run نتیجه را ببینید. سوئیچ --delete هر فایلی را که در مبدأ نباشد از مقصد پاک می‌کند؛ این گزینه برگشت‌ناپذیر است و بدون آزمایش با --dry-run نباید اجرا شود.

sftp؛ وقتی می‌خواهید تعاملی جلو بروید

اگر نمی‌دانید دقیقاً چه فایلی کجاست و می‌خواهید بگردید، sftp روی همان کانال SSH یک محیط تعاملی می‌دهد:

sftp -P 2222 root@203.0.113.10

داخل آن با ls و cd در سرور و با lcd در سیستم خودتان جابه‌جا می‌شوید، با put فایل می‌فرستید و با get می‌گیرید. اگر انتقالی نیمه‌کاره ماند، reput و reget آن را ادامه می‌دهند. روی هاست اشتراکی معمولاً به‌جای شل کامل، همین SFTP یا فایل‌منیجر کنترل‌پنل ابزار اصلی شماست و دامنه دسترسی بسته به پلن و سیاست سرویس‌دهنده فرق می‌کند.

wget و curl؛ گرفتن فایل از روی یک آدرس

وقتی فایل روی یک URL در دسترس است، وارد SSH شوید و مستقیم روی سرور دانلود کنید:

wget https://example.com/phpini.txt

با -O می‌توانید نام و مسیر خروجی را تعیین کنید، با -c دانلود نیمه‌تمام را ادامه دهید و با --limit-rate جلوی اشباع‌شدن پهنای باند سرور را بگیرید:

wget -c --limit-rate=5m -O /root/big.iso https://example.com/big.iso

curl هم همین کار را می‌کند؛ -L ریدایرکت‌ها را دنبال می‌کند، -O فایل را با نام اصلی ذخیره می‌کند و -C - ادامه دانلود است:

curl -C - -L -O https://example.com/big.iso

ادامه دادن دانلود فقط وقتی ممکن است که سرور مقابل از درخواست‌های Range پشتیبانی کند؛ در غیر این صورت فایل از ابتدا گرفته می‌شود. بعد از پایان کار هم درستی فایل را با sha256sum big.iso بسنجید و با مقدار منتشرشده مقایسه کنید. یک هشدار امنیتی جدی هم بدهم: خروجی یک آدرس ناشناس را هرگز مستقیم به شل ندهید؛ الگوی «دانلود و اجرای بی‌واسطه اسکریپت» یکی از رایج‌ترین راه‌های آلوده شدن سرور است؛ برای پیدا کردن شل‌های جاسازی‌شده روی سرور هم اسکن فایل‌های آلوده با آنتی‌شلر کمک می‌کند. اگر کار اصلی‌تان ارائه فایل‌های حجیم برای دانلود کاربران است، سرویس‌های تخصصی مثل دانلود هاست از این جهت مناسب‌تر از هاست عمومی هستند.

بعد از انتقال: مالکیت و سطح دسترسی را اصلاح کنید

این مرحله بیشترین خطاها را می‌سازد. فایلی که با wget و به‌عنوان root گرفته‌اید مالکش root است و وب‌سرور نمی‌تواند آن را بخواند یا در کنارش بنویسد. پس مالکیت را به کاربر درست بدهید (نام کاربر بسته به توزیع و کنترل‌پنل فرق می‌کند؛ در دبیان و اوبونتو معمولاً www-data و در خانواده RHEL اغلب apache است):

chown -R www-data:www-data /var/www/site

سپس سطح دسترسی متعارف را اعمال کنید — پوشه‌ها ۷۵۵ و فایل‌ها ۶۴۴:

find /var/www/site -type d -exec chmod 755 {} ;
find /var/www/site -type f -exec chmod 644 {} ;

هرگز برای «حل شدن سریع مشکل» دستور chmod -R 777 نزنید؛ این کار فایل‌ها را برای هر کاربری روی سرور قابل تغییر می‌کند. یادتان باشد rsync -a و scp -p مجوزها را حفظ می‌کنند اما scp ساده و wget این کار را نمی‌کنند. روی سیستم‌هایی که SELinux فعال است، ممکن است به اصلاح برچسب‌های امنیتی با restorecon هم نیاز باشد. اگر سایت بالا نیامد و علتش را پیدا نکردید، بهتر است پیش از آزمون‌وخطا روی سرور زنده از کارشناسان پشتیبانی آنلاین سرور کمک بگیرید.

چند نکته که دردسر را کم می‌کند

  • برای هزاران فایل کوچک، اول آرشیو بگیرید و بعد منتقل کنید؛ سربار هر فایل جداگانه بسیار زیاد است.
  • انتقال‌های طولانی را داخل screen یا tmux اجرا کنید تا قطع شدن اتصال SSH کار را نیمه‌کاره رها نکند.
  • به‌جای رمز عبور از کلید SSH استفاده کنید؛ هم امن‌تر است و هم اسکریپت‌های خودکار را ممکن می‌کند.
  • پیش از جابه‌جایی داده، فضای خالی دیسک مقصد را با df -h بررسی کنید.

جمع‌بندی ساده است: از سیستم خودتان به سرور، scp برای کارهای کوچک و rsync برای هر چیز بزرگ‌تر؛ از یک آدرس اینترنتی به سرور، wget یا curl؛ و در پایان همیشه مالکیت و سطح دسترسی را بررسی کنید.