Eğer kullanırsanız strace
bunu yayınlandığında, bir bir kabuk yürütülür görebilirsiniz.
Örnek
Diyelim ki bu kabuk betiği var.
$ cat hello_ul.bash
#!/bin/bash
echo "Hello Unix & Linux!"
Kullanarak çalıştırma strace
:
$ strace -s 2000 -o strace.log ./hello_ul.bash
Hello Unix & Linux!
$
strace.log
Dosyanın içine bir göz atmak aşağıdakileri ortaya çıkarır.
...
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)
...
Dosya bir kez okunduğunda, yürütülür:
...
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) = ?
Yukarıda, tüm betiğin tek bir varlık olarak okunduğunu ve daha sonra orada yürütüldüğünü açıkça görebiliyoruz. Böylece en azından Bash'in dosyasında dosyayı okuduğu ve sonra çalıştırdığı "belirir" . Yani sen çalışırken senaryoyu düzenleyebileceğini mi düşünüyorsun?
NOT: Yine de yapma! Çalışan bir komut dosyasıyla neden uğraşmamanız gerektiğini anlamak için okumaya devam edin.
Peki ya diğer tercümanlar?
Ama sorunuz biraz kapalı. Mutlaka dosyanın içeriğini yükleyen Linux değil, içeriği yükleyen tercümandır, bu yüzden tercümanın dosyayı bir seferde tamamen mi yoksa bloklar halinde mi yükleyeceği ile ilgili.
Peki neden dosyayı düzenleyemiyoruz?
Daha büyük bir komut dosyası kullanıyorsanız, ancak yukarıdaki testin biraz yanıltıcı olduğunu fark edeceksiniz. Aslında çoğu tercüman dosyalarını bloklar halinde yerleştirir. Bu, bir dosyanın bloklarını yükledikleri, işledikleri ve daha sonra başka bir blok yükledikleri birçok Unix araçlarında oldukça standart. Bu davranışı, bir süre önce yazdığım U&L Sorular ve Cevapları ile görebilirsiniz grep
: “ grep / egrep her seferinde ne kadar metin tüketir? .
Örnek
Aşağıdaki kabuk betiğini yaptığımızı söyleyin.
$ (
echo '#!/bin/bash';
for i in {1..100000}; do printf "%s\n" "echo \"$i\""; done
) > ascript.bash;
$ chmod +x ascript.bash
Bu dosyada sonuçlanan:
$ ll ascript.bash
-rwxrwxr-x. 1 saml saml 1288907 Mar 23 18:59 ascript.bash
Aşağıdaki içerik türünü içerir:
$ head -3 ascript.bash ; echo "..."; tail -3 ascript.bash
#!/bin/bash
echo "1"
echo "2"
...
echo "99998"
echo "99999"
echo "100000"
Şimdi bunu yukarıdaki teknikle aynı şekilde çalıştırdığınızda 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
Dosyanın 8KB'lik artışlarla okunduğunu fark edeceksiniz; bu nedenle Bash ve diğer kabukları bir dosyayı tamamen yüklemeyecek, bloklar halinde okuyacaklar.
Referanslar