1 คะแนน โดย GN⁺ 2025-02-09 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ทีมปฏิบัติการยังคงมี ขั้นตอนที่ต้องทำด้วยมือ (toil) ซึ่งกำจัดให้หมดได้ยาก เช่น การเปลี่ยนแปลงโครงสร้างพื้นฐานหรือการ provision บัญชี และเมื่อบริษัทเติบโตขึ้น ขั้นตอนและข้อยกเว้นก็เพิ่มมากขึ้น
  • แม้แต่ละขั้นตอนจะดูเหมือนทำให้เป็นอัตโนมัติได้ แต่หากทำเป็นสคริปต์เพียงบางส่วน ก็จะมีเครื่องมือเฉพาะกิจเพิ่มขึ้น และผู้ใช้ยังต้องทำตาม เอกสารขั้นตอนยาว ๆ อยู่ดี
  • สคริปต์แบบ Do-nothing ไม่ได้รันงานจริงโดยอัตโนมัติ แต่ห่อแต่ละขั้นตอนของกระบวนการไว้เป็นฟังก์ชัน แล้วสั่งผู้ใช้ทีละขั้น
  • ผู้ใช้มีโอกาสน้อยลงที่จะหลงตำแหน่งปัจจุบันหรือข้ามขั้นตอน และนักพัฒนาก็เปลี่ยนข้อความแนะนำของบางขั้นตอนให้เป็นโค้ดอัตโนมัติจริงในภายหลังได้ง่ายขึ้น
  • แม้ปริมาณงานที่ต้องทำด้วยมือในตอนนี้จะไม่ลดลง แต่ช่วยลด ต้นทุนเริ่มต้น ของการทำอัตโนมัติ ทำให้ค่อย ๆ กำจัด toil ได้เมื่อเวลาผ่านไป

เมื่อขั้นตอนที่ต้องทำด้วยมือกลายเป็นงานหนักหน่วง

  • ทุกทีมปฏิบัติการยังมี ขั้นตอนที่ต้องทำด้วยมือ ที่ยังทำให้เป็นอัตโนมัติไม่ได้ และ toil นั้นยากที่จะหายไปโดยสิ้นเชิง
  • ในบริษัทที่กำลังเติบโต ขั้นตอนอย่างการเปลี่ยนแปลงโครงสร้างพื้นฐานหรือการ provision บัญชีผู้ใช้มักกลายเป็นศูนย์กลางของ toil ขนาดใหญ่ได้ง่าย
  • ขั้นตอนการ provision บัญชีผู้ใช้อาจต้องผ่านหลายขั้นตอนดังนี้
    • สร้างคู่คีย์ SSH ของผู้ใช้
    • commit public key ลง Git แล้ว push ไปยัง master
    • รอให้งาน build เสร็จ
    • ตรวจสอบที่อยู่อีเมลของผู้ใช้ในไดเรกทอรีพนักงาน
    • ส่ง private key ให้ผู้ใช้ผ่าน 1Password
  • ในสภาพแวดล้อมจริง ขั้นตอนอาจเพิ่มขึ้นถึง 20 ขั้น หรืออาจต้องคอยติดตามการแตกแขนงและกรณีพิเศษระหว่างดำเนินการอย่างต่อเนื่อง
  • งานลักษณะนี้ต้องใช้สมาธิมาก แต่ใกล้เคียงกับการติ๊กเช็กบ็อกซ์เพิ่มอีกช่องมากกว่าการแก้ปัญหาที่น่าสนใจ จึงกลายเป็น slog

