Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม Bash

เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

Focus หลักของบทความนี้คือเข้าใจชัดเจนว่าเกิดอะไรขึ้นเมื่อคุณ Run Script vs Source Script ใน Bash ก่อนจะเข้าใจชัดเจนว่า Program ถูก Submit ยังไงเมื่อเรียก Script แบบต่างๆ

NOTE: สร้าง Script ด้วย Extension ไม่สำคัญ Script รันได้ดีแม้ไม่มี Extension

ทุก Script เริ่มด้วยบรรทัดที่เรียกว่า Shebang (#!) Hash Symbol ใน Bash จะถูกตีความเป็น Comments แต่ Shebang มีความหมายพิเศษ บอก Bash ให้ Submit Program ใน Interpreter ที่ระบุใน Shebang

ตัวอย่าง Program ระบุ Bash เป็น Interpreter:

$ cat >> Hello_World.sh
#!/usr/bin/env bash
echo "Hello world"
$ chmod +x Hello_world.sh

ตอนนี้ Run Script มี 2 วิธี:

  • ใช้ Relative Path เรียก Script ไป Directory ที่ Script อยู่ รัน ./Hello_world.sh
  • ใช้ Absolute Path เรียก Script จากที่ไหนใน File System พิมพ์ Full Path ไป Script
$ ./Hello_world.sh
$ pwd
$ /home/karthick/Hello_world
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

มาเห็นว่าอะไรเกิดขึ้นเมื่อ Submit Program โดยไม่มี Shebang ในกรณีไม่มี Shebang Program จะ Submit ไป Current Shell ที่คุณรันอยู่ ในกรณีของผมคือ Bash (/bin/bash)

Demo ตัวอย่าง สร้าง Python Script โดยไม่มี Shebang เมื่อเรียก Program Bash ไม่รู้ว่าควร Submit ไป Python Interpreter แทนจะรันใน Current Shell

$ cat > run-py.py
echo $SHELL
print("Hello world")
$ chmod +x run-py.py
$ ./run-py.py
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

กรณีนี้ เรียก Program โดยระบุ Interpreter หรือเพิ่ม Shebang Line ซึ่งแนะนำเสมอ

# which python3
$(which python3) /home/karthick/run_py.py
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

ตอนนี้รู้เรียก Script แล้ว ขั้นต่อไปเข้าใจว่าอะไรเกิดขึ้นเมื่อเรียก Script เมื่อ Invoke Script ตามตัวอย่าง จะสร้าง Child Process (Forking) และ Script จะ Submit ไป Child Process รัน Sample Script ที่รัน Command ด้านล่างแสดง Script Submit ไป Child Process

$ ps -ef --forest | grep -i bash
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

อาจมี Multiple Child Processes ตาม Code สำคัญ: Environment Variables ที่ Subscript สร้างจะ Dropped เมื่อจบ Child Process เข้าถึง Variables ที่ Parent Process สร้างได้โดย Export แต่ Parent Process เข้าถึง Variables ที่ Child Process สร้างไม่ได้

ดูบทความเพิ่มเติมเกี่ยว Variables และ Export:

  • Understanding and Writing 'Linux Variables' in Shell Scripting
  • Learn Difference Between $$ and $BASHPID in Bash

Sourcing the Script

"Source" เป็น Shell Built-in Command อ่าน File ที่ส่งเป็น Argument และรันโค้ดใน Current Shell Environment Use Case ที่เหมาะสมคือแก้ Config ใน .bashrc หรือ .bash_profile Reload Changes ด้วย Source Command

$ type -a source
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

มี 2 Syntactic Ways รัน Source Command เลือกได้ตามสะดวก

$ source FILE_NAME [ARGUMENTS]
$ . FILE_NAME [ARGUMENTS]

มา Demo Source ทำงานยังไง สร้าง 2 Shell Scripts Script แรก (Module.sh) เก็บ Variables และ Functions Script ที่สอง (Main.sh) พิมพ์ Variable และเรียก Function

File Module.sh:

#!/usr/bin/env bash
VAR1=$(echo "Welcome to $1")
function f1(){
  echo "Function f1 is called"
}

File Main.sh:

#!/usr/bin/env bash
echo $VAR1
f1
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

Set Execution Permission เรียก Main Script main.sh Script นี้จะหา Function f1 และ Variable VAR1 ใน Current Shell Environment และ Fail ด้วย Command Not Found

$ bash main.sh
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

ตอนนี้รัน Source Command ภายใน Script จะ Load Variable และ Functions เข้า Current Shell Environment เข้าถึงได้จาก main.sh

File Module.sh:

#!/usr/bin/env bash
VAR1=$(echo "Welcome to $1")
function f1(){
  echo "Function f1 is called"
}

File Main.sh:

#!/usr/bin/env bash
source module.sh Tecmint
echo $VAR1
f1
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

รัน Script อีกครั้งและดู

$ bash main.sh
เข้าใจ Bash: Sourcing vs Forking - ความแตกต่างสำคัญ

Source มีประโยชน์มากใน Bash สำหรับ Modular Programming Approach ในการสร้าง Shell Scripts เราแบ่งโค้ดเป็น Modules เล็กๆ ใช้ในหลาย Programs ทำตามหลัก DRY (Don't Repeat Yourself)

ขอจบเท่านี้ อธิบายความแตกต่างระหว่าง Sourcing และ Forking ใน Bash เรียบร้อย อ่านบทความและแชร์ Feedback ได้เลย