الفرق بين المراجعتين لصفحة: «Ruby/Kernel/spawn»
لا ملخص تعديل |
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
||
(1 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة) | |||
سطر 3: | سطر 3: | ||
[[تصنيف: Ruby Method]] | [[تصنيف: Ruby Method]] | ||
[[تصنيف: Ruby Kernel]] | [[تصنيف: Ruby Kernel]] | ||
ينفذ التابع <code>spawn</code> تعليمة محددة، ثم يعيد معرفها (pid).<syntaxhighlight lang="ruby">pid | ينفذ التابع <code>spawn</code> تعليمة محددة، ثم يعيد معرفها (pid). | ||
==البنية العامة== | |||
<syntaxhighlight lang="ruby">spawn([env,] command... [,options]) → pid | |||
spawn([env,] command... [,options]) → pid</syntaxhighlight>يشبه التابعُ <code>spawn</code> التابعَ <code>[[Ruby/Kernel/system|system]]</code> باستثناء أنّه لا ينتظر إلى أن ينتهي تنفيذ الأمر. | |||
يجب على العملية الأب (parent process) أن تستخدم التابع <code>[[Ruby/Process/wait|Process.wait]]</code> لتحصيل حالة الإنهاء للعملية الفرعية، أو تستخدم <code>[[Ruby/Process/detach|Process.detach]]</code> لتسجيل عدم الاهتمام بحالتها؛ خلاف ذلك، قد يُراكم نظام التشغيل عمليات ميتة (zombie processes). | |||
Process.wait | |||
التابع <code>spawn</code> لديه مجموعة من الخيارات لتحديد خاصيات العملية: | |||
{| class="wikitable" | |||
التابع <code>spawn</code> لديه مجموعة من الخيارات لتحديد | ! colspan="2" |env: hash | ||
|- | |||
|<code>name => val</code> | |||
|يضبط متغيرات البيئة. | |||
|- | |||
|<code>name => nil</code> | |||
|يلغي ضبط متغيرات البيئة. | |||
|- | |||
| colspan="2" |ينبغي تكون المفاتيح والقيم سلاسل نصية باستثناء <code>nil</code>. | |||
|- | |||
! colspan="2" |...command | |||
|- | |||
|<code>commandline</code> | |||
|تعليمة نصية تُمرر إلى الصدفة القياسية. | |||
|- | |||
|<code>... ,cmdname, arg1</code> | |||
|تعليمة وواحد أو أكثر من الوسائط (هذا الشكل لا يستخدم الصدفة). | |||
|- | |||
|<code>[cmdname, argv0], arg1, ...</code> | |||
|تعليمة والوسيط <code>argv[0]</code> ووسيط واحد أو أكثر. | |||
|- | |||
! colspan="2" |ptions: hash | |||
|- | |||
| colspan="2" |مسح متغيرات البيئة (clearing environment variables) | |||
|- | |||
|<code>unsetenv_others => true:</code> | |||
|مسح متغيرات البيئة باستثناء المحددة من قبل <code>env</code>. | |||
|- | |||
|<code>unsetenv_others => false:</code> | |||
|عدم مسح المتغيرات - الخيار الافتراضي. | |||
|- | |||
| colspan="2" |process group: (مجموعة العمليات) | |||
|- | |||
|<code>pgroup => true or 0:</code> | |||
|إنشاء مجموعة عمليات جديدة. | |||
|- | |||
|<code>pgroup => pgid:</code> | |||
|الانضمام إلى مجموعة العمليات المحددة. | |||
|- | |||
|<code>pgroup => nil:</code> | |||
|عدم تغيير مجموعة العمليات (الافتراضي). | |||
|- | |||
| colspan="2" |إنشاء مجموعة عمليات جديدة: ويندوز فقط | |||
|- | |||
|<code>new_pgroup => true:</code> | |||
|العملية الجديدة هي العملية الأصل لمجموعة عمليات جديدة. | |||
|- | |||
|<code>new_pgroup => false:</code> | |||
|عدم إنشاء مجموعة عمليات جديدة (الافتراضي). | |||
إن كانت القيمة | |- | ||
pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)</syntaxhighlight>إن كانت القيمة المعطاة | | colspan="2" |اسم المورد (resourcename): هو نواة (core)، معالج (cpu)، بيانات، ...إلخ. انظر التابع <code>[[Ruby/Process/setrlimit|Process.setrlimit]]</code>. | ||
|- | |||
|<code>:rlimit_resourcename => limit</code> | |||
| | |||
|- | |||
|<code>:rlimit_resourcename => [cur_limit, max_limit]</code> | |||
| | |||
|- | |||
| colspan="2" |umask: | |||
|- | |||
|<code>umask => int:</code> | |||
| | |||
|- | |||
| colspan="2" |إعادة التوجيه (redirection): | |||
* المفتاح (key): | |||
|- | |||
|<code>FD</code> | |||
|واصف ملف واحد في العملية الفرعية. | |||
|- | |||
|<code>[FD, FD, ...]</code> | |||
|واصفات ملف متعددة في العملية الفرعية. | |||
|- | |||
| colspan="2" | | |||
* القيمة (value): | |||
|- | |||
|<code>FD</code> | |||
|يعيد التوجيه إلى واصف الملف في العملية الأب. | |||
|- | |||
|<code>string</code> | |||
|يعيد التوجيه إلى الملف مع <code>open(string, "r" or "w")</code>. | |||
|- | |||
|<code>[string]</code> | |||
|يعيد التوجيه إلى الملف مع <code>open(string, File::RDONLY)</code>. | |||
|- | |||
|<code>[string, open_mode]</code> | |||
|يعيد التوجيه إلى الملف مع <code>open(string, open_mode, 0644)</code>. | |||
|- | |||
|<code>[string, open_mode, perm]</code> | |||
|يعيد التوجيه إلى الملف مع <code>open(string, open_mode, perm)</code>. | |||
|- | |||
|<code>[child, FD:]</code> | |||
|يعيد التوجيه إلى واصف الملف المعاد توجيهه. | |||
|- | |||
|<code>close:</code> | |||
|يغلق واصف الملف في العملية الفرعية. | |||
|- | |||
| colspan="2" |واصف الملف FD هو أحد القيم التالية: | |||
|- | |||
|<code>in:</code> | |||
|واصف الملف رقم 0 والذي هو الدخل القياسي. | |||
|- | |||
|<code>out:</code> | |||
|واصف الملف رقم 1 والذي هو الخرج القياسي. | |||
|- | |||
|<code>err:</code> | |||
|واصف الملف رقم 2 والذي هو مجرى الخطأ القياسي. | |||
|- | |||
|<code>integer</code> | |||
|واصف الملف ذو العدد الصحيح المحدد. | |||
|- | |||
|<code>io</code> | |||
|واصف الملف <code>[[Ruby/IO/fileno|io.fileno]]</code>. | |||
|- | |||
| colspan="2" |وراثة واصف الملف: أغلق واصفات الملفات غير الموجَّهة وغير القياسية (مثل 3، و 4، و 5، ...إلخ.) أو لا. | |||
|- | |||
|<code>close_others => true:</code> | |||
|لا تستعمل الواصفات الموروثة. | |||
|- | |||
| colspan="2" |المجلد الحالي: | |||
|- | |||
|<code>chdir => str:</code> | |||
| | |||
|- | |||
| colspan="2" | لا يستخدم الشكل '<code>cmdname, arg1, ...</code>' الصدفة. لكن في بعض أنظمة التشغيل، يتم توفير أوامر مدمجة (built-in) مثل "<code>echo</code>"، المُدمج في ويندوز ، خلافًا للأنظمة لينكس وماك التي يعد فيها أمرًا طبيعيًّا. وهذا يعني أن <code>`Process.spawn 'echo', '%Path%'`</code> سيعرض محتويات متغير البيئة `<code>%Path%</code>` على ويندوز، لكن <code>`Process.spawn 'echo', '$PATH'`</code> سيطبع '<code>$PATH</code>' حرفيًّا. | |||
|} | |||
إن كانت القيمة المعطاة للمعامل <code>env</code> [[Ruby/Hash|جدولًا من النوع Hash]]، فسيتم تحديث البيئة بواسطة <code>env</code> قبل تنفيذ <code>exec(2)</code> في العملية الفرعية. إن كان لأحد مدخلات المعامل <code>env</code> القيمة <code>nil</code>، فسيُحذَف ذلك المتغير.<syntaxhighlight lang="ruby"># set FOO as BAR and unset BAZ. | |||
pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)</syntaxhighlight>إن كانت القيمة المعطاة للمعامل <code>options</code> [[Ruby/Hash|جدولًا من النوع Hash]]، فسيُحدِّد مجموعة العمليات (process group)، وينشئ مجموعة عمليات جديدة، ويحدد الموارد، والمجلد الحالي، ويقوم بتقنيع (umask) وإعادة توجيه العملية الفرعية. ويمكن أيضًا ضبطها لمحو متغيرات البيئة. | |||
المفتاح <code>:unsetenv_others</code> في <code>options</code> يؤدي إلى محو متغيرات البيئة فضلًا عن تلك المحددة بواسطة <code>env</code>.<syntaxhighlight lang="ruby">pid = spawn(command, :unsetenv_others=>true) # no environment variable | المفتاح <code>:unsetenv_others</code> في <code>options</code> يؤدي إلى محو متغيرات البيئة فضلًا عن تلك المحددة بواسطة <code>env</code>.<syntaxhighlight lang="ruby">pid = spawn(command, :unsetenv_others=>true) # no environment variable | ||
pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only | pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only | ||
</syntaxhighlight>يحدد المفتاح <code>:pgroup</code> في <code>options</code> مجموعة العملية. يجب أن تساوي القيمة المقابلة <code>true</code>، أو | </syntaxhighlight>يحدد المفتاح <code>:pgroup</code> في الخيارات <code>options</code> مجموعة العملية. يجب أن تساوي القيمة المقابلة <code>true</code>، أو صفرًا، أو عددًا صحيحًا موجبًا، أو القيمة <code>nil</code>. القيمتان <code>true</code> والصفر 0 تجعلان العملية عمليةً قائدةً (process leader) لمجموعة عمليات جديدة. عدد صحيح موجب غير معدوم سيجعل العملية تنضم إلى مجموعة العمليات المعطاة. أما القيمة الافتراضية <code>nil</code>، فستُبقي العملية في نفس مجموعة العمليات.<syntaxhighlight lang="ruby">pid = spawn(command, :pgroup=>true) # process leader | ||
pid = spawn(command, :pgroup=>10) # belongs to the process group 10 | pid = spawn(command, :pgroup=>10) # belongs to the process group 10 | ||
</syntaxhighlight>المفتاح <code>:new_pgroup</code> في <code>options</code> يؤدي إلى تمرير الراية <code>CREATE_NEW_PROCESS_GROUP</code> إلى <code>CreateProcessW()</code>، والتي هي واجهة برمجية | </syntaxhighlight>المفتاح <code>:new_pgroup</code> في الخيارات <code>options</code> يؤدي إلى تمرير الراية <code>CREATE_NEW_PROCESS_GROUP</code> إلى <code>CreateProcessW()</code>، والتي هي واجهة برمجية في أنظمة ويندوز (Windows API). هذا الخيار متاح فقط لنظام التشغيل ويندوز. القيمة <code>true</code> تعني أن العملية الجديدة ستكون العملية الأب لمجموعة العمليات الجديدة. يتم تعطيل <code>CTRL + C</code> في العملية الجديدة. هذه الراية ضرورية للتابع <code>[[Ruby/Process/kill|Process.kill(:SIGINT,pid)]]</code> في العملية الفرعية. | ||
قيمة <code>: | قيمة <code>new_pgroup:</code> تساوي <code>false</code> افتراضيًا.<syntaxhighlight lang="ruby">pid = spawn(command, :new_pgroup=>true) # new process group | ||
pid = spawn(command, :new_pgroup=>false) # same process group | pid = spawn(command, :new_pgroup=>false) # same process group | ||
</syntaxhighlight> | </syntaxhighlight>يحدِّد المفتاح <code>:rlimit_foo</code> [[Ruby/Process/setrlimit|حدود الموارد]]. ويجب أن تكون <code>foo</code> إحدى أنواع الموارد مثل <code>core</code>. كما يجب أن تكون القيمة المقابلة إما عددًا صحيحًا، أو مصفوفةً تحتوي على عدد أوعددين صحيحين مثل الوسيطين <code>cur_limit</code> و <code>max_limit</code> في <code>[[Ruby/Process/setrlimit|Process.setrlimit]]</code>.<syntaxhighlight lang="ruby">cur, max = Process.getrlimit(:CORE) | ||
pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary. | pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary. | ||
pid = spawn(command, :rlimit_core=>max) # enable core dump | pid = spawn(command, :rlimit_core=>max) # enable core dump | ||
pid = spawn(command, :rlimit_core=>0) # never dump core. | pid = spawn(command, :rlimit_core=>0) # never dump core. | ||
</syntaxhighlight>يحدد المفتاح <code>:umask</code> في <code>options</code> التقنيع (umask).<syntaxhighlight lang="ruby">pid = spawn(command, :umask=>077) | </syntaxhighlight>يحدد المفتاح <code>:umask</code> في الخيارات <code>options</code> التقنيع (umask).<syntaxhighlight lang="ruby">pid = spawn(command, :umask=>077) | ||
</syntaxhighlight> | </syntaxhighlight>يحدِّد المفتاح <code>:in</code> و <code>out:</code> و <code>err:</code> و <code>[[Ruby/Integer|integer]]</code> و <code>[[Ruby/IO|io]]</code> و<nowiki/>[[Ruby/Array|المصفوفة]] إعادة توجيه. | ||
تحدد إعادة التوجيه واصف ملف (file descriptor) في العملية | تحدد إعادة التوجيه واصف ملف (file descriptor) في العملية الابن. على سبيل المثال، يمكن دمج <code>stderr</code> في <code>stdout</code> كما يلي:<syntaxhighlight lang="ruby">pid = spawn(command, :err=>:out) | ||
pid = spawn(command, 2=>1) | pid = spawn(command, 2=>1) | ||
pid = spawn(command, STDERR=>:out) | pid = spawn(command, STDERR=>:out) | ||
pid = spawn(command, STDERR=>STDOUT) | pid = spawn(command, STDERR=>STDOUT) | ||
</syntaxhighlight>تحدد مفاتيح | </syntaxhighlight>تحدد مفاتيح [[Ruby/Hash|الجدول Hash]] واصف الملف في العملية الفرعية التي بدأها <code>spawn</code>. أما <code>err:</code>، و <code>2</code>، و <code>STDERR</code> فيعيّنان مجرى الخطأ القياسي (stderr). | ||
تعيّن قيم | تعيّن قيم [[Ruby/Hash|الجدول Hash]] واصف ملف في العملية الأب، والتي تستدعي <code>spawn</code>. أما <code>out:</code> و <code>1</code> و <code>STDOUT</code> فتحدد مجرى الخرج القياسي (stdout). | ||
في المثال أعلاه، لم يُحدّد مجرى | في المثال أعلاه، لم يُحدّد مجرى الخرج القياسي في العملية الفرعية. لذلك فهو يرثها من العملية الأب. | ||
يمكن تحديد مجرى | يمكن تحديد مجرى الدخل القياسي (stdin) بواسطة <code>in:</code> و <code>0</code> و <code>STDIN</code>. | ||
يمكن تحديد اسم ملف كقيمة في | يمكن تحديد اسم ملف كقيمة في [[Ruby/Hash|الجدول Hash]].<syntaxhighlight lang="ruby">pid = spawn(command, :in=>"/dev/null") # read mode | ||
pid = spawn(command, :out=>"/dev/null") # write mode | pid = spawn(command, :out=>"/dev/null") # write mode | ||
pid = spawn(command, :err=>"log") # write mode | pid = spawn(command, :err=>"log") # write mode | ||
pid = spawn(command, [:out, :err]=>"/dev/null") # write mode | pid = spawn(command, [:out, :err]=>"/dev/null") # write mode | ||
pid = spawn(command, 3=>"/dev/null") # read mode | pid = spawn(command, 3=>"/dev/null") # read mode | ||
</syntaxhighlight>بالنسبة إلى stdout و stderr (أو | </syntaxhighlight>بالنسبة إلى <code>stdout</code> و <code>stderr</code> (أو مزيج منهما) ، يتم فتحهما في وضع الكتابة. وإلا فسيُعتمد وضع القراءة. | ||
لتحديد رايات وأذونات إنشاء الملفات بشكل صريح، يمكن استخدام مصفوفة.<syntaxhighlight lang="ruby">pid = spawn(command, :in=>" | لتحديد رايات وأذونات إنشاء الملفات بشكل صريح، يمكن استخدام مصفوفة.<syntaxhighlight lang="ruby">pid = spawn(command, :in=>["file"]) # read mode is assumed | ||
pid = spawn(command, : | pid = spawn(command, :in=>["file", "r"]) | ||
pid = spawn(command, : | pid = spawn(command, :out=>["log", "w"]) # 0644 assumed | ||
pid = spawn(command, | pid = spawn(command, :out=>["log", "w", 0600]) | ||
pid = spawn(command, | pid = spawn(command, :out=>["log", File::WRONLY|File::EXCL|File::CREAT, 0600]) | ||
</syntaxhighlight>تحدد المصفوفة اسم الملف والرايات والأذونات. الرايات قد تكون سلاسل نصية أو أعدادًا | |||
</syntaxhighlight>تحدد المصفوفة اسم الملف والرايات والأذونات. الرايات قد تكون سلاسل نصية أو أعدادًا صحيحةً. إذا حُذفَت الرايات أو كانت قيمتها <code>nil</code>، فستُستعمَل القيمة <code>File::RDONLY</code> الافتراضية. يجب أن يكون الإذن عددًا صحيحًا. إذا تم حذف الإذن أو كان يساوي <code>nil</code>، فسيتم اعتماد القيمة <code>0644</code> الافتراضية. | |||
إذا تم تحديد مصفوفة من كائنات | إذا تم تحديد مصفوفة من كائنات <code>[[Ruby/IO|IO]]</code> ومن الأعداد الصحيحة كمفتاح [[Ruby/Hash|للجدول Hash]]، فسيتم إعادة توجيه جميع العناصر.<syntaxhighlight lang="ruby"># stdout and stderr is redirected to log file. | ||
# The file "log" is opened just once. | # The file "log" is opened just once. | ||
pid = spawn(command, [:out, :err]=>["log", "w"]) | pid = spawn(command, [:out, :err]=>["log", "w"]) | ||
</syntaxhighlight>هناك طريقة أخرى لدمج عدة واصفات ملفات وهي <code>[:child، fd]</code>. والتي تعني واصف الملف في العملية الفرعية. وهو مختلف عن fd. على سبيل المثال، | </syntaxhighlight>هناك طريقة أخرى لدمج عدة واصفات ملفات وهي <code>[:child، fd]</code>. والتي تعني واصف الملف في العملية الفرعية. وهو مختلف عن <code>fd</code>. على سبيل المثال، تعني <code>err =>:out</code> إعادة توجيه المجرى <code>stderr</code> للعملية الفرعية إلى المجرى <code>stdout</code> للعملية الأب. ولكن <code>:err => [:child،:out]</code> تعني إعادة توجيه المجرى <code>stderr</code> للعملية الفرعية إلى المجرى <code>stdout</code> للعملية الفرعية نفسها، إذ سيكونان مختلفين إذا أُعيد توجيه المجرى <code>stdout</code> في العملية الفرعية على النحو التالي.<syntaxhighlight lang="ruby"># stdout and stderr is redirected to log file. | ||
# The file "log" is opened just once. | # The file "log" is opened just once. | ||
pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out]) | pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out]) | ||
</syntaxhighlight>يمكن استخدام <code><nowiki>[:child، :out]</nowiki></code> لدمج المجرى stderr في المجرى stdout في <code>IO.popen</code>. في هذه الحالة، يعيد <code>IO.popen</code> توجيه المجرى stdout إلى أنبوب (pipe) في العملية الفرعية، | </syntaxhighlight>يمكن استخدام <code><nowiki>[:child، :out]</nowiki></code> لدمج المجرى <code>stderr</code> في المجرى <code>stdout</code> في <code>[[Ruby/IO/popen|IO.popen]]</code>. في هذه الحالة، يعيد [[Ruby/IO/popen|<code>IO.popen</code>]] توجيه المجرى <code>stdout</code> إلى أنبوب (pipe) في العملية الفرعية، إذ تشير <code><nowiki>[:child ، :out]</nowiki></code> إلى المجرى <code>stdout</code> المعاد توجيهه.<syntaxhighlight lang="ruby">io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]]) | ||
p io.read #=> "out\nerr\n" | p io.read #=> "out\nerr\n" | ||
</syntaxhighlight>يحدد المفتاح <code>:chdir</code> في <code>options</code> المجلد الحالي.<syntaxhighlight lang="ruby">pid = spawn(command, :chdir=>"/var/tmp") | </syntaxhighlight>يحدد المفتاح <code>:chdir</code> في <code>options</code> المجلد الحالي.<syntaxhighlight lang="ruby">pid = spawn(command, :chdir=>"/var/tmp") | ||
</syntaxhighlight>تغلق <code>spawn</code> | </syntaxhighlight>تغلق <code>spawn</code> افتراضيًّا جميع الواصفات غير المحددة وغير القياسية. الواصفات "القياسية" هي <code>0</code> و <code>1</code> و <code>2</code>. يتم تحديد هذا السلوك بواسطة الخيار: <code>:close_others</code>. الخيار <code>:close_others</code> لا يؤثر على الواصفات القياسية التي يتم إغلاقها إلا في حالة تم تحديد <code>:close</code> بشكل صريح.<syntaxhighlight lang="ruby">pid = spawn(command, :close_others=>true) # close 3,4,5,... (default) | ||
pid = spawn(command, :close_others=>false) # don't close 3,4,5,... | pid = spawn(command, :close_others=>false) # don't close 3,4,5,... | ||
</syntaxhighlight>قيمة <code>:close_others</code> تساوي <code>true</code> بشكل افتراضي، بالنسبة للتابع <code>spawn</code> و <code>IO.popen</code>. | </syntaxhighlight>قيمة <code>:close_others</code> تساوي <code>true</code> بشكل افتراضي، بالنسبة للتابع <code>spawn</code> و [[Ruby/IO/popen|<code>IO.popen</code>]]. | ||
لاحظ أن | لاحظ أن واصفات الملفات التي تم تعيين الراية <code>close-on-exec</code> لها ستُغلق بغض النظر عن الخيار <code>close_others</code>. لذلك يمكن استخدام التابع <code>[[Ruby/IO/pipe|IO.pipe]]</code> والتابع <code>spawn</code> مثل التابع [[Ruby/IO/popen|<code>IO.popen</code>]].<syntaxhighlight lang="ruby"># similar to r = IO.popen(command) | ||
r, w = IO.pipe | r, w = IO.pipe | ||
pid = spawn(command, :out=>w) # r, w is closed in the child process. | pid = spawn(command, :out=>w) # r, w is closed in the child process. | ||
w.close | w.close | ||
</syntaxhighlight>يتم تحديد <code>: | </syntaxhighlight>يتم تحديد <code>close:</code> كقيمة في [[Ruby/Hash|الجدول Hash]] لإغلاق واصف ملف بشكل فردي.<syntaxhighlight lang="ruby">f = open(foo) | ||
system(command, f=>:close) # don't inherit f. | system(command, f=>:close) # don't inherit f. | ||
</syntaxhighlight>إذا كانت هناك حاجة إلى توريث واصف الملف، فيمكن استخدام <code>io => io</code>.<syntaxhighlight lang="ruby"># valgrind has --log-fd option for log destination. | </syntaxhighlight>إذا كانت هناك حاجة إلى توريث واصف الملف، فيمكن استخدام <code>io => io</code>.<syntaxhighlight lang="ruby"># valgrind has --log-fd option for log destination. | ||
سطر 133: | سطر 211: | ||
</syntaxhighlight>من الممكن أيضًا تبادل واصفات الملفات.<syntaxhighlight lang="ruby">pid = spawn(command, :out=>:err, :err=>:out) | </syntaxhighlight>من الممكن أيضًا تبادل واصفات الملفات.<syntaxhighlight lang="ruby">pid = spawn(command, :out=>:err, :err=>:out) | ||
</syntaxhighlight>تحدد مفاتيح | </syntaxhighlight>تحدد مفاتيح [[Ruby/Hash|الجدول Hash]] واصفات الملفات في العملية الفرعية بينما تحدد قيم [[Ruby/Hash|الجدول Hash]] واصفات الملفات في العملية الأب. بناءً على ذلك، يحدد المثال أعلاه تبادل المَجرّيين <code>stdout</code> و <code>stderr</code>. داخليًا، يستخدم <code>spawn</code> واصف ملف إضافي لحل هذا التعيين الدوري لواصفات الملفات. | ||
راجع صفحة <code>[[Ruby/Kernel/exec|exec]]</code> لأجل لمزيد من المعلومات | راجع صفحة التابع <code>[[Ruby/Kernel/exec|exec]]</code> لأجل لمزيد من المعلومات حول الصدفة (shell) القياسية. | ||
==المعاملات== | ==المعاملات== | ||
===<code>env</code>=== | ===<code>env</code>=== | ||
سطر 145: | سطر 220: | ||
التعليمة المراد تنفيذها. | التعليمة المراد تنفيذها. | ||
===<code>options</code>=== | ===<code>options</code>=== | ||
خيارات. | خيارات إضافية للتحكم بالعملية. | ||
==القيمة | ==القيمة المعادة== | ||
يعاد معرف العملية المنفذة (pid). | |||
==أمثلة== | ==أمثلة== | ||
مثال على استخدام التابع <code>spawn</code>:<syntaxhighlight lang="ruby">pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2") | مثال على استخدام التابع <code>spawn</code>:<syntaxhighlight lang="ruby">pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2") | ||
سطر 154: | سطر 229: | ||
Process.wait pid</syntaxhighlight> | Process.wait pid</syntaxhighlight> | ||
==انظر أيضا== | ==انظر أيضا== | ||
*التابع <code>[[Ruby/Kernel/exec|exec]]</code>: يستبدل | *التابع <code>[[Ruby/Kernel/exec|exec]]</code>: يستبدل العملية (process) الحالية عبر تشغيل الأمر الخارجي المعطى. | ||
*التابع <code>[[Ruby/Kernel/system|system]]</code>: ينفذ | *التابع <code>[[Ruby/Kernel/system|system]]</code>: ينفذ التعليمة المعطاة في صدفة فرعية (subshell). | ||
==مصادر== | ==مصادر== | ||
*[http://ruby-doc.org/core-2.5.1/Kernel.html#method-i-spawn قسم | *[http://ruby-doc.org/core-2.5.1/Kernel.html#method-i-spawn قسم التابع spawn في الصنف Kernel في توثيق روبي الرسمي.] |
المراجعة الحالية بتاريخ 06:41، 6 يناير 2019
ينفذ التابع spawn
تعليمة محددة، ثم يعيد معرفها (pid).
البنية العامة
spawn([env,] command... [,options]) → pid
spawn([env,] command... [,options]) → pid
يشبه التابعُ spawn
التابعَ system
باستثناء أنّه لا ينتظر إلى أن ينتهي تنفيذ الأمر.
يجب على العملية الأب (parent process) أن تستخدم التابع Process.wait
لتحصيل حالة الإنهاء للعملية الفرعية، أو تستخدم Process.detach
لتسجيل عدم الاهتمام بحالتها؛ خلاف ذلك، قد يُراكم نظام التشغيل عمليات ميتة (zombie processes).
التابع spawn
لديه مجموعة من الخيارات لتحديد خاصيات العملية:
env: hash | |
---|---|
name => val
|
يضبط متغيرات البيئة. |
name => nil
|
يلغي ضبط متغيرات البيئة. |
ينبغي تكون المفاتيح والقيم سلاسل نصية باستثناء nil .
| |
...command | |
commandline
|
تعليمة نصية تُمرر إلى الصدفة القياسية. |
... ,cmdname, arg1
|
تعليمة وواحد أو أكثر من الوسائط (هذا الشكل لا يستخدم الصدفة). |
[cmdname, argv0], arg1, ...
|
تعليمة والوسيط argv[0] ووسيط واحد أو أكثر.
|
ptions: hash | |
مسح متغيرات البيئة (clearing environment variables) | |
unsetenv_others => true:
|
مسح متغيرات البيئة باستثناء المحددة من قبل env .
|
unsetenv_others => false:
|
عدم مسح المتغيرات - الخيار الافتراضي. |
process group: (مجموعة العمليات) | |
pgroup => true or 0:
|
إنشاء مجموعة عمليات جديدة. |
pgroup => pgid:
|
الانضمام إلى مجموعة العمليات المحددة. |
pgroup => nil:
|
عدم تغيير مجموعة العمليات (الافتراضي). |
إنشاء مجموعة عمليات جديدة: ويندوز فقط | |
new_pgroup => true:
|
العملية الجديدة هي العملية الأصل لمجموعة عمليات جديدة. |
new_pgroup => false:
|
عدم إنشاء مجموعة عمليات جديدة (الافتراضي). |
اسم المورد (resourcename): هو نواة (core)، معالج (cpu)، بيانات، ...إلخ. انظر التابع Process.setrlimit .
| |
:rlimit_resourcename => limit
|
|
:rlimit_resourcename => [cur_limit, max_limit]
|
|
umask: | |
umask => int:
|
|
إعادة التوجيه (redirection):
| |
FD
|
واصف ملف واحد في العملية الفرعية. |
[FD, FD, ...]
|
واصفات ملف متعددة في العملية الفرعية. |
| |
FD
|
يعيد التوجيه إلى واصف الملف في العملية الأب. |
string
|
يعيد التوجيه إلى الملف مع open(string, "r" or "w") .
|
[string]
|
يعيد التوجيه إلى الملف مع open(string, File::RDONLY) .
|
[string, open_mode]
|
يعيد التوجيه إلى الملف مع open(string, open_mode, 0644) .
|
[string, open_mode, perm]
|
يعيد التوجيه إلى الملف مع open(string, open_mode, perm) .
|
[child, FD:]
|
يعيد التوجيه إلى واصف الملف المعاد توجيهه. |
close:
|
يغلق واصف الملف في العملية الفرعية. |
واصف الملف FD هو أحد القيم التالية: | |
in:
|
واصف الملف رقم 0 والذي هو الدخل القياسي. |
out:
|
واصف الملف رقم 1 والذي هو الخرج القياسي. |
err:
|
واصف الملف رقم 2 والذي هو مجرى الخطأ القياسي. |
integer
|
واصف الملف ذو العدد الصحيح المحدد. |
io
|
واصف الملف io.fileno .
|
وراثة واصف الملف: أغلق واصفات الملفات غير الموجَّهة وغير القياسية (مثل 3، و 4، و 5، ...إلخ.) أو لا. | |
close_others => true:
|
لا تستعمل الواصفات الموروثة. |
المجلد الحالي: | |
chdir => str:
|
|
لا يستخدم الشكل 'cmdname, arg1, ... ' الصدفة. لكن في بعض أنظمة التشغيل، يتم توفير أوامر مدمجة (built-in) مثل "echo "، المُدمج في ويندوز ، خلافًا للأنظمة لينكس وماك التي يعد فيها أمرًا طبيعيًّا. وهذا يعني أن `Process.spawn 'echo', '%Path%'` سيعرض محتويات متغير البيئة `%Path% ` على ويندوز، لكن `Process.spawn 'echo', '$PATH'` سيطبع '$PATH ' حرفيًّا.
|
إن كانت القيمة المعطاة للمعامل env
جدولًا من النوع Hash، فسيتم تحديث البيئة بواسطة env
قبل تنفيذ exec(2)
في العملية الفرعية. إن كان لأحد مدخلات المعامل env
القيمة nil
، فسيُحذَف ذلك المتغير.
# set FOO as BAR and unset BAZ.
pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)
إن كانت القيمة المعطاة للمعامل options
جدولًا من النوع Hash، فسيُحدِّد مجموعة العمليات (process group)، وينشئ مجموعة عمليات جديدة، ويحدد الموارد، والمجلد الحالي، ويقوم بتقنيع (umask) وإعادة توجيه العملية الفرعية. ويمكن أيضًا ضبطها لمحو متغيرات البيئة.
المفتاح :unsetenv_others
في options
يؤدي إلى محو متغيرات البيئة فضلًا عن تلك المحددة بواسطة env
.
pid = spawn(command, :unsetenv_others=>true) # no environment variable
pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only
يحدد المفتاح :pgroup
في الخيارات options
مجموعة العملية. يجب أن تساوي القيمة المقابلة true
، أو صفرًا، أو عددًا صحيحًا موجبًا، أو القيمة nil
. القيمتان true
والصفر 0 تجعلان العملية عمليةً قائدةً (process leader) لمجموعة عمليات جديدة. عدد صحيح موجب غير معدوم سيجعل العملية تنضم إلى مجموعة العمليات المعطاة. أما القيمة الافتراضية nil
، فستُبقي العملية في نفس مجموعة العمليات.
pid = spawn(command, :pgroup=>true) # process leader
pid = spawn(command, :pgroup=>10) # belongs to the process group 10
المفتاح :new_pgroup
في الخيارات options
يؤدي إلى تمرير الراية CREATE_NEW_PROCESS_GROUP
إلى CreateProcessW()
، والتي هي واجهة برمجية في أنظمة ويندوز (Windows API). هذا الخيار متاح فقط لنظام التشغيل ويندوز. القيمة true
تعني أن العملية الجديدة ستكون العملية الأب لمجموعة العمليات الجديدة. يتم تعطيل CTRL + C
في العملية الجديدة. هذه الراية ضرورية للتابع Process.kill(:SIGINT,pid)
في العملية الفرعية.
قيمة new_pgroup:
تساوي false
افتراضيًا.
pid = spawn(command, :new_pgroup=>true) # new process group
pid = spawn(command, :new_pgroup=>false) # same process group
يحدِّد المفتاح :rlimit_foo
حدود الموارد. ويجب أن تكون foo
إحدى أنواع الموارد مثل core
. كما يجب أن تكون القيمة المقابلة إما عددًا صحيحًا، أو مصفوفةً تحتوي على عدد أوعددين صحيحين مثل الوسيطين cur_limit
و max_limit
في Process.setrlimit
.
cur, max = Process.getrlimit(:CORE)
pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary.
pid = spawn(command, :rlimit_core=>max) # enable core dump
pid = spawn(command, :rlimit_core=>0) # never dump core.
يحدد المفتاح :umask
في الخيارات options
التقنيع (umask).
pid = spawn(command, :umask=>077)
يحدِّد المفتاح :in
و out:
و err:
و integer
و io
والمصفوفة إعادة توجيه.
تحدد إعادة التوجيه واصف ملف (file descriptor) في العملية الابن. على سبيل المثال، يمكن دمج stderr
في stdout
كما يلي:
pid = spawn(command, :err=>:out)
pid = spawn(command, 2=>1)
pid = spawn(command, STDERR=>:out)
pid = spawn(command, STDERR=>STDOUT)
تحدد مفاتيح الجدول Hash واصف الملف في العملية الفرعية التي بدأها spawn
. أما err:
، و 2
، و STDERR
فيعيّنان مجرى الخطأ القياسي (stderr).
تعيّن قيم الجدول Hash واصف ملف في العملية الأب، والتي تستدعي spawn
. أما out:
و 1
و STDOUT
فتحدد مجرى الخرج القياسي (stdout).
في المثال أعلاه، لم يُحدّد مجرى الخرج القياسي في العملية الفرعية. لذلك فهو يرثها من العملية الأب.
يمكن تحديد مجرى الدخل القياسي (stdin) بواسطة in:
و 0
و STDIN
.
يمكن تحديد اسم ملف كقيمة في الجدول Hash.
pid = spawn(command, :in=>"/dev/null") # read mode
pid = spawn(command, :out=>"/dev/null") # write mode
pid = spawn(command, :err=>"log") # write mode
pid = spawn(command, [:out, :err]=>"/dev/null") # write mode
pid = spawn(command, 3=>"/dev/null") # read mode
بالنسبة إلى stdout
و stderr
(أو مزيج منهما) ، يتم فتحهما في وضع الكتابة. وإلا فسيُعتمد وضع القراءة.
لتحديد رايات وأذونات إنشاء الملفات بشكل صريح، يمكن استخدام مصفوفة.
pid = spawn(command, :in=>["file"]) # read mode is assumed
pid = spawn(command, :in=>["file", "r"])
pid = spawn(command, :out=>["log", "w"]) # 0644 assumed
pid = spawn(command, :out=>["log", "w", 0600])
pid = spawn(command, :out=>["log", File::WRONLY|File::EXCL|File::CREAT, 0600])
تحدد المصفوفة اسم الملف والرايات والأذونات. الرايات قد تكون سلاسل نصية أو أعدادًا صحيحةً. إذا حُذفَت الرايات أو كانت قيمتها nil
، فستُستعمَل القيمة File::RDONLY
الافتراضية. يجب أن يكون الإذن عددًا صحيحًا. إذا تم حذف الإذن أو كان يساوي nil
، فسيتم اعتماد القيمة 0644
الافتراضية.
إذا تم تحديد مصفوفة من كائنات IO
ومن الأعداد الصحيحة كمفتاح للجدول Hash، فسيتم إعادة توجيه جميع العناصر.
# stdout and stderr is redirected to log file.
# The file "log" is opened just once.
pid = spawn(command, [:out, :err]=>["log", "w"])
هناك طريقة أخرى لدمج عدة واصفات ملفات وهي [:child، fd]
. والتي تعني واصف الملف في العملية الفرعية. وهو مختلف عن fd
. على سبيل المثال، تعني err =>:out
إعادة توجيه المجرى stderr
للعملية الفرعية إلى المجرى stdout
للعملية الأب. ولكن :err => [:child،:out]
تعني إعادة توجيه المجرى stderr
للعملية الفرعية إلى المجرى stdout
للعملية الفرعية نفسها، إذ سيكونان مختلفين إذا أُعيد توجيه المجرى stdout
في العملية الفرعية على النحو التالي.
# stdout and stderr is redirected to log file.
# The file "log" is opened just once.
pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out])
يمكن استخدام [:child، :out]
لدمج المجرى stderr
في المجرى stdout
في IO.popen
. في هذه الحالة، يعيد IO.popen
توجيه المجرى stdout
إلى أنبوب (pipe) في العملية الفرعية، إذ تشير [:child ، :out]
إلى المجرى stdout
المعاد توجيهه.
io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]])
p io.read #=> "out\nerr\n"
يحدد المفتاح :chdir
في options
المجلد الحالي.
pid = spawn(command, :chdir=>"/var/tmp")
تغلق spawn
افتراضيًّا جميع الواصفات غير المحددة وغير القياسية. الواصفات "القياسية" هي 0
و 1
و 2
. يتم تحديد هذا السلوك بواسطة الخيار: :close_others
. الخيار :close_others
لا يؤثر على الواصفات القياسية التي يتم إغلاقها إلا في حالة تم تحديد :close
بشكل صريح.
pid = spawn(command, :close_others=>true) # close 3,4,5,... (default)
pid = spawn(command, :close_others=>false) # don't close 3,4,5,...
قيمة :close_others
تساوي true
بشكل افتراضي، بالنسبة للتابع spawn
و IO.popen
.
لاحظ أن واصفات الملفات التي تم تعيين الراية close-on-exec
لها ستُغلق بغض النظر عن الخيار close_others
. لذلك يمكن استخدام التابع IO.pipe
والتابع spawn
مثل التابع IO.popen
.
# similar to r = IO.popen(command)
r, w = IO.pipe
pid = spawn(command, :out=>w) # r, w is closed in the child process.
w.close
يتم تحديد close:
كقيمة في الجدول Hash لإغلاق واصف ملف بشكل فردي.
f = open(foo)
system(command, f=>:close) # don't inherit f.
إذا كانت هناك حاجة إلى توريث واصف الملف، فيمكن استخدام io => io
.
# valgrind has --log-fd option for log destination.
# log_w=>log_w indicates log_w.fileno inherits to child process.
log_r, log_w = IO.pipe
pid = spawn("valgrind", "--log-fd=#{log_w.fileno}", "echo", "a", log_w=>log_w)
log_w.close
p log_r.read
من الممكن أيضًا تبادل واصفات الملفات.
pid = spawn(command, :out=>:err, :err=>:out)
تحدد مفاتيح الجدول Hash واصفات الملفات في العملية الفرعية بينما تحدد قيم الجدول Hash واصفات الملفات في العملية الأب. بناءً على ذلك، يحدد المثال أعلاه تبادل المَجرّيين stdout
و stderr
. داخليًا، يستخدم spawn
واصف ملف إضافي لحل هذا التعيين الدوري لواصفات الملفات.
راجع صفحة التابع exec
لأجل لمزيد من المعلومات حول الصدفة (shell) القياسية.
المعاملات
env
بيئة التنفيذ.
command...
التعليمة المراد تنفيذها.
options
خيارات إضافية للتحكم بالعملية.
القيمة المعادة
يعاد معرف العملية المنفذة (pid).
أمثلة
مثال على استخدام التابع spawn
:
pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
Process.wait pid
pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
Process.wait pid
انظر أيضا
- التابع
exec
: يستبدل العملية (process) الحالية عبر تشغيل الأمر الخارجي المعطى. - التابع
system
: ينفذ التعليمة المعطاة في صدفة فرعية (subshell).