ช่องว่างที่การทำอัตโนมัติบางส่วนทิ้งไว้

  • slog ดูเหมือนเป็นเป้าหมายที่เหมาะสำหรับการทำอัตโนมัติ
    • สามารถนึกวิธีทำให้แต่ละขั้นตอนเป็นอัตโนมัติได้ง่าย
    • คอมพิวเตอร์ทำตามคำสั่งได้เร็วและแม่นยำกว่าคน
    • โอกาสเกิด practical drift ก็ต่ำกว่า
  • ปัญหาคือการทำให้ slog เป็นอัตโนมัติมักรู้สึกเหมือนเป็นแบบ ทั้งหมดหรือไม่ก็ไม่เลย
  • เราสามารถสร้างสคริปต์ที่จัดการเฉพาะขั้นตอนที่ 2 หรือขั้นตอนที่ 5 ได้ แต่ความยุ่งยากของกระบวนการทั้งหมดไม่ได้ลดลงมากนัก
  • เมื่อสคริปต์เฉพาะกิจเพิ่มขึ้น แต่ละเครื่องมือก็มีแนวปฏิบัติและพฤติกรรมที่คาดหวังต่างกัน และผู้ใช้ยังต้องทำตามเอกสารหลายขั้นตอนอยู่ดี

วิธีทำงานของสคริปต์แบบ Do-nothing

  • slog แทบทุกอย่างสามารถเปลี่ยนเป็น สคริปต์แบบ Do-nothing ได้
  • หัวใจสำคัญคือใส่คำสั่งของ slog ลงในโค้ด และ encapsulate แต่ละขั้นตอนไว้เป็นฟังก์ชันหนึ่งตัว
  • ลำดับการทำงานของสคริปต์ตัวอย่างเป็นดังนี้
    • CreateSSHKeypairStep แสดงคำสั่ง ssh-keygen แล้วรอจนกว่าผู้ใช้จะกด Enter
    • GitCommitStep แนะนำให้คัดลอก public key ไปยัง Git repository แล้วรัน git commit, git push
    • WaitForBuildStep แนะนำให้รอการเสร็จสิ้นที่ URL ของงาน build
    • RetrieveUserEmailStep ค้นหาที่อยู่อีเมลในไดเรกทอรี รับอินพุต แล้วบันทึกไว้ใน context["email"]
    • SendPrivateKeyStep แนะนำให้สร้างเอกสาร private key ใน 1Password แล้วแชร์กับผู้ใช้ที่ใช้อีเมลนั้น
  • สคริปต์นี้ไม่ได้ทำขั้นตอนใด ๆ ของกระบวนการจริง ๆ แต่จะสั่งผู้ใช้ทีละขั้นแล้วรอให้ทำเสร็จด้วยมือ

เส้นทางที่นำไปสู่การทำอัตโนมัติ

  • เมื่อเห็นครั้งแรก สคริปต์แบบ Do-nothing อาจดูเหมือนทำให้เอกสารอ่านยากขึ้น แต่ในความเป็นจริงมันช่วยยึด workflow ไว้ให้ปลอดภัยกว่าเดิม
    • ผู้ใช้มีโอกาสน้อยลงที่จะหลงตำแหน่งที่ทำอยู่หรือข้ามขั้นตอน
    • รักษาสมาธิและทำ slog ไปจนจบได้ง่ายขึ้น
    • แต่ละขั้นตอนถูกแยกเป็นฟังก์ชัน จึงสามารถแทนที่ข้อความของบางขั้นตอนด้วยโค้ดที่ทำงานจริงได้
    • เมื่อเวลาผ่านไป จะเกิดไลบรารีของขั้นตอนที่นำกลับมาใช้ซ้ำได้ และงานทำอัตโนมัติหลังจากนั้นก็มีประสิทธิภาพมากขึ้น
  • ตัวสคริปต์แบบ Do-nothing เองไม่ได้ลด ปริมาณงานที่ต้องทำด้วยมือ ของทีม
  • ผลลัพธ์ของมันอยู่ที่การทำให้เริ่มต้นทำอัตโนมัติได้ง่าย และทีมสามารถใช้สิ่งนี้เป็นฐานในการกำจัด toil เมื่อเวลาผ่านไป

