Environment & $PATH
เข้าใจ env variables ที่ส่งต่อถึง process และ $PATH กลไกเบื้องหลังที่ shell หา binary เวลาพิมพ์คำสั่ง + which + export + .env
บทที่แล้วเรียนการคุม process ที่กำลังรัน ตอนนี้มาตอบคำถามพื้นฐานกว่านั้น เวลาพิมพ์ node app.js shell รู้ได้ยังไงว่าต้องไปรันไฟล์ไหน ทำไมพิมพ์ node บางเครื่องเจอ บางเครื่องขึ้น command not found ทั้งที่ใช้ชื่อเดียวกัน
คำตอบอยู่ที่ environment variables โดยเฉพาะตัวที่ชื่อ $PATH กลไกนี้ทำงานเงียบๆ เบื้องหลังทุกคำสั่งที่เคยพิมพ์มา รู้จักแล้วจะ debug ปัญหาเรื่องหาคำสั่งไม่เจอได้เอง
Environment variables คืออะไร
Environment variables คือ ตัวแปรสภาพแวดล้อม ที่ shell เก็บไว้ใช้งาน เวลา shell รัน process ลูก process ลูกจะได้ copy ของ env variables ทั้งหมดติดตัวไปด้วย เป็นช่องทางส่งค่าให้ process โดยไม่ต้องใส่ argument
$ echo $HOME # ดูค่าของ HOME
/Users/krish
$ echo $USER # ชื่อผู้ใช้ปัจจุบัน
krish
$ echo $SHELL # ใช้ shell อะไร
/bin/zsh
$ env # list env vars ทั้งหมด
$ printenv PATH # เจาะจงตัวเดียวเวลาเรียกใช้ variable ต้องใส่ $ นำหน้าชื่อ shell จะแทนด้วยค่าก่อนรันคำสั่ง
$PATH: ทำไมพิมพ์ `node` แล้วเจอ
$PATH คือ variable พิเศษที่ เก็บรายการ folder คั่นด้วย : (colon) เมื่อคุณพิมพ์ชื่อคำสั่ง shell จะเดินหา executable ไฟล์ชื่อนั้นในแต่ละ folder ที่อยู่ใน $PATH ทีละอัน จากซ้ายไปขวา หยุดทันทีที่เจอ
$ echo $PATH
/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin
# shell หา node ในลำดับ:
# 1. /usr/local/bin/node ← เจอที่นี่ หยุดค้น
# 2. /opt/homebrew/bin/node (ถ้าไม่เจอข้างบน)
# 3. /usr/bin/node
# 4. /bin/nodeลอง search ใน $PATH ดู
widget ข้างล่างจำลองการเดินใน $PATH ของ Mac เลือก preset หรือพิมพ์ชื่อคำสั่งเอง ดูว่า shell เดินจาก folder แรกไล่ลงไปหยุดเมื่อเจอ ลอง banana ดูว่าเมื่อ shell เดินจนจบแล้วไม่เจอ จะขึ้น command not found
/usr/local/binnodepnpmclaudecode/opt/homebrew/binbrewpython3treejq/usr/bingitlsgrepcatpythoncurl/binshbashcpmvrmechoตั้งค่า env variable เอง: export
export FOO=bar ตั้ง variable FOO ให้ค่า bar ใช้ได้กับ process ลูกที่ shell จะรันต่อไป ตัวแปรนี้อยู่แค่ใน shell session ปัจจุบัน ปิด terminal แล้วหาย
$ export NODE_ENV=production
$ echo $NODE_ENV
production
$ npm start # process นี้ได้ NODE_ENV=production ไปด้วย
$ unset NODE_ENV # ลบ variableถ้าอยากให้ตั้งค่าอัตโนมัติทุกครั้งที่เปิด terminal ต้องใส่ไว้ใน shell config (~/.zshrc หรือ ~/.bashrc) ซึ่งเป็นเนื้อหาบทหน้า
.env file: env vars ประจำ project
ไฟล์ .env ในโฟลเดอร์ project เก็บ env variables เฉพาะ project นั้น shell เองไม่ได้อ่าน ไฟล์นี้ app framework (Next.js, Vite, dotenv) เป็นคนอ่านตอน start แล้ว inject เข้า process
# .env
DATABASE_URL=postgresql://localhost:5432/mydb
NEXT_PUBLIC_API_URL=https://api.example.com
CLERK_SECRET_KEY=sk_test_...ห้าม commit .env เข้า git (มักมี secret) ใส่ .env ใน .gitignore เสมอ ให้ commit .env.example แทน (โครงสร้างไม่มีค่าจริง)
env vars ที่เจอบ่อย
$HOME= home directory ของคุณ$USER= username ของคุณ$SHELL= shell ที่ใช้อยู่ (/bin/zsh)$PATH= รายการ folder หา executable$PWD= current working directory (เปลี่ยนตาม cd)$EDITOR= editor default (vim,code,nano)$NODE_ENV= convention ของ Node (development/production/test)
สรุป
- Environment variables = ตัวแปรสภาพแวดล้อมของ shell, process ลูกได้ติดตัวไปด้วย
$PATHเก็บรายการ folder คั่นด้วย:shell เดินหา executable ทีละอันจากซ้ายไปขวาwhich nodeบอกว่า shell จะรัน node จากไหนexport FOO=barตั้ง var ใน session ปัจจุบัน.envfile เก็บ vars ประจำ project (shell ไม่อ่าน app อ่าน) ต้อง.gitignore
env vars ที่ export ใน session ปัจจุบันหายเมื่อปิด terminal ถ้าอยากให้ตั้งทุกครั้งที่เปิด terminal ต้องใส่ไว้ใน shell config file อย่าง ~/.zshrc หรือ ~/.bashrc บทต่อไปจะเรียนว่าไฟล์พวกนี้คืออะไร ทำงานยังไง พร้อมเรียน alias ที่ทำให้ชีวิตใน terminal สบายขึ้นเยอะ