หากคุณใช้strace
คุณสามารถดูวิธีการทำงานของเชลล์สคริปต์เมื่อทำงาน
ตัวอย่าง
สมมติว่าฉันมีเชลล์สคริปต์นี้
$ cat hello_ul.bash
#!/bin/bash
echo "Hello Unix & Linux!"
ใช้มันโดยใช้strace
:
$ strace -s 2000 -o strace.log ./hello_ul.bash
Hello Unix & Linux!
$
การดูภายในstrace.log
ไฟล์จะแสดงสิ่งต่อไปนี้
...
open("./hello_ul.bash", O_RDONLY) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fff0b6e3330) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR) = 0
read(3, "#!/bin/bash\n\necho \"Hello Unix & Linux!\"\n", 80) = 40
lseek(3, 0, SEEK_SET) = 0
getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=4*1024}) = 0
fcntl(255, F_GETFD) = -1 EBADF (Bad file descriptor)
dup2(3, 255) = 255
close(3)
...
เมื่อไฟล์ถูกอ่านแล้วมันจะถูกเรียกใช้งาน:
...
read(255, "#!/bin/bash\n\necho \"Hello Unix & Linux!\"\n", 40) = 40
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc0b38ba000
write(1, "Hello Unix & Linux!\n", 20) = 20
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(255, "", 40) = 0
exit_group(0) = ?
ในด้านบนเราจะเห็นได้อย่างชัดเจนว่าสคริปต์ทั้งหมดดูเหมือนว่ากำลังถูกอ่านเป็นเอนทิตี้เดียวและดำเนินการหลังจากนั้น ดังนั้นมันจะ"ปรากฏขึ้น"อย่างน้อยในกรณีของ Bash ที่อ่านไฟล์จากนั้นเรียกใช้งานไฟล์ ดังนั้นคุณคิดว่าคุณสามารถแก้ไขสคริปต์ในขณะที่ทำงานอยู่
หมายเหตุ:อย่า แต่! อ่านเพื่อทำความเข้าใจว่าทำไมคุณไม่ควรยุ่งกับไฟล์สคริปต์ที่กำลังทำงานอยู่
แล้วล่ามคนอื่นล่ะ
แต่คำถามของคุณจะปิดไปเล็กน้อย ไม่ใช่ลินุกซ์ที่จำเป็นต้องโหลดเนื้อหาของไฟล์มันเป็นล่ามที่กำลังโหลดเนื้อหาดังนั้นมันขึ้นอยู่กับการใช้งานของล่ามไม่ว่าจะโหลดไฟล์ทั้งหมดหรือในบล็อกหรือบรรทัดในเวลาเดียวกัน
เหตุใดเราจึงไม่สามารถแก้ไขไฟล์ได้
หากคุณใช้สคริปต์ที่มีขนาดใหญ่กว่ามาก แต่คุณจะสังเกตได้ว่าการทดสอบด้านบนนั้นทำให้เข้าใจผิดเล็กน้อย ในความเป็นจริงล่ามส่วนใหญ่โหลดไฟล์ในบล็อก นี่เป็นมาตรฐานที่ค่อนข้างสวยด้วยเครื่องมือ Unix จำนวนมากที่พวกมันโหลดบล็อกของไฟล์ประมวลผลแล้วโหลดบล็อกอื่น คุณสามารถเห็นพฤติกรรมนี้ด้วยคำถาม & คำตอบ U ที่ฉันเขียนขึ้นเมื่อไม่นานมานี้เกี่ยวกับgrep
หัวข้อ: grep / egrep ใช้ข้อความในปริมาณเท่าไหร่ในแต่ละครั้ง .
ตัวอย่าง
สมมติว่าเราทำเชลล์สคริปต์ต่อไปนี้
$ (
echo '#!/bin/bash';
for i in {1..100000}; do printf "%s\n" "echo \"$i\""; done
) > ascript.bash;
$ chmod +x ascript.bash
ส่งผลให้ไฟล์นี้:
$ ll ascript.bash
-rwxrwxr-x. 1 saml saml 1288907 Mar 23 18:59 ascript.bash
ซึ่งมีเนื้อหาประเภทต่อไปนี้:
$ head -3 ascript.bash ; echo "..."; tail -3 ascript.bash
#!/bin/bash
echo "1"
echo "2"
...
echo "99998"
echo "99999"
echo "100000"
ตอนนี้เมื่อคุณเรียกใช้สิ่งนี้โดยใช้เทคนิคเดียวกันกับstrace
:
$ strace -s 2000 -o strace_ascript.log ./ascript.bash
...
read(255, "#!/bin/bash\necho \"1\"\necho \"2\"\necho \"3\"\necho \"4\"\necho \"5\"\necho \"6\"\necho \"7\"\necho \"8\"\necho \"9\"\necho \"10\"\necho
...
...
\"181\"\necho \"182\"\necho \"183\"\necho \"184\"\necho \"185\"\necho \"186\"\necho \"187\"\necho \"188\"\necho \"189\"\necho \"190\"\necho \""..., 8192) = 8192
คุณจะสังเกตเห็นว่าไฟล์กำลังถูกอ่านที่เพิ่มขึ้น 8KB ดังนั้น Bash และเชลล์อื่น ๆ จะไม่โหลดไฟล์ทั้งหมด แต่จะอ่านเป็นบล็อก
อ้างอิง