1 ความคิดเห็น

 
GN⁺ 2025-02-09
ความคิดเห็นจาก Hacker News
  • ชอบแนวทางนี้มาก
    โดยรวมแล้วมันเป็นอีกวิธีหนึ่งในการนิยาม อินเทอร์เฟซ รอบ ๆ กระบวนการนั้น กระบวนการนั้นอาจเป็นแบบทำด้วยมือหรือถูกทำให้เป็นอัตโนมัติก็ได้ แต่อินเทอร์เฟซยังคงเดิมได้ ดังนั้นจึงค่อนข้างทรงพลังเมื่อทำให้ขั้นตอนต่าง ๆ เป็นอัตโนมัติ
    ก็แค่นำไปใช้เหมือนกับที่ทำกับระบบอื่น ๆ
    เมื่อก่อนเคยกรอก Google Sheets ด้วยมือแล้วทำให้เป็นอัตโนมัติด้วยสคริปต์ และเคยทำให้เมื่อสร้างตั๋ว Jira แล้วระบบดึงไปจัดการโดยอัตโนมัติด้วย เริ่มได้เร็วขึ้น ทำให้เฉพาะส่วนที่น่ารำคาญที่สุดเป็นอัตโนมัติได้ และไม่จำเป็นต้องทำให้ทั้งหมดเป็นอัตโนมัติเสมอไป
    ผลข้างเคียงของสคริปต์ที่ไม่ทำอะไรเลยคือ มันมีโอกาสถูกใช้งานจริงมากกว่าเอกสาร จึงมีแนวโน้มถูกปรับให้ทันสมัยบ่อยกว่า

    • ในความเห็นที่ไม่ค่อยถ่อมตัวของผม การค่อย ๆ เข้ารหัสกระบวนการเป็นสคริปต์แบบนี้จะสร้าง ระบบที่มีศูนย์กลางอยู่ที่กระบวนการ ไม่ใช่ระบบที่กลืนกระบวนการเข้าไป
      ผมเห็นด้วยกับการมีรายการสคริปต์สำหรับทำงานทั่วไปให้เป็นอัตโนมัติ แต่ทันทีที่สคริปต์เหล่านั้นเริ่มถูกเรียกจากบริการที่ใช้งานจริง ก็จะเกิด หนี้ทางเทคนิค ก้อนใหญ่ให้กับคนโชคร้ายที่ต้องมาคลายเครือข่ายสปาเกตตีนี้
      ยิ่งไปกว่านั้น เพราะกระบวนการที่มีคนเป็นศูนย์กลางได้ไปทำให้ระบบกลายเป็นโค้ด จึงทำให้การเปลี่ยนแปลงที่เป็นประโยชน์ต่อระบบซอฟต์แวร์ เช่น การแยกระบบออกเป็นคอมโพเนนต์ ทำไม่ได้ สุดท้ายการขยายแบบค่อยเป็นค่อยไปก็กลายเป็นการยัดสิ่งต่าง ๆ เข้าไปในกระบวนการมากขึ้น และนั่นก็เป็นวงจรเพิ่มพูนตัวเองที่คอยต่อเติมเข้าไปในสคริปต์โมโนลิธต่อไป
    • แนวทางเดิมเป็นแบบนี้: 1) จับกระบวนการปัจจุบันไว้ตามที่เป็น 2) ทำให้กระบวนการนั้นผ่านการทดสอบแบบ “หัวเราะไม่ออก” 3) ทำให้พร้อมสำหรับการทำอัตโนมัติ
      ระหว่างทำข้อ 3 และ 4 ให้ทำซ้ำกระบวนการ และให้คนใช้จริงให้มากที่สุดเท่าที่เป็นไปได้ แล้วปรับกระบวนการตามการใช้งานผิด ๆ ที่เห็นในสนามจริง
      4) ทำให้กระบวนการเป็นอัตโนมัติ
      ทุกคนเห็นด้วยกับข้อ 1 และ 2 และส่วนใหญ่ก็จะตามมาถึงข้อ 4 ในที่สุด แต่เมื่อทำข้อ 3 จะมีคนจำนวนมากขึ้นที่เรียกร้องและเข้าใจข้อ 4 มากขึ้น
      อย่างไรก็ตาม ข้อจำกัดของแนวทางนี้คือ ถ้าทำให้จุดเริ่มต้นหรือจุดสิ้นสุดของกระบวนการเป็นอัตโนมัติได้ก็ยังพอไหว แต่ถ้ามีจุดอัตโนมัติสองจุดที่แยกเป็นเกาะอยู่กลางกระบวนการ มันก็ไม่ได้ดีกว่า เครื่องมือบรรทัดคำสั่ง ที่มีพรอมป์เท่าไรนัก
    • ใช่ สำหรับผมมันยังเป็นอีกโอกาสหนึ่งในการใช้และแชร์ Jupyter notebooks ด้วย
      แค่อธิบายสิ่งที่ต้องทำ แล้วให้โค้ดสำเร็จรูปหรือตัวอย่าง และไฟล์ปฏิบัติการที่รับพารามิเตอร์ได้
      ถ้าใช้ Notebooks เป็นระบบเอกสารโดยพฤตินัยก็น่าจะเจ๋งดี แต่ถ้าจะวางเป็นเลเยอร์บนคลาวด์ SaaS อย่าง Confluence มันหนักเกินไป และในรูปแบบปัจจุบันก็มีช่องให้เกิดปัญหาอย่างการยกระดับสิทธิ์ได้มากเกินไป
    • เริ่มเห็นภูเขาจาก “Zen and the Art of Motorcycle Maintenance” แล้ว
      แนวทางนี้เปลี่ยนหน้าคู่มือใน Confluence ให้เป็น walkthrough แบบกึ่งโต้ตอบ นี่คือด้านที่มีสติ
      อีกด้านหนึ่งคือ การทำให้การทดสอบเป็นอัตโนมัติ ตอนแรกเริ่มจากก้อน XPath ที่ overfit และขั้นตอนที่ไม่มีเอกสารกำกับ ทุกครั้งที่แอปพลิเคชันเปลี่ยน ก็ต้องค้นพบขั้นตอนเหล่านั้นใหม่ นี่คือด้านที่ไร้สติ
      หวังว่าเมื่อถึงยอดแล้วจะรันได้เร็ว ขณะเดียวกันก็ยังรู้ว่าเรามาถึงตรงนั้นได้อย่างไรและทำไมถึงเป็นแบบนั้น
    • สิ่งที่ทำได้ด้วยคำสั่งอยู่แล้ว ผมอยากให้สคริปต์ทำให้เองโดยตรง
      แค่ให้ผู้ใช้ยืนยันแบบ Execute command (y/N)? ก็พอ
      ผมเกลียดการคัดลอกแล้ววางจากเทอร์มินัลหนึ่งไปอีกเทอร์มินัลหนึ่งจริง ๆ มันกินสมาธิไปเยอะเหมือนกัน
      ให้ถามผู้ใช้เฉพาะงานที่ยังไม่ใช่คำสั่งและต้องทำด้วยมือก็พอ: Look up the e-mail address for foo. Paste it here: หรือ Put that shit in 1Password: Are you done (y/N)?
  • เป็นแนวทางที่น่าสนใจ
    แต่ตัวอย่างงานที่ยกมานั้นแค่แสดงให้เห็นว่า วิธีแจกจ่ายคีย์ SSH ของบริษัทนั้นไม่ปลอดภัยแค่ไหน ในความเป็นจริงควรปลูกฝังให้ผู้ใช้สร้างคีย์ส่วนตัวเอง และส่งเฉพาะคีย์สาธารณะให้ผู้ดูแลระบบเพื่อให้สิทธิ์เข้าถึง ผู้ดูแลระบบไม่ควรได้สำเนาคีย์ส่วนตัวไม่ว่า ณ จุดใด แม้แต่ชั่วคราวก็ตาม ดังนั้นขั้นตอน 1Password เองจึงไม่ควรจำเป็น
    อนึ่ง ผมเป็นผู้เขียน github-keygen ซึ่งเป็นเครื่องมือที่ทำให้การสร้างคีย์ SSH สำหรับเข้าถึง GitHub โดยเฉพาะ และการตั้งค่า SSH ในบริบทนั้นเป็นอัตโนมัติ
    https://github.com/dolmen/github-keygen

    • การให้ผู้ใช้ที่ไม่ชำนาญจัดการคีย์ของตัวเองก็ดูไม่ค่อยปลอดภัยเหมือนกัน ดังนั้นประเด็นหลักคือย้ายมันไปเป็นสคริปต์
    • ขั้นตอนที่ว่า ผู้ใช้ต้องสร้างคีย์ส่วนตัวเองและส่งเฉพาะคีย์สาธารณะให้ผู้ดูแลระบบ นั้นน่าหงุดหงิดในการนำไปใช้เสมอ
      เราได้ย้ายจาก SSH ไปใช้ การยืนยันตัวตนด้วยใบรับรอง แล้ว และไม่ต้องย้ายคีย์สาธารณะไปมาอีกต่อไป กระบวนการทั้งหมดง่ายขึ้นจริง ๆ
    • นี่เป็นมาตรฐานขั้นต่ำจริง ๆ หรือ? ยังไง IT ก็เป็นเจ้าของทุกส่วนของ เครื่องทำงานที่มีคีย์ส่วนตัวอยู่ข้างใน ไม่ใช่หรือ? ผมเข้าใจว่ารหัสผ่านนั้นต่างออกไป แต่คีย์ส่วนตัวก็ถูกเก็บไว้ในเครื่องอยู่ดี
  • ผมเพิ่งได้ลองใช้แนวทางนี้จริง ๆ หลังจากบทความนี้เผยแพร่ครั้งแรกไปประมาณ 1 ปี
    เพราะบั๊กใน toolchain ของเรา runbook สำหรับ hotfix จึงซับซ้อนกว่ากระบวนการ release ปกติราวสองเท่า
    มันไม่ได้รับการประเมินค่าสูงเท่าที่ควร แต่จากเดิมที่ใช้แค่ประมาณทุก 10 สัปดาห์กับ issue ระดับ sev 1 หรือ epic ช่วงท้าย ๆ กลายเป็นถูกใช้เฉลี่ยสัปดาห์ละครั้ง และบางสัปดาห์ถึง 3 ครั้ง ทำให้เราไม่จำเป็นต้องทำทุกอย่างเป็น feature toggle อีกต่อไป และสามารถขุดลึกลงไปใน หนี้ทางเทคนิค ได้มากขึ้นมาก
    ถ้าเป็นบริษัทเล็กที่ทำซ้ำข้อมูล production ไปยัง environment ก่อน production ได้ง่าย คุณอาจไม่เห็นผลลัพธ์แบบนี้ แต่ endpoint ที่เราติดต่อด้วยมีมากกว่า 150 รายการ และคิดว่าเฉลี่ยประมาณ 3 รายการต่อบริการ มี dataset จำนวนมาก และบางส่วนถูกเก็บรวบรวมด้วยวิธีที่คล้าย Kafka ในยุคก่อนที่ Kafka จะมีอยู่
    มีคนเพียงคนเดียวที่พยายามทำซ้ำข้อมูล production และคนนั้นก็มีเวลาและพลังงานไม่พอ จึงทำได้แค่ปีละครั้งหรือสองครั้ง ความเร็วนั้นช้ากว่าความเร็วที่ลูกค้าและฟีเจอร์เปลี่ยนไปมาก สุดท้ายเราจึงต้องง่วนอยู่กับกระบวนการ deploy แบบ blue-green และ jmeter เพื่อหาว่าเราเข้าใกล้แค่ไหน และจะวัดความสำเร็จ/ล้มเหลวก่อนขึ้น live อย่างไร
    สุดท้ายสิ่งที่ขวางผู้คนไว้คือ กระบวนการ build ที่จุกจิกและผิดพลาดได้ง่าย และมันคลี่คลายได้ก็ต่อเมื่อผมทำ automation ให้มันไปได้ครึ่งหนึ่งแล้ว
    ต่อมาเมื่อมีการใช้งานมากขึ้น ผมก็หา URL ทั้งหมดในขั้นตอน manual แล้วใส่ไว้ใน lookup table ภายในเครื่องมือ และทำให้มองเห็นได้ในกระบวนการ verification ทั่วไปสำหรับการอนุมัติ release ด้วย ทำให้ coordinator ทำงานได้เร็วขึ้นเล็กน้อยและเครียดน้อยลง กระบวนการนั้นน่ารำคาญมากจนมีสามทีมผลัดกันรับผิดชอบเพื่อแบ่งภาระกัน

  • คำว่า “ลด activation energy ของการทำ automation งาน” หมายความว่า ท้ายที่สุด สคริปต์ที่ไม่ทำอะไรเลย จะมีขั้นตอนที่ automate บางอย่างจริง ๆ ในภายหลังใช่ไหม?
    ถ้ามองเป็น placeholder สำหรับ automation ในอนาคต ก็รู้สึกเหมือนเป็นสมดุลที่เหมาะสมระหว่าง automation กับประสิทธิภาพ เราสามารถเริ่มลองครั้งแรกได้โดยไม่ต้องลงทุนมากเกินไป และเหลือ low-hanging fruit ไว้จัดการทีหลังเมื่อความพยายามนั้นเห็นชัดขึ้นว่าคุ้มค่า

    • ใช่
      ตอนนี้แต่ละขั้นตอนของ procedure ถูก encapsulate เป็น function แล้ว ดังนั้นจึงสามารถแทนที่ข้อความของขั้นตอนใดขั้นตอนหนึ่งด้วย code ที่ทำ action จริงโดยอัตโนมัติได้
  • class Foo(object): def run(self, context): ...
    object ที่มี method สำหรับ execute เพียง method เดียวมีอยู่ built-in ใน Python อยู่แล้ว นั่นก็คือ function
    def foo(context): ...

    • แต่ถ้าไม่ได้เสพ abstraction ที่พังเละเทะวันละครั้ง เราจะอยู่รอดได้อย่างไร?
    • ข้อดีของแนวทางเดิมคือ เมื่อภายหลังจำเป็นต้องใช้ ก็สามารถเพิ่ม private method ที่เป็นของ class นั้นเท่านั้นเข้าไปได้เลย
      ในแนวทางแบบ function ถ้าต้องการ function ใหม่ ก็จะเพิ่มในระดับ global ถ้ามีแค่หนึ่งหรือสองอันก็ไม่เป็นไรเลย แต่ถ้ามากกว่านั้น function จะเรียงกันเต็มในระดับเดียวกัน และ dependency ระหว่างพวกมันจะไม่ชัดเจนอีกต่อไป
    • นึกถึงของ Brain Will ที่ https://www.youtube.com/watch?v=QM1iUe6IofM เขามีซีรีส์ที่บ่นเรื่องแนว ๆ นี้อยู่
      ตอนหนึ่งในนั้นพูดถึงตัวอย่างการทำให้ code ที่ถูก abstract เกินจำเป็นกลับมาเรียบง่าย
  • ยอดเยี่ยม แต่หยุดกลางทางไม่ได้
    อยากให้แสดงทุกขั้นตอนล่วงหน้า แล้วค่อย check แต่ละรายการระหว่างดำเนินการ บางครั้งการเตรียมตัวจากมุมมองที่กว้างขึ้นจริง ๆ ก็ดีกว่า
    อาจบันทึก summary เป็น log ลงไฟล์ได้ด้วย
    มีอะไรให้ปรับปรุงได้มากเหลือเกิน จนอาจกลายเป็นว่าทางออกที่เรียบง่ายที่สุดคือทางที่ดีที่สุด

    • ถ้าใช้ command-line library ที่ดีกว่า ก็สามารถแสดง checklist และ output จากการรันของแต่ละขั้นตอนได้ ไม่ว่าขั้นตอนไหนจะถูก automate อยู่หรือไม่ก็เป็นแนวทางที่ดี
      แต่สคริปต์ shell ที่ไม่ทำอะไรเลยนั้นเริ่มต้นง่ายมากจนยากที่จะไม่ทำต่อจนเสร็จ ความพยายามนั้นอาจเอาไปใช้ automate ขั้นตอนหนึ่งแทนจะดีกว่า คุณอาจตกลงไปในหล่มที่สนุกแต่ไม่ค่อย productive เช่น จะใช้ TUI library ตัวไหนดี หรือจะวางโครงสร้างอย่างไร
    • ดีใจที่มีประเด็นเรื่อง “หยุดกลางทางไม่ได้” ขึ้นมา เพราะเหตุนี้ผมจึงใช้ Makefile แทนสคริปต์ Bash
      แต่ละขั้นตอนเป็น rule ชื่อ *.done และเมื่อเสร็จแล้วก็สร้างไฟล์ .done จะหยุดเมื่อไรก็ได้ แก้สคริปต์เพื่อแก้อะไรบางอย่าง แล้ว resume ด้วย make ได้
      แต่การเขียน Makefile นั้นเจ็บปวดจริง ๆ มีทางออกที่ดีกว่านี้ไหม?
    • เวลาทำของแบบนี้ ผมจะเหลือ persistent state ไว้เพื่อให้หยุดกลางทางได้ ตัวอย่างเช่น ถ้าเป็นงานประจำปี ก็รันแบบ ./do-the-thing.sh 2025 แล้วสร้างไดเรกทอรี 2025 เพื่อเก็บ state ว่าทำไปถึงไหนแล้ว
      เมื่ออนุมัติขั้นตอนแรก ก็สามารถ touch ไฟล์ 2025/first-step ได้ ถ้าสคริปต์ตายหรือถูกหยุดแล้วรันอีกครั้ง มันจะตรวจไฟล์นั้นและข้ามขั้นตอนแรก
      เมื่อมีอะไรเปลี่ยนจน automation ไม่ทำงาน การออกมาแก้สคริปต์แล้วรันใหม่โดยไม่เสีย state ไปถือเป็นเรื่องดี
      ปกติผมจะให้สคริปต์บอกขั้นตอน manual ถัดไปเพียงขั้นตอนเดียวแล้ว exit เพื่อให้ใช้ terminal ทำอย่างอื่นได้ สามารถรันสคริปต์ใหม่ได้ง่ายจาก command history
    • นี่เป็นคำวิจารณ์ต่อบทความจริง ๆ หรือเปล่า? แล้วก็ทิ้งบทสรุปไว้แล้วเดินจากไปเสียอย่างนั้น ทางออกไหนคือ “ทางออกที่เรียบง่ายที่สุด” กันแน่?
    • เคยใช้สคริปต์คล้าย ๆ กัน แล้วถ้าเผลอใส่อีเมลผิด ก็กลายเป็น “แล้วตอนนี้ทำยังไงต่อ?” ต้องเริ่มสคริปต์ใหม่ทั้งหมดไหม? การติดอยู่ในสคริปต์ อาจกลายเป็นความเจ็บปวดได้
  • มีการถกเถียงก่อนหน้านี้ด้วย คอมเมนต์เยอะ
    https://news.ycombinator.com/item?id=29083367 - 3 ปีก่อน, 230 คอมเมนต์
    https://news.ycombinator.com/item?id=20495739 - 6 ปีก่อน, 124 คอมเมนต์

  • ผมพูดเกินจริงไม่ได้เลยว่าชอบแนวทางนี้มากแค่ไหน
    นำไปใช้กับหลายโปรเจกต์ได้สำเร็จแล้ว ตัวอย่างที่ชอบที่สุดคือ หุ่นยนต์ผ่าตัดราคา 30 ล้านดอลลาร์ ที่เคยล้มเหลวในการทดสอบในห้องแล็บเพราะ “ปัจจัยมนุษย์”

    • ถ้าช่วยแชร์ตัวอย่างเพิ่มเติมอย่างน้อยหนึ่งตัวอย่างแบบละเอียดขึ้น หรือสรุปประสบการณ์กับเคล็ดลับให้ได้ก็จะดีมาก จะเป็นที่นี่หรือเป็นบทความบล็อกก็อยากอ่าน
      ผมอยู่คนละสายงานคือสายปฏิบัติงานกฎหมาย แต่ก็อยากลองคิดว่าจะนำแนวทางนี้ไปใช้กับบริษัทของเราได้อย่างไร
  • แนวทางนี้ดี ผมชอบวิธีที่ทำคล้าย ๆ กันอยู่แล้ว แม้ในระบบที่ใช้ภาษาโปรแกรมมิงซึ่งมีความซับซ้อนระดับหนึ่งขึ้นไป ฝั่งโปรแกรมมิงเชิงฟังก์ชันดูเหมือนจะเรียกสิ่งนี้ว่า ช่องว่าง (holes)
    ข้อผิดพลาด not implemented ของอินเทอร์เฟซก็ใช้ตรรกะคล้ายกัน แต่ผมมองว่าการเขียนสิ่งเล็ก ๆ ที่ไม่มีความหมายแต่ให้เอาต์พุตที่ถูกต้องตามรูปแบบ สำหรับแต่ละชิ้นส่วนหลาย ๆ ชิ้นที่พึ่งพากันนั้นมีคุณค่ามาก แบบนั้นกระบวนการสร้างชิ้นส่วนเหล่านั้นจะเร็วขึ้น และมีโอกาสมากขึ้นที่จะทดสอบและสร้างทีละชิ้น ลดความจำเป็นที่จะต้องเขียนหลายส่วนพร้อมกันก่อนเริ่มทดสอบ
    ในบริบทของสคริปต์ เช่นกรณีใช้งานที่บทความกล่าวถึง บางครั้งความถูกต้องในระดับชนิดข้อมูลแบบนี้อาจไม่ค่อยสำคัญนัก เพราะผลของคำสั่งบรรทัดคำสั่งจำนวนมาก หากมองจากมุมโปรแกรมมิงเชิงฟังก์ชัน ก็น่าจะเป็น ผลข้างเคียง แต่เพราะมันดำเนินไปตามลำดับ ผลกระทบจึงเล็กกว่ามาก และด้วยพรอมป์ต์ที่รอรับคำสั่ง ก็ยังรักษาลำดับงานไว้ได้ โดยคงขั้นตอนแบบแมนนวลที่อย่างไรก็ต้องทำแม้ไม่มีสคริปต์ไว้ด้วยต้นทุนเพียงเล็กน้อย
    นั่งร้านนี้ไม่สมบูรณ์ แต่โดยพื้นฐานแล้วมีประโยชน์

  • ในทางทฤษฎีฟังดูดี แต่ในทางปฏิบัติน่าจะยาก
    ถ้าทีมปฏิบัติการทำงานเดิมซ้ำ ๆ และเห็นว่าสคริปต์ที่ไม่ทำอะไรเลยนั้นไม่ทำอะไรจริง ๆ พอถึงจุดที่คิดว่าจำขั้นตอนได้แล้ว หรือรู้สึกว่าทำเองเร็วกว่า หรือน่าสนใจกว่า ก็อาจเลิกใช้ในทันที
    ผมเคยเขียนระบบอัตโนมัติและเอกสารสำหรับทีมปฏิบัติการมามาก แต่การทำให้คนใช้มัน และใช้ต่อไปเรื่อย ๆ เป็นปัญหาเสมอ แม้แต่การเปลี่ยนแปลงเอกสารก็ยังต้องประกาศแจ้ง คนเราพอทำอะไรเป็นแล้ว ก็มักเลิกอ่านเอกสารอย่างรวดเร็ว
    ถ้าเป็นโลกที่สมบูรณ์แบบ แนวทางนี้สมเหตุสมผลมาก และผมก็คงใช้กับงานส่วนตัวได้เหมือนกัน แต่ความจริงแทบไม่เคยสมบูรณ์แบบ ถ้าเป็นผมคงใช้วิธีนี้เฉพาะกรณีที่ทำให้เป็นอัตโนมัติไปแล้ว 90% และเหลือขั้นตอนที่ยังแก้ไม่ได้อีก 1 ขั้นเท่านั้น แม้ตอนนั้น สมาชิกบางส่วนของทีมปฏิบัติการก็อาจข้ามขั้นตอนแมนนวลนั้นไป แล้วทึกทักว่าทั้งหมดเป็นเวทมนตร์ที่ทำงานอัตโนมัติแล้วก็ได้

    • โดยปกติ บางส่วนมักทำให้เป็นอัตโนมัติได้ หรือบางขั้นตอนแบบแมนนวลก็ตรวจสอบยืนยันได้ เมื่อนั้นมันก็จะกลายเป็น สคริปต์ที่ทำบางอย่าง ขึ้นมาทันที