ทำไมถึงมีทั้งตัวแปรสภาพแวดล้อม TMP และ TEMP? (2015)
(devblogs.microsoft.com)- บน Windows ยังคงมีทั้ง
TMPและTEMPที่ใช้ระบุตำแหน่งไฟล์ชั่วคราว และเมื่อทั้งสองค่าไม่ตรงกัน จะใช้ตัวไหนขึ้นอยู่กับการติดตั้งใช้งานของแต่ละโปรแกรม - CP/M ไม่มีตัวแปรสภาพแวดล้อม จึงต้องกำหนดตำแหน่งไฟล์ชั่วคราวแยกในแต่ละโปรแกรม และโปรแกรมอย่าง WordStar ใช้วิธีแพตช์ไบต์บางตำแหน่งในไฟล์ปฏิบัติการเพื่อเปลี่ยนพฤติกรรมการทำงาน
- MS-DOS เพิ่ม ตัวแปรสภาพแวดล้อม เข้ามาโดยยังคำนึงถึงความเข้ากันได้กับ CP/M อย่างมาก แต่โปรแกรม MS-DOS ยุคแรกแทบไม่ใช้
TEMPหรือTMPเพราะยังติดแนวคิดเดิมจาก CP/M - เมื่อโปรแกรม MS-DOS เริ่มใช้ตัวแปรสภาพแวดล้อมเป็นวิธีเก็บค่าการตั้งค่า
TEMPกับTMPจึงเริ่มแข่งขันกัน และบางโปรแกรม เช่นDISKCOPYและEDITจะค้นหาTEMPก่อนTMP - การทำงานของ pipe ใน MS-DOS 2.0 เลือกใช้
TEMPสำหรับตำแหน่งไฟล์ชั่วคราว แต่GetTempFileNameของ Windows ตรวจสอบTMPก่อน ทำให้ทั้งสองตัวแปรยังคงอยู่ร่วมกันต่อมา
ที่มาที่ทำให้ TMP และ TEMP ยังอยู่ทั้งคู่
- ในตัวแปรสภาพแวดล้อมของ Windows มีทั้ง
TMPและTEMPสำหรับระบุตำแหน่งไฟล์ชั่วคราว และถ้าทั้งสองต่างกัน โปรแกรมไหนจะถือว่าค่าใดถูกต้องก็ขึ้นอยู่กับแต่ละโปรแกรม - โปรแกรมหนึ่งจะสร้างไฟล์ชั่วคราวไว้ที่ใดขึ้นอยู่กับการติดตั้งใช้งานของโปรแกรมนั้นเอง โดยโปรแกรมบน Windows มีแนวโน้มจะใช้ฟังก์ชัน
GetTempFileNameและในกรณีนั้นTMPจะมาก่อน - สาเหตุที่ในหน้าต่างตั้งค่าตัวแปรสภาพแวดล้อมยังเห็นทั้ง
TMPและTEMPพร้อมกัน เป็นเพราะไม่มีฝ่ายใดถูกทำให้เป็นมาตรฐานเดียวอย่างสมบูรณ์ และในทางประวัติศาสตร์ทั้งสองทางเลือกอยู่ร่วมกันมา
CP/M ไม่มีตัวแปรสภาพแวดล้อม
- ราวปี 1973 ระบบปฏิบัติการที่พบได้บ่อยบนไมโครคอมพิวเตอร์คือ CP/M และ CP/M ไม่มีตัวแปรสภาพแวดล้อม
- เมื่อไม่มีตัวแปรสภาพแวดล้อม จึงไม่มี
TMPหรือTEMPด้วย - หากต้องการกำหนดตำแหน่งเก็บไฟล์ชั่วคราวให้โปรแกรม ก็ต้องตั้งค่าแยกเป็นรายโปรแกรม เช่น แพตช์ไบต์บางตำแหน่งในไฟล์ปฏิบัติการเพื่อระบุอักษรไดรฟ์ที่จะใช้เก็บไฟล์ชั่วคราว
- โปรแกรมอย่าง WordStar มีคู่มือที่บอกว่าแพตช์ไบต์ใดแล้วพฤติกรรมใดจะเปลี่ยนไป และยังเตรียมพื้นที่สำหรับแพตช์เพื่อใส่ซับรูทีนแบบกำหนดเอง เช่น การรองรับเครื่องพิมพ์
การมาถึงของ MS-DOS และตัวแปรสภาพแวดล้อม
- ในปี 1981 โปรเซสเซอร์ 8086 และ MS-DOS ปรากฏขึ้น โดยทั้งคู่ได้รับอิทธิพลจาก CP/M อย่างมาก
- หนึ่งในเป้าหมายการออกแบบยุคแรกของ MS-DOS คือทำให้สามารถแปลโปรแกรม CP/M สำหรับโปรเซสเซอร์ 8080 ไปเป็นโปรแกรม MS-DOS สำหรับโปรเซสเซอร์ 8086 ได้แบบเชิงกล
- ตัวแปลนี้ตั้งอยู่บนสมมติฐานว่าโปรแกรมจะไม่ใช้รูปแบบแปลก ๆ เช่น self-modifying code, การกระโดดเข้าไปกลางคำสั่ง, หรือการใช้โค้ดเป็นข้อมูล
- รีจิสเตอร์ H และ L ของ 8080 สอดคล้องกับรีจิสเตอร์ BH และ BL ของ 8086 และเพราะใน 8080 รีจิสเตอร์ที่ใช้เข้าถึงแอดเดรสที่คำนวณไว้ได้มีเพียง HL จึงกลายเป็นเหตุผลว่าทำไมใน 8086 จาก AX, BX, CX, DX มีเพียง BX ที่ใช้เข้าถึงหน่วยความจำได้
- นอกจากความเข้ากันได้กับ CP/M แล้ว MS-DOS ยังเพิ่มตัวแปรสภาพแวดล้อมเข้ามา แต่เพราะโปรแกรม CP/M เดิมไม่ได้ใช้ตัวแปรสภาพแวดล้อม โปรแกรม MS-DOS ยุคแรกจึงไม่ใช้มันเช่นกัน
- ผู้ใช้จะตั้งค่า
TEMPหรือTMPได้ก็จริง แต่โปรแกรมยุคแรก ๆ แทบไม่สนใจค่าเหล่านี้
TEMP และ TMP แข่งขันกันในตลาด
- เมื่อเวลาผ่านไปและเริ่มมีการเขียนโปรแกรมที่มุ่งเป้าไปยัง MS-DOS เป็นหลัก โปรแกรมต่าง ๆ ก็เริ่มใช้ตัวแปรสภาพแวดล้อมเป็นที่เก็บข้อมูลการตั้งค่า
TEMPและTMPจึงเริ่มถูกใช้เป็นตัวแปรสภาพแวดล้อมสำหรับระบุตำแหน่งไฟล์ชั่วคราว และกลายเป็นสองตัวเลือกหลัก- โปรแกรมจะตรวจสอบตัวแปรใดก่อนขึ้นอยู่กับการเลือกในการติดตั้งใช้งานของโปรแกรมนั้น
- หลายโปรแกรมตรวจสอบทั้งคู่เพื่อให้รองรับได้ทุกทาง แต่จะดูตัวใดก่อนนั้นแตกต่างกันไปตามแต่ละการติดตั้งใช้งาน
- โปรแกรมรุ่นเก่าบางตัวอย่าง
DISKCOPYและEDITจะค้นหาTEMPก่อนTMP
pipe ของ MS-DOS 2.0 และ TEMP
- MS-DOS 2.0 เพิ่มความสามารถของ pipe สำหรับส่งเอาต์พุตของโปรแกรมหนึ่งไปเป็นอินพุตของอีกโปรแกรมหนึ่ง
- เนื่องจาก MS-DOS เป็นระบบปฏิบัติการแบบงานเดี่ยว pipe จึงถูกจำลองขึ้นโดยรีไดเร็กต์เอาต์พุตของโปรแกรมแรกไปยังไฟล์ชั่วคราว รันจนจบ แล้วค่อยรันโปรแกรมที่สองโดยให้รับอินพุตจากไฟล์ชั่วคราวนั้น
- ความสามารถนี้ทำให้ตัว MS-DOS เองต้องมีตำแหน่งสำหรับสร้างไฟล์ชั่วคราว
- ตัวแปรที่ถูกเลือกมาใช้ควบคุมตำแหน่งไฟล์ชั่วคราวนั้นคือ
TEMP - แม้
COMMAND.COMจะเลือกใช้TEMPแต่โปรแกรมอื่น ๆ จะใช้TEMPหรือTMPก็ยังคงเป็นการตัดสินใจของแต่ละโปรแกรม
บน Windows มีเส้นทางที่ทำให้ TMP มาก่อน
- Windows ก็ผ่านกระบวนการคล้ายกัน แต่การติดตั้งใช้งานช่วงแรกของ
GetTempFileNameถูกสร้างให้ตรวจสอบTMPก่อนTEMP - หากโปรแกรมบน Windows ใช้
GetTempFileNameเพื่อสร้างไฟล์ชั่วคราว ก็จะมีแนวโน้มให้ความสำคัญกับTMPมากกว่า - ดังนั้นจึงไม่มีคำตอบเดียวสำหรับคำถามว่า “ตัวแปรไหนถูกต้อง” เพราะขึ้นอยู่กับว่าโปรแกรมใช้ API ใดหรือใช้ตรรกะภายในแบบใด
- จนถึงปัจจุบัน ในหน้าต่างตั้งค่าตัวแปรสภาพแวดล้อมก็ยังคงมีทั้ง
TMPและTEMPอยู่ และทั้งสองตัวยังคงอยู่ร่วมกันต่อไปในเรื่องตำแหน่งไฟล์ชั่วคราว
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
น่าสนใจดี เป็นเรื่องก่อนยุคของผม เลยไม่เคยได้ยินว่ามีการ ตั้งค่าโปรแกรม CP/M ด้วยการแพตช์
ผมเคยใช้ความสามารถนี้เขียนรูทีนคีย์บอร์ดและการแสดงผลหน้าจอที่เร็วขึ้นให้ WordStar ของตัวเอง
จำได้ว่าในเอกสารของ WordStar 7 มีตำแหน่งแพตช์ที่ใช้
debug.exeของ DOS เพื่อเปลี่ยนพฤติกรรมของโปรแกรมรวมอยู่ด้วยconfig.hแล้วคอมไพล์ใหม่https://suckless.org/
เพิ่มเติมคือผมเพิ่งเห็นทีหลังว่ามีคนพูดถึงเรื่องนี้ไปแล้วในเธรดย่อยอื่นของหน้านี้
โปรแกรม CP/M หลายตัวต้องรันได้บน RAM 32K กับฟลอปปีดิสก์ช้า ๆ ขนาด 130K หรือแย่กว่านั้นคือเทปคาสเซ็ตด้วยซ้ำ ถ้ามี RAM 64K กับดิสก์ 360K ถือว่าค่อนข้างหรูแล้ว
สมัยนั้นต่างจากทุกวันนี้ตรงที่โปรแกรมไม่ได้ถูกปรับให้เหมาะกับตลาดระดับบน แต่ปรับให้ลงไปได้ถึงระดับล่างสุด ยิ่งรันได้บนเครื่องมากเท่าไร ก็ยิ่งขายได้มากเท่านั้น โดยไม่ต้องผลักภาระให้ลูกค้าไปอัปเกรดฮาร์ดแวร์
ไม่มีพื้นที่พอสำหรับไฟล์คอนฟิกแยกภายนอก หรือโปรแกรมที่จะสร้างไฟล์คอนฟิกนั้นขึ้นมา แม้แต่การรองรับอาร์กิวเมนต์บรรทัดคำสั่งก็ยังกินไบต์อันมีค่า
ทุกวันนี้คนบ่นว่า MacBook Neo มี RAM แค่ 8,000,000,000 ไบต์ แต่ในปี 1978 ยังสร้าง IDE พื้นฐานที่มีขนาด 2,048 ไบต์ ได้เลย
ผมชอบบล็อกของ Raymond แต่การบอกว่าไมโครคอมพิวเตอร์ในปี 1973 ใช้ CP/M กันทั่วไปมันแปลก ๆ
ไมโครคอมพิวเตอร์ในปี 1973 ยังใกล้เคียงกับต้นแบบระดับระบบพัฒนาอย่าง Intel Intellec และยังไม่มีระบบปฏิบัติการด้วยซ้ำ จริงอยู่ที่ Kildall เริ่มพัฒนา CP/M ในปี 1973 แต่ตอนนั้นมันรันได้แค่บน ซิมูเลเตอร์ของเมนเฟรม PDP-10
ถ้าพูดปี 1979 ยังพอว่า แต่นี่ปี 1973 เร็วเกินไปมาก
พอนึกแบบนั้นก็ทำให้รู้สึกว่าในปี 2020 ยังไม่มี ChatGPT เลย
เป็นตัวอย่างที่ดีของการตัดสินใจที่นักพัฒนายุคแรกทำไปแบบแทบไม่คิด แต่ อยู่ต่อไปอีกหลายสิบปี
attorniesไปตลอดกาล เพราะช่วงแรกไม่มีใครสังเกตเห็นว่ามันสะกดผิดที่โปรแกรมต่าง ๆ เลือกใช้
TMPน่าจะเป็นเพราะส่วนขยายไฟล์ของ MS-DOS ยาวได้แค่ 3 ตัวอักษร และมีธรรมเนียมใช้ ส่วนขยาย.TMPสำหรับไฟล์ชั่วคราวคล้ายกับที่โปรแกรม Unix ดู
http_proxyหรือHTTP_PROXYกันไม่สม่ำเสมอทุกวันนี้หลายโปรแกรมรองรับทั้งคู่ แต่ลำดับที่ตรวจอาจไม่เหมือนกัน
การพูดถึง CP/M ทำให้งง ผู้เขียนเหมือนจะบอกว่ามันจะมีความสำคัญในภายหลัง แต่สุดท้ายกลับอธิบายว่า มันไม่ได้เกี่ยวกับ CP/M หรือ CPU 8080 เลย
แก่นจริง ๆ คือ Microsoft ใช้เองอยู่แท้ ๆ แต่ ไม่คิดจะทำให้เป็นมาตรฐาน
TMPหรือTEMPก็คงมีอยู่แล้ว และ DOS ก็น่าจะทำตามแต่ปัญหาจริงคือ CP/M ไม่มีไดเรกทอรี และ DOS 1.0 ก็ไม่มีเหมือนกัน
ราวปี 1995 ที่ Telstra หรือ Australia Telecom มีเดสก์ท็อปทั่วทั้งองค์กรประมาณ 50,000 เครื่อง
วันหนึ่งมีไฟล์เล็ก ๆ ชื่อ
nullโผล่ขึ้นมาในโฮมไดเรกทอรีบนเครือข่ายของทุกคน และดูเหมือนจะเป็นฝีมือของ ผู้ใช้ Unix ที่ลองเขียนไฟล์.batก็ประมาณว่า ทำไมต้องทำตามมาตรฐานที่มีอยู่แล้วด้วยล่ะ ผมอยากถามว่า “ทำไมต้องมาตรฐาน” เหมือนกัน แต่ก็คิดว่าอาจจะทำให้คนอเมริกาเหนือสับสนได้
/dev/nullก่อนแล้วไม่สำเร็จ เลยเปลี่ยนเป็นnullเฉย ๆไม่อย่างนั้นจะบอกว่าเป็นโปรแกรมเมอร์ Unix ก็ดูไม่สมเหตุสมผล น่าจะเป็นโปรแกรมเมอร์ DOS ที่เขียน
NULผิดเป็นnullมากกว่ามันมองหาไฟล์ชื่อ
NULLบนฮาร์ดดิสก์ ซึ่งแน่นอนว่าในไฟล์.BATมีไวยากรณ์อย่าง> NULLพูดตามตรง สำหรับหลายโปรแกรม การตั้งค่าแบบแพตช์สไตล์ CP/M อาจดีกว่าวิธี โปรย dotfile เต็มโฮมไดเรกทอรี
ตอนนี้มีโครงการมากขึ้นเรื่อย ๆ ที่นำไปใช้ รวมถึงพวกที่เคยดื้ออย่าง Firefox ด้วย
ถ้ามองแบบโอเพนซอร์สสมัยใหม่ ก็ถือว่าเป็นแนวทางที่คล้ายกัน เพียงแต่ด้วยความมินิมัลสุดโต่งโดยรวม โปรเจกต์เหล่านี้อาจจะถูกจริตคนบางกลุ่มมากกว่า
.configทั้งหมดปัญหาคือนักพัฒนาแอปจำนวนมากคิดว่าแอปของตัวเองพิเศษพอที่จะสมควรมี ไดเรกทอรีแยกต่างหาก
grepได้และจัดการด้วยโปรแกรมแก้ไขข้อความ ดีกว่าคอนฟิกที่กระจัดกระจายอยู่ทั่วไบนารีรีจิสทรีส่วนกลางหรือบางทีอาจเป็นเพราะผมคุ้นแบบนั้นมากกว่า
.configได้ ไม่ว่ายังไงสำหรับผมก็คือผู้ชนะแต่ก็ดูเหมือนว่าเราอาจพลาดจังหวะนั้นไปแล้ว
ไม่เคยรู้เลยว่ามันสับสนขนาดนี้
บทเรียนก็น่าจะเป็นว่า ทำให้มันชี้ไปยังพาธเดียวกันเสมอ ไม่งั้นมีเรื่องแน่
ผมหงุดหงิดกับเรื่องแบบนี้ของ Microsoft มาหลายสิบปีแล้ว
สมัยก่อนจะมี “นักพัฒนาระดับอาวุโส” ที่ทำเหมือนรู้ทุกอย่างและมีคำตอบเสมอ ประมาณว่า “
tempคือ temporary ส่วนtmpคือ troubleshoot my pc เอาไว้สำหรับล็อกดีบัก นี่แหละทำไมฉันถึงเป็นซีเนียร์ แต่นายไม่ใช่”พอผมอาวุโสขึ้นเองก็พบว่าการตั้งคำถามนั้นถูกต้อง และตอนนี้พอคุยกับนักพัฒนา Microsoft รุ่นดั้งเดิมจริง ๆ ก็จะอธิบายว่า มันเป็นความผิดพลาด แต่คงไว้เพราะ backward compatibility
แต่ผมก็อดถามไม่ได้ว่าทำไมข้ออ้างนั้นถึงใช้ได้ ในเมื่ออ้างเรื่อง backward compatibility แต่ก็ยังดันการเปลี่ยนแปลงอย่าง New Outlook ที่ทำลายความเข้ากันได้สำคัญและเวิร์กโฟลว์การทำงานจริงอยู่บ่อย ๆ แล้วก็จบด้วยการปัดว่า “ฉันไม่ใช่นักพัฒนาที่แย่ ไปถามคนใหม่เอาเอง”
ซึ่งคนใหม่ก็ถามไม่ได้ แถมยังซ่อนอยู่หลังด่านคัดเลือกแบบ LeetCode อีก เลยไม่แปลกที่ปัญหาใช้งานจริงแบบนี้ไม่ถูกแก้ และของอย่าง New Outlook ถึงออกมาได้ เพราะซีเนียร์แบบนั้นตอนนี้ไปอยู่ที่นั่นแล้ว ส่วนนักพัฒนาของจริงก็เกษียณกันหมด
ต่อให้ Microsoft ให้คำอธิบายดูมีเหตุผลเกี่ยวกับปัญหาที่โปรแกรมสุ่มเอาโฟลเดอร์ Documents ในโฮมผู้ใช้ไปใช้อย่างไม่เหมาะสม หรือ OneDrive เผลอลบมันทิ้งแบบบังคับ แต่ภายใน 6 เดือน Microsoft ก็จะผลักการเปลี่ยนแปลงสุ่ม ๆ เข้ามาอีกจนทำให้พฤติกรรมแย่ลงและเหตุผลแกนนั้นพังไปเอง
Notepad ก็คล้ายกัน ในบทสัมภาษณ์นักพัฒนาบอกว่าเพราะความเสี่ยงต้องเป็นศูนย์ มันเลยต้องเป็นโปรแกรมที่เรียบง่ายมาก แต่ต่อมากลับมี การล็อกอินด้วยบัญชี Microsoft และ Copilot โผล่มา
ผมคิดว่าทัศนคติแบบนักพัฒนา LeetCode กับวัฒนธรรม Microsoft ทำให้อุตสาหกรรมทั้งวงการแย่ลง เพราะคุยกันอย่างสงบไม่ได้ และสุดท้ายจะลงเอยที่ “คุณไม่ได้ทำงานที่ Microsoft งั้นข้อโต้แย้งของคุณก็ใช้ไม่ได้”
ผมยังจำได้ชัดว่า Google Chrome เคยติดตั้งลง
AppDataเพื่อเลี่ยงสิทธิ์ผู้ดูแลระบบ จุดประสงค์ดั้งเดิมของฟีเจอร์นั้นชัดเจนว่าไม่ได้มีไว้ให้บุคคลที่สามใช้ติดตั้งโดยไม่ต้องมีสิทธิ์แอดมินแต่เพราะตอนนั้น Chrome ดีมาก และมีความวุ่นวายจากการต้องกระจายโปรแกรมยกเว้นของบุคคลที่สามไปยังคอมพิวเตอร์องค์กรที่ถูกล็อกไว้หลายล้านเครื่อง นักพัฒนาจึงค่อย ๆ ปรับกรอบให้มันกลายเป็นฟีเจอร์ที่ตั้งใจไว้ตั้งแต่แรก