কীভাবে লিনাক্স শেল স্ক্রিপ্টগুলির সাথে ডিল করে?


22

এই প্রশ্নের জন্য, আসুন একটি বাশ শেল স্ক্রিপ্ট বিবেচনা করুন, যদিও এই প্রশ্নটি অবশ্যই সমস্ত ধরণের শেল স্ক্রিপ্টের জন্য প্রযোজ্য।

যখন কেউ শেল স্ক্রিপ্ট কার্যকর করে, তখন লিনাক্স কি সমস্ত স্ক্রিপ্ট একবারে লোড করে (সম্ভবত স্মৃতিতে) বা এটি স্ক্রিপ্ট কমান্ড একের পর এক করে (লাইন দ্বারা লাইন) পড়ে?

অন্য কথায়, আমি যদি একটি শেল স্ক্রিপ্ট এক্সিকিউট করি এবং এক্সিকিউশন শেষ হওয়ার আগে এটি মুছে ফেলি, তাহলে কি এক্সিকিউশনটি সমাপ্ত হবে বা এটি যেমন চলবে তেমন থাকবে?


3
চেষ্টা করে দেখুন (এটি অবিরত থাকবে))
ডিভনুল

1
@ দেবনুল এখানে একটি আকর্ষণীয় প্রশ্ন আছে। মঞ্জুর, এটি চালিয়ে যাওয়া হবে কিনা তা পরীক্ষার পক্ষে তুচ্ছ তবে বাইনারি ফাইলগুলির মধ্যে পার্থক্য রয়েছে (যা মেমরিতে লোড করা হয়) এবং শেবাং লাইনযুক্ত স্ক্রিপ্টগুলির সাথে, বা শেবাং লাইন ছাড়াই স্ক্রিপ্টগুলি।
টেরডন


23
আপনার বাস্তব অভিপ্রায়টির উদ্দেশ্যে, কার্যকর করার সময় শেল স্ক্রিপ্টটি মুছে ফেলার জন্য, এটি একবারে বা লাইনে-লাইন একসাথে পড়ে কিনা তা বিবেচ্য নয়। ইউনিক্সে, কোনও আনোড প্রকৃতপক্ষে মুছে ফেলা হয় না (এমনকি কোনও ডিরেক্টরি থেকে এর কোনও লিঙ্ক না থাকলেও) এটির শেষ উন্মুক্ত ফাইলটি বন্ধ না হওয়া পর্যন্ত। অন্য কথায়, যদি আপনার শেলটি ফাঁসির সময় শেল স্ক্রিপ্ট লাইনে লাইনে পড়তে পারে তবে এটি মুছে ফেলা নিরাপদ। একমাত্র ব্যতিক্রম হ'ল যদি আপনার শেলটি এমন ধরণের হয় যা শেল স্ক্রিপ্টটি প্রতিবার বন্ধ করে এবং পুনরায় খোলে, তবে যদি এটি হয় তবে আপনার অনেক বড় (সুরক্ষা) সমস্যা রয়েছে।
ক্রিস জেস্টার-ইয়ং

উত্তর:


33

আপনি যদি ব্যবহার করেন তবে 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)                           = ?

উপরের অংশে আমরা পরিষ্কারভাবে দেখতে পারি যে পুরো লিপিটি একক সত্তা হিসাবে পাঠ করা হয়েছে এবং তারপরে সেখানে সম্পাদন করা হয়েছে uted সুতরাং এটি কমপক্ষে বাশের ক্ষেত্রে "উপস্থিত" হবে যে এটি ফাইলটি পড়ে এবং তারপরে এটি কার্যকর করে। সুতরাং আপনি কি ভাবছেন যে স্ক্রিপ্টটি চলাকালীন সম্পাদনা করতে পারবেন?

দ্রষ্টব্য: যদিও না! চলমান স্ক্রিপ্ট ফাইলের সাথে কেন আপনার গোলযোগ করা উচিত তা বুঝতে পড়ুন।

অন্যান্য দোভাষী সম্পর্কে কি?

তবে আপনার প্রশ্নটি কিছুটা বন্ধ। এটি লিনাক্স নয় যে অগত্যা ফাইলটির বিষয়বস্তু লোড করা উচিত, এটি অনুবাদকরা যে বিষয়বস্তুগুলি লোড করে চলেছে, তাই অনুবাদক কীভাবে এটি প্রয়োগ করেছিলেন যে এটি একবারে ফাইলটি সম্পূর্ণরূপে বা ব্লক বা লাইনে লোড করে কিনা to

