เคยไหมต้อง copy ไฟล์ จำนวนมาก จากเครื่องหนึ่งไปอีกเครื่องหนึ่ง เช่นต้องการย้ายข้อมูลไปอีกเซิร์ฟเวอร์นึง หรือต้องการสำรองข้อมูลไปไว้อีกเครื่อง
แต่ก่อนถือเป็นงานยากของผู้ดูแลระบบที่จะย้ายไฟล์ได้ ยิ่งถ้ามีหลายไดเร็คทอรีย่อย มีหลายไฟล์ หรือต้องการเก็บค่า permission หรือ owner, group ของไฟล์ไว้ด้วย อาจต้องใช้คำสั่ง tar ก่อน แล้วค่อย copy ไฟล์ไป
ปัญหาก็คือหากระหว่างนั้นมีการเปลี่ยนแปลงไฟล์ เพิ่ม ลบ แก้ไข บนเครื่องต้นทาง อาจจะต้อง copy ไฟล์ใหม่ทั้งหมด หรือใช้คำสั่ง find เพื่อตรวจสอบ เนื่องจากไม่รู้ว่าไฟล์อะไรเปลี่ยนแปลงไปบ้าง
บทความนี้ขอแนะนำวิธีง่ายๆ คือใช้คำสั่ง rsync เพื่อใช้ copy ไฟล์ระหว่างเครื่อง
ทดสอบบนเครื่องที่ติดตั้งลีนุกซ์
เครื่องต้นทาง (src)
– user: user1
– ip: 192.168.0.1
เครื่องปลายทาง (dst)
– user: user2
– ip: 192.168.0.2
คำแนะนำ แนะนำให้ใช้ user ธรรมดาทดสอบบนเครื่องต้นทางและปลายทาง เพื่อป้องกันความผิดพลาดในการ copy ไฟล์ทับไฟล์สำคัญของระบบ
สร้างไฟล์และไดเร็คทอรีสำหรับการทดสอบ บนเครื่องต้นทาง (src)
[user1@src ~]$ mkdir test [user1@src ~]$ cd test/ [user1@src test]$ touch file1.txt [user1@src test]$ touch file2.txt [user1@src test]$ mkdir dir1 [user1@src test]$ touch dir1/file3.txt [user1@src test]$ ls -l total 4 drwxrwxr-x. 2 user1 user1 4096 Dec 1 21:38 dir1 -rw-rw-r--. 1 user1 user1 0 Dec 1 21:37 file1.txt -rw-rw-r--. 1 user1 user1 0 Dec 1 21:37 file2.txt
สมมติว่าต้องการ copy ไดเร็คทอรี test รวมทั้งไฟล์และไดเร็คทอรีย่อยๆ ทั้งหมดไปยังเครื่องปลายทาง (dst) สามารถทำได้ง่ายๆ คือ
บนเครื่องต้นทาง ใช้คำสั่ง rsync ตามด้วยออปชั่น -av แล้วตามด้วยไฟล์หรือไดเร็คทอรีที่ต้องการ copy ตามด้วย เครื่องปลายทาง โดยใส่ในรูปแบบ [ชื่อ user]@[ip ปลายทาง]:
คำอธิบาย
-a (archive mode) ให้ copy ไฟล์และไดเร็คทอรีย่อยๆ ทั้งหมด เหมือนกับการระบุออปชั่น -rlptgoD
-v (verbose) ให้แสดงชื่อไฟล์และรายละเอียดในการ copy ไฟล์ด้วย
รูปแบบการใช้คำสั่ง rsync จะเหมือนกับคำสั่ง cp คือตามด้วยออปชั่น แล้วตามด้วยไฟล์ต้นทางที่ต้องการ copy หากมีหลายไฟล์หรือหลายไดเร็คทอรี ก็สามารถเว้นวรรคได้ แล้วสุดท้ายคือปลายทางที่ต้องการ copy ไป เพียงแต่การระบุปลายทาง เช่นต้องการไปยังเครื่องอื่น ต้องระบุในรูปแบบ [ชื่อ user]@[ip ปลายทาง]: ต้องมีเครื่องหมาย : ปิดท้ายด้วย
ตัวอย่างเช่น ต้องการ copy ไดเร็คทอรี test และไฟล์ย่อยๆ ทั้งหมด ไปยังเครื่องปลายทาง ชื่อ user2 มี ip 192.168.0.2
โดยดีฟอลต์ rsync จะใช้ ssh ในการส่งไฟล์ระหว่างเครื่อง เพราะฉะนั้นจะต้องระบุรหัสผ่าน (password) บนเครื่องปลายทางให้ถูกต้อง
[user1@src ~]$ rsync -av test user2@192.168.0.2: user2@192.168.0.2's password: sending incremental file list test/ test/file1.txt test/file2.txt test/dir1/ test/dir1/file3.txt
sent 260 bytes received 77 bytes 96.29 bytes/sec total size is 0 speedup is 0.00
ในทำนองกลับกัน แทนที่จะรันคำสั่ง rsync บนเครื่องต้นทาง สามารถรันคำสั่ง rsync บนเครื่องปลายทางก็ได้ เช่น
[user2@dst ~]$ rsync -av user1@192.168.0.1:test .
เพื่อป้องกันความสับสน ในที่นี้ขอรันคำสั่ง rsync บนเครื่องต้นทาง
สังเกต การระบุไดเร็คทอรีที่ต้องการจะ copy จะไม่มีการใส่เครื่องหมาย / ต่อท้ายชื่อไดเร็คทอรี ซึ่งหมายถึงเป็นการ copy ทั้งไดเร็คทอรีแล้วไปสร้างไดเร็คทอรีใหม่ให้เหมือนเดิมบนเครื่องปลายทาง
ลองดูไฟล์ที่ copy ได้บนเครื่องปลายทาง
[user2@dst ~]$ ls -l total 4 drwxrwxr-x 3 user2 users 4096 Dec 1 21:37 test
ทดลองลบไดเร็คทอรีนี้บนเครื่องปลายทางออกไป
[user2@dst ~]$ rm -rf test/
รัน rsync ใหม่บนเครื่องต้นทาง โดยที่ไม่ได้ใส่เครื่องหมาย /
[user1@src ~]$ rsync -av test/ user2@192.168.0.2: user1@192.168.0.2's password: sending incremental file list ./ file1.txt file2.txt dir1/ dir1/file3.txt
sent 249 bytes received 76 bytes 92.86 bytes/sec total size is 0 speedup is 0.00
สังเกตว่าจะเป็นการ copy เฉพาะไฟล์หรือไดเร็คทอรีย่อยๆ ภายใน test ถ้าไปดูบนเครื่องปลายทาง จะไม่มีไดเร็คทอรี test มาด้วย
[user2@dst ~]$ ls -l total 4 drwxrwxr-x 2 user2 users 4096 Dec 1 21:38 dir1 -rw-rw-r-- 1 user2 users 0 Dec 1 21:37 file1.txt -rw-rw-r-- 1 user2 users 0 Dec 1 21:37 file2.txt
ขอลบไฟล์ที่ถูก copy มาบนเครื่องปลายทาง
[user2@dst ~]$ rm -rf dir1/ file1.txt file2.txt
ใช้ rsync แบบแรก ที่ไม่มีเครื่องหมาย /
[user1@src ~]$ rsync -av test user2@192.168.0.2: user1@192.168.0.2's password: sending incremental file list test/ test/file1.txt test/file2.txt test/dir1/ test/dir1/file3.txt
sent 260 bytes received 77 bytes 44.93 bytes/sec total size is 0 speedup is 0.00
หาก copy ไฟล์ไปแล้ว ไฟล์ต้นทางไม่มีการเปลี่ยนแปลง แล้วรันคำสั่ง rsync ซ้ำอีกที
[user1@src ~]$ rsync -av test user2@192.168.0.2: user1@192.168.0.2's password: sending incremental file list test/
sent 140 bytes received 17 bytes 62.80 bytes/sec total size is 0 speedup is 0.00
จะสังเกตว่า ไม่มีการ copy ไฟล์เลย
ทดลองสร้างไฟล์เพิ่มบนเครื่องต้นทาง
[user1@src ~]$ touch test/file4.txt
ลองรันคำสั่ง rsync อีกครั้ง
[user1@src ~]$ rsync -av test user2@192.168.0.2:
user1@192.168.0.2's password:
sending incremental file list
test/
test/file4.txt
sent 194 bytes received 36 bytes 41.82 bytes/sec total size is 0 speedup is 0.00
จะเห็นว่า rsync จะ copy ไฟล์ที่เพิ่มขึ้นมาเท่านั้น หรือหากไฟล์มีการเปลี่ยนแปลง
[user1@src ~]$ echo 111 > test/file1.txt
ลองรััน rsync อีกครั้ง ก็จะ copy ไฟล์ที่เปลี่ยนแปลงไปเท่านั้น
[user1@src ~]$ rsync -av test user2@192.168.0.2:
user1@192.168.0.2's password:
sending incremental file list
test/file1.txt
sent 199 bytes received 33 bytes 66.29 bytes/sec total size is 4 speedup is 0.02
ทำให้ประหยัดเวลา copy ไฟล์อย่างมาก
แต่ถ้าไฟล์ต้นทางถูกลบไป
[user1@src ~]$ rm -f test/file2.txt
รันคำสั่ง rsync อีกครั้ง ก็ไม่เห็นความเปลี่ยนแปลง ไฟล์ที่ถูกลบ หากไปตรวจสอบบนเครื่องปลายทางก็ยังคงอยู่
[user1@src ~]$ rsync -av test user2@192.168.0.2: user1@192.168.0.2's password: sending incremental file list test/
sent 140 bytes received 17 bytes 44.86 bytes/sec total size is 4 speedup is 0.03
หากต้องการให้ rsync ตรวจสอบไฟล์ที่ถูกลบบนเครื่องต้นทางด้วย แล้วให้ลบบนเครื่องปลายทางด้วย หรือหากเครื่องปลายทางมีไฟล์เกินมา ให้ลบทิ้งไปด้วย ต้องระบุออปชั่น –delete
[user1@src ~]$ rsync -av --delete test user2@192.168.0.2:
user1@192.168.0.2's password:
sending incremental file list
deleting test/file2.txt
sent 141 bytes received 14 bytes 44.29 bytes/sec total size is 4 speedup is 0.03
สังเกตว่าจะมีการลบไฟล์ด้วย
ลองหัดเล่นคำสั่ง rsync กันดูครับ หากต้องการดูรายละเอียดการใช้คำสั่ง rsync เพิ่มเติม ลองรัน rsync –help
หวังว่าจะมีประโยชน์กับผู้ดูแลระบบทั้งหลาย
ข้อมูลอ้างอิง
- rsync –help
- ถ่ายโอนไฟล์ระหว่าง Windows กับลีนุกซ์ ด้วย pscp
แล้วเราจะต้อง config ยังไงบ้างอะครับ