โฮมเพจ » ทำอย่างไร » คู่มือสำหรับผู้เริ่มต้นสู่การเขียนสคริปต์เชลล์ 2 สำหรับลูป

    คู่มือสำหรับผู้เริ่มต้นสู่การเขียนสคริปต์เชลล์ 2 สำหรับลูป

    หากคุณต้องการสร้างความน่าเชื่อถือให้เข้าร่วมกับเราสำหรับงวดที่สองในชุดสคริปต์เชลล์ของเรา เรามีการแก้ไขเล็กน้อยการปรับปรุงบางส่วนของสคริปต์ของสัปดาห์ที่แล้วและคำแนะนำในการวนซ้ำสำหรับผู้เริ่มต้น.

    สคริปต์ datecp ได้รับการตรวจสอบอีกครั้ง

    ในงวดแรกของคู่มือการใช้สคริปต์เชลล์เราสร้างสคริปต์ที่คัดลอกไฟล์ไปยังไดเรกทอรีสำรองหลังจากผนวกวันที่ต่อท้ายชื่อไฟล์.

    ซามูเอลดิออน - เรียลชี้ให้เห็นในความคิดเห็นว่ามีวิธีที่ดีกว่ามากในการจัดการการอ้างอิงตัวแปรของเรา.

    อาร์กิวเมนต์คั่นด้วยช่องว่างในเชลล์ bash ซึ่งจะโทเค็นเมื่อมีช่องว่างในคำสั่งที่ขยายออกมา ในสคริปต์ของคุณ, cp $ 1 $ 2. $ date_formatted จะทำงานตามที่ตั้งใจไว้ตราบใดที่ตัวแปรที่ขยายเพิ่มไม่มีช่องว่าง หากคุณเรียกสคริปต์ของคุณด้วยวิธีนี้: datecp "ชื่อเก่าของฉัน" "ชื่อใหม่ของฉัน" การขยายตัวจะส่งผลให้คำสั่งนี้: cp ชื่อใหม่ของฉันชื่อเก่าของฉัน the_date ซึ่งมี 6 ข้อโต้แย้ง.

    ในการแก้ไขปัญหานี้อย่างถูกต้องบรรทัดสุดท้ายของสคริปต์ควรเป็น: cp "$ 1" "$ 2 $ date_formatted"

    อย่างที่คุณเห็นการเปลี่ยนบรรทัดสคริปต์ของเราจาก:

    cp -iv $ 1 $ 2. $ date_formatted

    ไปที่:

    cp -iv“ $ 1”“ $ 2”. $ date_formatted

    จะดูแลปัญหานี้เมื่อใช้สคริปต์กับไฟล์ที่มีช่องว่างในชื่อ ซามูเอลยังชี้ให้เห็นว่าเมื่อคัดลอกและวางรหัสจากเว็บไซต์นี้ (หรืออินเทอร์เน็ตทั่วไป) ต้องแน่ใจว่าได้แทนที่เครื่องหมายขีดคั่นและเครื่องหมายคำพูดที่เหมาะสมสำหรับ“ ตัวพิมพ์ที่ดีกว่า” ที่มักจะแทนที่ นอกจากนี้เราจะทำสิ่งต่างๆให้มากขึ้นเพื่อให้แน่ใจว่ารหัสของเรานั้นง่ายต่อการคัดลอกและวาง ;-)

    นักวิจารณ์คนอื่น Myles Braithwaite ตัดสินใจที่จะขยายสคริปต์ของเราเพื่อให้วันที่ปรากฏก่อนนามสกุลไฟล์ ดังนั้นแทนที่จะ

    tastyfile.mp3.07_14_11-12.34.56

    เราจะได้สิ่งนี้:

    tastyfile.07_14_11-12.34.56.mp3

    ซึ่งทำให้การใช้งานสะดวกขึ้นเล็กน้อยสำหรับผู้ใช้ส่วนใหญ่ รหัสของเขามีอยู่ที่หน้า GitHub ของเขา ลองดูที่สิ่งที่เขาใช้เพื่อแยกชื่อไฟล์.

    date_formatted = $ (วันที่ +% Y-% m-% d_% H. % M% S)
    file_extension = $ (echo“ $ 1 "| awk -F. 'พิมพ์ $ NF')
    file_name = $ (basename $ 1. $ file_extension)

    cp -iv $ 1 $ file_name- $ date_formatted $ file_extension

    ฉันเปลี่ยนรูปแบบเล็กน้อย แต่คุณจะเห็นว่า Myles ประกาศฟังก์ชันวันที่ของเขาในบรรทัดที่ 1 ในบรรทัดที่ 2 อย่างไรก็ตามเขาใช้คำสั่ง“ echo” พร้อมอาร์กิวเมนต์แรกของสคริปต์เพื่อส่งชื่อไฟล์ เขาใช้คำสั่ง pipe เพื่อใช้เอาต์พุตนั้นและใช้เป็นอินพุตสำหรับส่วนถัดไป หลังจากไปป์ Myles เรียกใช้คำสั่ง“ awk” ซึ่งเป็นโปรแกรมการสแกนรูปแบบที่ทรงพลัง ใช้แฟล็ก -F เขาบอกคำสั่งว่าตัวละครถัดไป (หลังจากเว้นวรรค) คือสิ่งที่จะกำหนด "ตัวคั่นฟิลด์" ในกรณีนี้นั่นคือช่วงเวลา.

    ตอนนี้ awk ดูไฟล์ชื่อ“ Deliciousfile.mp3” ซึ่งประกอบด้วยสองฟิลด์:“ Deliciousfile” และ“ mp3” สุดท้ายเขาก็ใช้

    'พิมพ์ $ NF'

    เพื่อแสดงฟิลด์สุดท้าย ในกรณีที่ไฟล์ของคุณมีหลายช่วงเวลา - ทำให้ awk เห็นหลาย ๆ ฟิลด์ - มันจะแสดงเฉพาะช่วงสุดท้ายซึ่งเป็นนามสกุลไฟล์.

    ในบรรทัดที่ 3 เขาสร้างตัวแปรใหม่สำหรับชื่อไฟล์และใช้คำสั่ง "basename" เพื่ออ้างอิงทุกอย่างใน $ 1 ยกเว้น นามสกุลไฟล์ สิ่งนี้ทำได้โดยใช้ basename และให้ $ 1 เป็นอาร์กิวเมนต์ของมันจากนั้นเพิ่มช่องว่างและนามสกุลไฟล์ นามสกุลไฟล์จะถูกเพิ่มเข้ามาโดยอัตโนมัติเนื่องจากตัวแปรที่อ้างอิงบรรทัด 2 สิ่งนี้จะทำ

    tastyfile.mp3

    และเปลี่ยนเป็น

    tastyfile

    จากนั้นในบรรทัดสุดท้าย Myles รวบรวมคำสั่งที่จะส่งออกทุกอย่างตามลำดับ โปรดทราบว่าไม่มีการอ้างอิงถึง $ 2 ซึ่งเป็นอาร์กิวเมนต์ที่สองสำหรับสคริปต์ สคริปต์เฉพาะนี้จะคัดลอกไฟล์ดังกล่าวไปยังไดเรกทอรีปัจจุบันของคุณแทน ทำได้ดีมากกับซามูเอลและไมลส์!

    กำลังเรียกใช้สคริปต์และ $ PATH

    นอกจากนี้เรายังพูดถึงในบทความพื้นฐานของเราว่าสคริปต์ไม่ได้รับอนุญาตให้อ้างอิงเป็นคำสั่งโดยค่าเริ่มต้น นั่นคือคุณต้องชี้ไปที่เส้นทางของสคริปต์เพื่อเรียกใช้:

    ./ script

    ~ / bin / script

    แต่ด้วยการวางสคริปต์ของคุณใน ~ / bin / คุณสามารถพิมพ์ชื่อของพวกเขาจากที่ใดก็ได้เพื่อให้พวกเขาทำงาน.

    ผู้แสดงความคิดเห็นใช้เวลาในการพิจารณาว่าเรื่องนี้เหมาะสมอย่างไรเนื่องจากไม่มีดิสทริบิวเตอร์ distro รุ่นใหม่ที่สร้างไดเรกทอรีดังกล่าวตามค่าเริ่มต้น นอกจากนี้ยังไม่มีใครเพิ่มลงในตัวแปร $ PATH โดยค่าเริ่มต้นซึ่งเป็นสิ่งที่จำเป็นเพื่อให้สคริปต์ทำงานเหมือนคำสั่ง ฉันงงนิดหน่อยเพราะหลังจากตรวจสอบตัวแปร $ PATH ผู้แสดงความเห็นถูกต้อง แต่สคริปต์การโทรยังใช้งานได้สำหรับฉัน ฉันค้นพบสาเหตุ: ดิสทริบิวเตอร์ distros รุ่นใหม่หลายคนสร้างไฟล์พิเศษในโฮมไดเร็กตอรี่ของผู้ใช้ -. profile.

    ไฟล์นี้ถูกอ่านโดย bash (ยกเว้นว่า. bash_profile ปรากฏอยู่ในโฮมไดเร็กตอรี่ของผู้ใช้) และที่ด้านล่างมีส่วนที่เพิ่ม ~ / bin / โฟลเดอร์ไปยังตัวแปร $ PATH หากมีอยู่ ดังนั้นความลึกลับนั้นจึงถูกลบล้างไป สำหรับซีรีส์ที่เหลือฉันจะวางสคริปต์ต่อไปในไดเรกทอรี ~ / bin / เพราะเป็นสคริปต์ผู้ใช้และควรจะสามารถเรียกใช้โดยผู้ใช้ และดูเหมือนว่าเราไม่จำเป็นต้องยุ่งกับตัวแปร $ PATH ด้วยมือเพื่อให้สิ่งต่าง ๆ ทำงานได้.

    การทำซ้ำคำสั่งด้วยลูป

    มาเป็นหนึ่งในเครื่องมือที่มีประโยชน์ที่สุดในคลังแสงที่เกินบรรยายสำหรับจัดการกับงานซ้ำ ๆ : ลูป วันนี้เราจะมาพูดถึงลูป "สำหรับ".

    โครงร่างพื้นฐานของ for-loop เป็นดังนี้:

    เพื่อความหลากหลายใน LIST; ทำ
    Command1
    Command2
    ...
    CommandN
    เสร็จแล้ว

    ตัวแปรสามารถเป็นตัวแปรใดก็ได้แม้ว่าโดยทั่วไปแล้วตัวพิมพ์เล็ก "i" จะถูกใช้โดยการประชุม รายการคือรายการของรายการ; คุณสามารถระบุหลายรายการ (คั่นด้วยช่องว่าง) ชี้ไปที่ไฟล์ข้อความภายนอกหรือใช้เครื่องหมายดอกจัน (*) เพื่อแสดงไฟล์ใด ๆ ในไดเรกทอรีปัจจุบัน คำสั่งที่แสดงรายการจะถูกเยื้องโดยการประชุมดังนั้นจึงง่ายต่อการดูการซ้อน - การวนซ้ำในการวนซ้ำ (เพื่อให้คุณสามารถวนซ้ำในขณะที่คุณวนซ้ำ).

    เนื่องจากรายการใช้ช่องว่างเป็นตัวคั่น - นั่นคือช่องว่างหมายถึงการย้ายไปยังรายการถัดไปในรายการ - ไฟล์ที่มีช่องว่างในชื่อจึงไม่เป็นมิตร ตอนนี้มาทำงานกับไฟล์ที่ไม่มีช่องว่างมาเริ่มด้วยสคริปต์ง่าย ๆ เพื่อแสดงชื่อไฟล์ในไดเรกทอรีปัจจุบัน สร้างสคริปต์ใหม่ใน ~ / bin / โฟลเดอร์ชื่อ“ loopscript” หากคุณจำไม่ได้ว่าจะทำอย่างไร (รวมถึงการทำเครื่องหมายว่าสามารถปฏิบัติการได้และเพิ่มแฮ็กแฮ็ก) อ้างอิงถึงบทความพื้นฐานการเขียนสคริปต์ทุบตีของเรา.

    ในนั้นใส่รหัสต่อไปนี้:

    สำหรับฉันใน item1 item2 item3 item4 item5 item6; ทำ
    echo“ $ i”
    เสร็จแล้ว

    เมื่อคุณเรียกใช้สคริปต์คุณควรได้รับรายการเหล่านั้นเป็นผลลัพธ์.

    ค่อนข้างง่ายใช่มั้ย เรามาดูกันว่าจะเกิดอะไรขึ้นถ้าเราเปลี่ยนสิ่งต่าง ๆ เล็กน้อย เปลี่ยนสคริปต์ของคุณเพื่อให้มันบอกว่าสิ่งนี้:

    สำหรับฉันใน *; ทำ
    echo“ $ i”
    เสร็จแล้ว

    เมื่อคุณเรียกใช้สคริปต์นี้ในโฟลเดอร์คุณควรได้รับรายชื่อของไฟล์ที่มันเป็นเอาท์พุท.

    ทีนี้มาเปลี่ยนคำสั่ง echo ให้เป็นประโยชน์มากขึ้น - พูดคำสั่ง zip กล่าวคือเราจะเพิ่มไฟล์ลงในไฟล์เก็บถาวร และขอขัดแย้งในการผสมกัน!

    สำหรับฉันใน $ @; ทำ
    ไฟล์ zip“ $ i”
    เสร็จแล้ว

    มีอะไรใหม่! “ $ @” เป็นทางลัดสำหรับ“ $ 1 $ 2 $ 3 … $ n” นั่นคือรายการทั้งหมดของอาร์กิวเมนต์ทั้งหมดที่คุณระบุ ตอนนี้ดูว่าเกิดอะไรขึ้นเมื่อฉันเรียกใช้สคริปต์ด้วยไฟล์อินพุตหลายไฟล์.

    คุณสามารถดูไฟล์ที่อยู่ในโฟลเดอร์ของฉัน ฉันรันคำสั่งด้วยหกอาร์กิวเมนต์และแต่ละไฟล์ถูกเพิ่มลงในไฟล์ซิปที่ชื่อ“ archive.zip” ง่ายถูกต้อง?

    สำหรับลูปนั้นวิเศษมาก ตอนนี้คุณสามารถเรียกใช้ฟังก์ชันแบตช์ในรายการไฟล์ ตัวอย่างเช่นคุณสามารถคัดลอกอาร์กิวเมนต์ทั้งหมดของสคริปต์ของคุณลงในไฟล์บีบอัดซิปย้ายต้นฉบับไปยังโฟลเดอร์อื่นและคัดลอกไฟล์ zip นั้นไปยังคอมพิวเตอร์ระยะไกลโดยอัตโนมัติ หากคุณตั้งค่าไฟล์คีย์ด้วย SSH คุณไม่จำเป็นต้องป้อนรหัสผ่านและคุณสามารถบอกให้สคริปต์ลบไฟล์ zip หลังจากอัปโหลด!


    การใช้ for-loops ทำให้การดำเนินการต่างๆเป็นไปอย่างง่ายดายสำหรับไฟล์ทั้งหมดในไดเรกทอรี คุณสามารถสแต็กคำสั่งที่หลากหลายเข้าด้วยกันและใช้อาร์กิวเมนต์ได้ง่ายมากในการสร้างและรายการแบบทันทีและนี่เป็นเพียงส่วนเล็ก ๆ ของภูเขาน้ำแข็ง.

    ทุบตี Scripters คุณมีข้อเสนอแนะใด ๆ ? คุณสร้างสคริปต์ที่มีประโยชน์ที่ใช้ลูปหรือไม่? ต้องการแบ่งปันความคิดของคุณในซีรี่ส์หรือไม่ แสดงความคิดเห็นและช่วยมือใหม่อื่น ๆ ในการเขียนสคริปต์!