তাহলে আমরা ফাইলটি সম্পাদনা করতে পারি না কেন?

আপনি যদি আরও বড় স্ক্রিপ্ট ব্যবহার করেন তবে আপনি লক্ষ্য করবেন যে উপরের পরীক্ষাটি কিছুটা বিভ্রান্তিকর। আসলে বেশিরভাগ দোভাষী তাদের ফাইলগুলি ব্লকে লোড করে। এটি অনেকগুলি ইউনিক্স সরঞ্জামের সাথে স্ট্যান্ডার্ড যেখানে তারা কোনও ফাইলের ব্লক লোড করে, প্রক্রিয়াজাত করে এবং অন্য একটি ব্লক লোড করে। grepশিরোনাম: আমি এই U&L প্রশ্নোত্তরের সাথে এই আচরণটি দেখতে পাচ্ছি যে শিরোনামটি সম্পর্কে: গ্রিপ / এগ্রিপ প্রতিটি বার কত পাঠ্য ব্যবহার করে?

উদাহরণ

বলুন আমরা নীচের শেল স্ক্রিপ্টটি তৈরি করি।

$ ( 
    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 ইনক্রিমেন্টে পড়ছে, সুতরাং বাশ এবং অন্যান্য শেলগুলি সম্ভবত কোনও ফাইল পুরোপুরি লোড করবে না, বরং তারা এগুলি ব্লকগুলিতে পড়ে।

তথ্যসূত্র


@ ইটারডন - হ্যাঁ আমি আগে এই প্রশ্নোত্তর দেখেছি মনে আছে।
slm

5
40-বাইট স্ক্রিপ্ট সহ, অবশ্যই এটি একটি ব্লকে পড়ে read একটি> 8 কেবি স্ক্রিপ্ট দিয়ে চেষ্টা করুন।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

আমি কখনই চেষ্টা করি নি, তবে আমি মনে করি ফাইলগুলি অপসারণ প্রকৃতপক্ষে সম্পন্ন হয় না যতক্ষণ না সমস্ত প্রক্রিয়া সরিয়ে ফেলা ফাইলের সাথে সম্পর্কিত ফাইল বর্ণনাকারী বন্ধ করে দেয়, যাতে বাশ মুছে ফেলা ফাইল থেকে পড়া চালিয়ে যেতে পারে।
ফরিদ নুরি নেশাত

@ গিলস - হ্যাঁ আমি একটি উদাহরণ যুক্ত করেছি, এটি পেয়ে যাচ্ছিলাম।
slm

2
এই আচরণটি সংস্করণ নির্ভর is আমি বাশ সংস্করণ ৩.২.৫১ (১) -রিলিজ দিয়ে পরীক্ষা করেছি এবং খুঁজে পেয়েছি যে এটি বর্তমান লাইনটি পেরেছে না ( এই স্ট্যাকওভারফ্লো উত্তরটি দেখুন )।
গর্ডন ডেভিসন

11

এটি ওএস নির্ভরতার চেয়ে বেশি শেল নির্ভর।

সংস্করণটির উপর নির্ভর করে, kshস্ক্রিপ্টটি 8 কে বা 64 কে বাইট ব্লক দ্বারা চাহিদা অনুযায়ী পড়ুন।

bashলিখিতভাবে স্ক্রিপ্ট লাইন পড়ুন। যাইহোক, সত্য লাইনগুলি নির্বিচারে দৈর্ঘ্যের হতে পারে, এটি পরের লাইনের শুরু থেকে পার্স করার জন্য প্রতিবার 8176 বাইট পড়ে reads

এটি সাধারণ নির্মাণের জন্য, অর্থাত্ প্লেইন কমান্ডের স্যুট।

শেল স্ট্রাকচার্ড কমান্ডগুলি যদিfor/do/done লুপ, একটি case/esacসুইচ, একটি এখানে নথি, বন্ধনী দ্বারা আবদ্ধ একটি সাব-শেল, একটি ফাংশন সংজ্ঞা ইত্যাদির মতো এবং উপরের কোনও সংমিশ্রণের মতো শেল স্ট্রাকচার্ড কমান্ডগুলি ব্যবহার করা হয় ( কেস গ্রহণযোগ্য উত্তর বিবেচনা না করে ) নির্মাণের শেষে প্রথমে নিশ্চিত করে নিন যে কোনও সিনট্যাক্স ত্রুটি নেই।

এটি কিছুটা অকার্যকর কারণ একই কোডটি বারবার প্রচুর পরিমাণে পড়তে পারে তবে এই বিষয়বস্তুটিকে সাধারণত ক্যাশে করা হয় এই বিষয়টি দ্বারা প্রশমিত।

শেল ইন্টারপ্রেটার যাই হোক না কেন, শেল স্ক্রিপ্টটি সম্পাদন করার সময় এটি সম্পাদন করা খুব বুদ্ধিমানের কাজ কারণ শেলটি স্ক্রিপ্টের যে কোনও অংশটি পুনরায় পড়তে মুক্ত এবং সিঙ্কের বাইরে থাকলে এটি অপ্রত্যাশিত বাক্য গঠনের ত্রুটি ঘটাতে পারে।

আরও মনে রাখবেন যে অতিরিক্ত মাত্রায় স্ক্রিপ্ট নির্মাণের জন্য ksh93 নির্দোষভাবে পড়তে পারে যখন ব্যাশটি বিভাগ বিধি লঙ্ঘনের সাথে ক্রাশ হতে পারে।


7

এটি স্ক্রিপ্টটি চালিয়ে দোভাষী কীভাবে কাজ করে তার উপর নির্ভর করে। সমস্ত কার্নেলটি হ'ল ফাইলটি সম্পাদন করার জন্য লক্ষ্য করা শুরু করা হয় #!, মূলত একটি প্রোগ্রাম হিসাবে বাকী রেখাটি চালায় এবং এটিকে যুক্তি হিসাবে নির্বাহযোগ্য করে দেয়। সেখানে তালিকাভুক্ত দোভাষী যদি সেই ফাইল লাইনটি লাইন দ্বারা পড়েন (যেমনটি ইন্টারেক্টিভ শেলগুলি আপনি টাইপ করেন তেমন করে) তবে এটি আপনি পাবেন (তবে বহু-লাইন লুপ স্ট্রাকচারগুলি পুনরাবৃত্তি করার জন্য পড়া হয় এবং চারপাশে রাখা হয়); দোভাষী যদি ফাইলটিকে মেমোরিতে স্লাপ করে, এটি প্রক্রিয়া করে (সম্ভবত এটি একটি মধ্যবর্তী উপস্থাপনা যেমন পার্ল এবং পাইটন ডু এর সাথে সংকলন করে) চালিত হওয়ার আগে ফাইলটি পুরোপুরি পড়ে is

আপনি যদি এর মধ্যে ফাইলটি মুছে ফেলেন, দোভাষী এটি বন্ধ না করা পর্যন্ত ফাইলটি মুছে ফেলা হয় না (সর্বদা হিসাবে, ফাইলগুলি শেষ রেফারেন্সটি হয়ে যায়, এটি ডিরেক্টরি এন্ট্রি হোক বা এটি খোলা রাখার প্রক্রিয়া হোক) অদৃশ্য হয়ে যায়।


4

'এক্স' ফাইল:

cat<<'dog' >xyzzy
LANG=C
T=`tty`
( sleep 2 ; ls -l xyzzy >$T ) &
( sleep 4 ; rm -v xyzzy >$T ) &
( sleep 4 ; ls -l xyzzy >$T ) &
echo alive. ; sleep 1
echo alive. ; sleep 1
echo alive. ; sleep 1
echo alive. ; sleep 1
echo alive. ; sleep 1
echo alive. ; sleep 1
echo alive. ; sleep 1
echo alive. ; sleep 1
dog

sh xyzzy

রান:

~/wrk/tmp$ sh x
alive.
alive.
alive.
-rw-r--r-- 1 yeti yeti 287 Mar 23 16:57 xyzzy
alive.
removed `xyzzy'
ls: cannot access xyzzy: No such file or directory
alive.
alive.
alive.
alive.
~/wrk/tmp$ _

আইআইআরসি কোনও ফাইল যতক্ষণ না এই প্রক্রিয়াটি খোলা রাখে ততক্ষণ মুছে ফেলা হয় না। মুছে ফেলা কেবল প্রদত্ত DIRENT সরিয়ে দেয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.