الفرق بين المراجعتين ل"Ruby/Kernel/spawn"

من موسوعة حسوب
< Ruby‏ | Kernel
اذهب إلى التنقل اذهب إلى البحث
سطر 60: سطر 60:
 
‎</syntaxhighlight> لا يستخدم الشكل '<code>cmdname</code>، <code>arg1...‎</code>' الصدفة. لكن مع ذلك، على عدة أنظمة تشغيل، يتم توفير أمور كأوامر مدمجة (built-in). مثل "<code>echo</code>" ، المُدمجة في Windows ، على خلاف Linux و Mac OS X. وهذا يعني أن  <code>`Process.spawn 'echo', '%Path%'`</code>ستعرض محتويات متغير البيئة `<code>%Path%</code>` على Windows ، لكن<code>`Process.spawn 'echo', '$PATH'`</code> سيطبع الحرف'‎<code>$PATH‎</code>'.
 
‎</syntaxhighlight> لا يستخدم الشكل '<code>cmdname</code>، <code>arg1...‎</code>' الصدفة. لكن مع ذلك، على عدة أنظمة تشغيل، يتم توفير أمور كأوامر مدمجة (built-in). مثل "<code>echo</code>" ، المُدمجة في Windows ، على خلاف Linux و Mac OS X. وهذا يعني أن  <code>`Process.spawn 'echo', '%Path%'`</code>ستعرض محتويات متغير البيئة `<code>%Path%</code>` على Windows ، لكن<code>`Process.spawn 'echo', '$PATH'`</code> سيطبع الحرف'‎<code>$PATH‎</code>'.
  
 +
إن كانت القيمة أالمعطاة للوسيط <code>env</code> قاموسًا (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> قاموسًا (hash)، فسيحدد مجموعة العمليات (process group)، وينشئ مجموعة عمليات جديدة، ويحدد الموارد، والمجلد الحالي، ويقوم بتقنيع (umask) وإعادة توجيه العملية الفرعية. يمكن أيضًا ضبطها لمحو متغيرات البيئة.
  
إن كانت القيمة أالمعطاة للوسيط <code>env</code> قاموسًا (hashفسيتم تحديث البيئة بواسطة <code>env</code> قبل <code>exec(2)‎</code> في العملية الفرعية. إن كان لأحد مدخلات <code>env</code> القيمة <code>nil</code>، فسيُحذف ذلك المتغير.
+
المفتاح ‎<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
 +
</syntaxhighlight>يحدد المفتاح ‎<code>:pgroup</code> في <code>options</code> مجموعة العملية. يجب أن تساوي القيمة المقابلة <code>true</code>، أو صفر، أو عددًا صحيحًا موجبًا، أو <code>nil</code>. القيمتان <code>true</code> وصفر تجعلان العملية عمليةً قائدة (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
 +
</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>Process.kill(:SIGINT,pid)‎</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
 +
</syntaxhighlight>يحدد المفتاح ‎<code>:rlimit_foo</code> حدود الموارد. ويجب أن تكون <code>foo</code> إحدى أنواع الموارد مثل <code>core</code>. ويجب أن تكون القيمة المقابلة إما عددًا صحيحًا، أو مصفوفة تحتوي على عدد أوعددين صحيحين: مثل الوسيطين <code>cur_limit</code> و <code>max_limit</code> في <code>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=>max) # enable core dump
 +
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)
  
إن كانت القيمة المعطاة للوسيط <code>options</code> قاموسًا (hash)، فسيحدد مجموعة العمليات (process group)، وينشئ مجموعة عمليات جديدة، ويحدد الموارد، والمجلد الحالي، ويقوم بتقنيع (umask) وإعادة توجيه العملية الفرعية. يمكن أيضًا ضبطها لمحو متغيرات البيئة.
+
</syntaxhighlight>المفاتيح ‎ <code>:in</code>, و <code>:out</code> و <code>:err</code> و عدد  integer، وكائن <code>IO</code> و مصفوفة تحدد إعادة توجيه. إعادة التوجيه تحدد واصف ملف (file descriptor) في العملية التابعة.
  
المفتاح ‎<code>:unsetenv_others</code> في <code>options</code> يؤدي إلى محو متغيرات البيئة فضلًا عن تلك المحددة بواسطة <code>env</code>.
+
على سبيل المثال، يمكن دمج <code>stderr</code> في <code>stdout</code> كما يلي:<syntaxhighlight lang="ruby">pid = spawn(command, :err=>:out)
 
+
pid = spawn(command, 2=>1)
يحدد المفتاح ‎<code>:pgroup</code> في <code>options</code> مجموعة العملية. يجب أن تساوي القيمة المقابلة <code>true</code>، أو صفر، أو عددًا صحيحًا موجبًا، أو <code>nil</code>. القيمتان <code>true</code> وصفر تجعلان العملية عمليةً قائدة (process leader) لمجموعة عمليات جديدة. عدد صحيح موجب غير معدوم سيجعل العملية تنضم إلى مجموعة العمليات المعطاة. أما القيمة الافتراضية <code>nil</code>، فتُبقي العملية في نفس مجموعة العمليات.
+
pid = spawn(command, STDERR=>:out)
 
+
pid = spawn(command, STDERR=>STDOUT)
المفتاح ‎<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>Process.kill(:SIGINT,pid)‎</code> في العملية الفرعية. قيمة <code>:new_pgroup</code> تساوي <code>false</code> افتراضيًا.
+
</syntaxhighlight>تحدد مفاتيح القاموس واصف الملف في العملية الفرعية التي بدأها <code>spawn</code>. أما <code>err، 2</code> و <code>STDERR</code> فيعيّنان مجرى الخطأ القياسي (stderr).
 
 
يحدد المفتاح ‎<code>:rlimit_foo</code> حدود الموارد. ويجب أن تكون <code>foo</code> إحدى أنواع الموارد مثل <code>core</code>. ويجب أن تكون القيمة المقابلة إما عددًا صحيحًا، أو مصفوفة تحتوي على عدد أوعددين صحيحين: مثل الوسيطين <code>cur_limit</code> و <code>max_limit</code> في <code>Process.setrlimit</code>.
 
 
 
يحدد المفتاح ‎<code>:umask</code> في <code>options</code> التقنيع (umask).
 
 
 
المفاتيح ‎ <code>:in</code>, و <code>:out</code> و <code>:err</code> و عدد  integer، وكائن <code>IO</code> و مصفوفة تحدد إعادة توجيه. إعادة التوجيه تحدد واصف ملف (file descriptor) في العملية التابعة.
 
 
 
على سبيل المثال، يمكن دمج <code>stderr</code> في <code>stdout</code> كما يلي:
 
 
 
تحدد مفاتيح القاموس واصف الملف في العملية الفرعية التي بدأها <code>spawn</code>. أما <code>err، 2</code> و <code>STDERR</code> فيعيّنان مجرى الخطأ القياسي (stderr).
 
  
 
تعيّن قيم القاموس واصف ملف في العملية الأم، والتي تستدعي <code>spawn.</code> أما  <code>:out</code>و <code>1</code> و  <code>STDOUT</code> فتحدد مجرى الإخراج القياسي (stdout).
 
تعيّن قيم القاموس واصف ملف في العملية الأم، والتي تستدعي <code>spawn.</code> أما  <code>:out</code>و <code>1</code> و  <code>STDOUT</code> فتحدد مجرى الإخراج القياسي (stdout).
سطر 87: سطر 89:
 
يمكن تحديد مجرى الإدخال القياسي (stdin) بواسطة: :<code>in</code>و  <code>0</code> و <code>STDIN</code>.
 
يمكن تحديد مجرى الإدخال القياسي (stdin) بواسطة: :<code>in</code>و  <code>0</code> و <code>STDIN</code>.
  
يمكن تحديد اسم ملف كقيمة في قاموس.
+
يمكن تحديد اسم ملف كقيمة في قاموس.<syntaxhighlight lang="ruby">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
 +
</syntaxhighlight>بالنسبة إلى stdout و stderr (أو توليفة منهما) ، يتم فتحهما في وضع الكتابة. وإلا فسيُعتمد وضع القراءة.
  
بالنسبة إلى stdout و stderr (أو توليفة منهما) ، يتم فتحهما في وضع الكتابة. وإلا فسيُعتمد وضع القراءة.
+
لتحديد رايات وأذونات إنشاء الملفات بشكل صريح، يتم استخدام مصفوفة بدلاً من ذلك.<syntaxhighlight lang="ruby">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
 +
</syntaxhighlight>تحدد المصفوفة اسم الملف والرايات والأذونات. الرايات قد تكون سلاسل نصية أو أعدادًا صحيحة. إذا حُذفت الرايات أو أعطيت القيمة <code>nil</code>، فستُفترض <code>File :: RDONLY</code>. يجب أن يكون الإذن عددًا صحيحًا. إذا تم حذف الإذن أو كان يساوي <code>nil</code>، يتم افتراض القيمة <code>0644</code>.
  
لتحديد رايات وأذونات إنشاء الملفات بشكل صريح، يتم استخدام مصفوفة بدلاً من ذلك.
+
إذا تم تحديد مصفوفة من كائنات IOs ومن الأعداد الصحيحة كمفتاح للقاموس، سيتم إعادة توجيه جميع العناصر.<syntaxhighlight lang="ruby"># stdout and stderr is redirected to log file.
 +
# The file "log" is opened just once.
 +
pid = spawn(command, [:out, :err]=>["log", "w"])
 +
</syntaxhighlight>هناك طريقة أخرى لدمج عدة واصفات ملفات وهي <code>[‎:child، fd]</code>. والتي تعني واصف الملف في العملية الفرعية. وهو مختلف عن fd. على سبيل المثال،: <code>err =>:out</code> تعني إعادة توجيه المجرى stderr الفرعي إلى المجرى stdout الأم. ولكن‎<code>:err => [:child،:out]‎</code> تعني إعادة توجيه المجرى stderr الفرعي إلى المجرى stdout الفرعي. إذ سيكونان مختلفين إذا أُعيد توجيه المجرى stdout في العملية الفرعية على النحو التالي.<syntaxhighlight lang="ruby"># stdout and stderr is redirected to log file.
 +
# The file "log" is opened just once.
 +
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) في العملية الفرعية، حيث تشير <code><nowiki>[‎:child ، :out]</nowiki></code> إلى المجرى stdout المعاد توجيهه.<syntaxhighlight lang="ruby">io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]])
 +
p io.read #=> "out\nerr\n"
 +
</syntaxhighlight>يحدد المفتاح ‎<code>:chdir</code> في <code>options</code> المجلد الحالي.<syntaxhighlight lang="ruby">pid = spawn(command, :chdir=>"/var/tmp")
  
تحدد المصفوفة اسم الملف والرايات والأذونات. الرايات قد تكون سلاسل نصية أو أعدادًا صحيحة. إذا حُذفت الرايات أو أعطيت القيمة <code>nil</code>، فستُفترض <code>File :: RDONLY</code>. يجب أن يكون الإذن عددًا صحيحًا. إذا تم حذف الإذن أو كان يساوي <code>nil</code>، يتم افتراض القيمة <code>0644</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,...
 +
</syntaxhighlight>قيمة <code>‎:close_others</code> تساوي <code>true</code> بشكل افتراضي، بالنسبة للتابع <code>spawn</code> و <code>IO.popen</code>.
  
إذا تم تحديد مصفوفة من كائنات IOs ومن الأعداد الصحيحة كمفتاح للقاموس، سيتم إعادة توجيه جميع العناصر.
+
لاحظ أن العناصر fds التي تم تعيين الراية <code>close-on-exec</code> خاصتها، ستُغلق بغض النظر عن الخيار <code>close_others</code>. لذلك يمكن استخدام <code>IO.pipe</code> و <code>spawn</code> كـ <code>IO.popen</code>.<syntaxhighlight lang="ruby"># 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
 +
</syntaxhighlight>يتم تحديد <code>:close</code> كقيمة قاموس لإغلاق عنصر fd بشكل فردي.<syntaxhighlight lang="ruby">f = open(foo)
 +
system(command, f=>:close)        # don't inherit f.
 +
</syntaxhighlight>إذا كانت هناك حاجة إلى توريث واصف الملف، فيمكن استخدام <code>io => io</code>.<syntaxhighlight lang="ruby"># 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
 +
</syntaxhighlight>من الممكن أيضًا تبادل واصفات الملفات.<syntaxhighlight lang="ruby">pid = spawn(command, :out=>:err, :err=>:out)
  
هناك طريقة أخرى لدمج عدة واصفات ملفات وهي <code>[‎:child، fd]</code>. والتي تعني واصف الملف في العملية الفرعية. وهو مختلف عن fd. على سبيل المثال،: <code>err =>:out</code> تعني إعادة توجيه المجرى stderr الفرعي إلى المجرى stdout الأم. ولكن‎<code>:err => [:child،:out]‎</code> تعني إعادة توجيه المجرى stderr الفرعي إلى المجرى stdout الفرعي. إذ سيكونان مختلفين إذا أُعيد توجيه المجرى stdout في العملية الفرعية على النحو التالي.
+
</syntaxhighlight>تحدد مفاتيح القاموس واصفات الملفات في العملية الفرعية. فيما تحدد قيم القاموس واصفات الملفات في العملية الأم. بهذا يحدد المثال أعلاه تبادل المَجرّيين stdout و stderr. داخليًا، يستخدم <code>spawn</code> واصف ملف إضافي لحل هذا التعيين الدوري لواصفات الملفات.
 
 
يمكن استخدام <code><nowiki>[‎:child، :out]</nowiki></code> لدمج المجرى stderr في المجرى stdout في <code>IO.popen</code>. في هذه الحالة، يعيد <code>IO.popen</code> توجيه المجرى stdout إلى أنبوب (pipe) في العملية الفرعية، حيث تشير <code><nowiki>[‎:child ، :out]</nowiki></code> إلى المجرى stdout المعاد توجيهه.
 
 
 
يحدد المفتاح ‎<code>:chdir</code> في <code>options</code> المجلد الحالي.
 
 
 
تغلق <code>spawn</code> افتراضيا جميع الواصفات غير المحددة وغير القياسية. الواصفات "القياسية" هي <code>0</code> و <code>1</code> و <code>2</code>. يتم تحديد هذا السلوك بواسطة الخيار: <code>‎:close_others</code>. الخيار ‎<code>:close_others</code> لا يؤثر على الواصفات القياسية التي يتم إغلاقها إلا في حالة تم تحديد <code>:close</code> بشكل صريح.
 
 
 
قيمة <code>‎:close_others</code> تساوي <code>true</code> بشكل افتراضي، بالنسبة للتابع <code>spawn</code> و <code>IO.popen</code>.
 
 
 
لاحظ أن العناصر fds التي تم تعيين الراية <code>close-on-exec</code> خاصتها، ستُغلق بغض النظر عن الخيار <code>close_others</code>. لذلك يمكن استخدام <code>IO.pipe</code> و <code>spawn</code> كـ <code>IO.popen</code>.
 
 
 
يتم تحديد <code>:close</code> كقيمة قاموس لإغلاق عنصر fd بشكل فردي.
 
 
 
إذا كانت هناك حاجة إلى توريث واصف الملف، فيمكن استخدام <code>io => io</code>.
 
 
 
من الممكن أيضًا تبادل واصفات الملفات.
 
 
 
تحدد مفاتيح القاموس واصفات الملفات في العملية الفرعية. فيما تحدد قيم القاموس واصفات الملفات في العملية الأم. بهذا يحدد المثال أعلاه تبادل المَجرّيين stdout و stderr. داخليًا، يستخدم <code>spawn</code> واصف ملف إضافي لحل هذا التعيين الدوري لواصفات الملفات.
 
  
 
راجع صفحة <code>[[Ruby/Kernel/exec|exec]]</code> لأجل لمزيد من المعلومات بخصوص الصدفة (shell) القياسية.
 
راجع صفحة <code>[[Ruby/Kernel/exec|exec]]</code> لأجل لمزيد من المعلومات بخصوص الصدفة (shell) القياسية.
سطر 124: سطر 140:
 
===<code>env‎</code>===
 
===<code>env‎</code>===
 
بيئة التنفيذ.
 
بيئة التنفيذ.
 
 
===<code>command...‎</code>===
 
===<code>command...‎</code>===
 
التعليمة المراد تنفيذها.
 
التعليمة المراد تنفيذها.
 
 
===<code>options‎</code>===
 
===<code>options‎</code>===
 
 
خيارات.
 
خيارات.
 
==القيمة المُعادة==
 
==القيمة المُعادة==
 
يعيد معرف العملية المنفذة (pid).
 
يعيد معرف العملية المنفذة (pid).
 
 
==أمثلة==
 
==أمثلة==
مثال على استخدام التابع <code>spawn‎</code>:
+
مثال على استخدام التابع <code>spawn‎</code>:<syntaxhighlight lang="ruby">pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
<syntaxhighlight lang="ruby">pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
 
 
Process.wait pid
 
Process.wait pid
 
pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
 
pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
 
Process.wait pid‎</syntaxhighlight>
 
Process.wait pid‎</syntaxhighlight>
 
==انظر أيضا==
 
==انظر أيضا==
* التابع <code>[[Ruby/Kernel/exec|exec]]</code>: يستبدل التابع <code>exec</code> العملية (process) الحالية عبر تشغيل الأمر الخارجي المعطى <code>command</code>.
+
*التابع <code>[[Ruby/Kernel/exec|exec]]</code>: يستبدل التابع <code>exec</code> العملية (process) الحالية عبر تشغيل الأمر الخارجي المعطى <code>command</code>.
 
 
 
==مصادر==
 
==مصادر==
 
*[http://ruby-doc.org/core-2.5.1/Kernel.html#method-i-spawn قسم  التابع spawn‎ في الصنف Kernel‎ في توثيق روبي الرسمي.]
 
*[http://ruby-doc.org/core-2.5.1/Kernel.html#method-i-spawn قسم  التابع spawn‎ في الصنف Kernel‎ في توثيق روبي الرسمي.]

مراجعة 18:01، 22 أكتوبر 2018

ينفذ التابع spawn تعليمة محددة، ثم يعيد معرفها (pid).

pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
Process.wait pid

pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
Process.wait 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]  تعليمة و
o ptions: hash
  clearing environment variables: (محو متغيرات البيئة)
    :unsetenv_others => true   :  env محو متغيرات البيئة باستثناء المحددة من قبل
    :unsetenv_others => false  : لا تمحو المتغيرات - افتراضي
  process group: (مجموعة العمليات)
    :pgroup => true or 0 : انشاء مجموعة عمليات جديدة
    :pgroup => pgid      : الانضمام إلى مجموعة العمليات المحددة
    :pgroup => nil       : عدم تغيير مجموعة العمليات - افتراصي)
  create new process group: Windows only  انشاء مجموعة عمليات جديدة، في الويندوز فقط
    :new_pgroup => true  : العملية الجديدة هي العملية الأصل لمجموعة عمليات جديدة
    :new_pgroup => false : لا تنشئ مجموعة عمليات جديدة - افتراضي
  resource limit: resourcename is core, cpu, data, etc.  See Process.setrlimit.
    :rlimit_resourcename => limit
    :rlimit_resourcename => [cur_limit, max_limit]
  umask:
    :umask => int
  redirection:
    key:
      FD              : واصف ملف واحد في العملية الفرعية
      [FD, FD, ...]   : واصف ملف متعدد في العمليةالفرعية
    value:
      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 is one of follows
      :in     : واصف الملف رقم 0 والذي هو المدخل القياسي
      :out    : واصف الملف رقم 1 والذي هو المخرج القياسي
      :err    : واصف الملف رقم 2 والذي هو مجرى الخطأ القياسي
      integer : واصف الملف ذو الرقم المحدد
      io      :  io.fileno واصف الملف
  file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
    :close_others => true  : don't inherit
  current directory:
    :chdir => str

 لا يستخدم الشكل 'cmdname، arg1...‎' الصدفة. لكن مع ذلك، على عدة أنظمة تشغيل، يتم توفير أمور كأوامر مدمجة (built-in). مثل "echo" ، المُدمجة في Windows ، على خلاف Linux و Mac OS X. وهذا يعني أن `Process.spawn 'echo', '%Path%'`ستعرض محتويات متغير البيئة `%Path%` على Windows ، لكن`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 وصفر تجعلان العملية عمليةً قائدة (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)

تحدد مفاتيح القاموس واصف الملف في العملية الفرعية التي بدأها spawn. أما err، 2 و STDERR فيعيّنان مجرى الخطأ القياسي (stderr).

تعيّن قيم القاموس واصف ملف في العملية الأم، والتي تستدعي spawn. أما :outو 1 و STDOUT فتحدد مجرى الإخراج القياسي (stdout).

في المثال أعلاه، لم يُحدّد مجرى الإخراج القياسي في العملية الفرعية. لذلك فهو يرثها من العملية الأم.

يمكن تحديد مجرى الإدخال القياسي (stdin) بواسطة: :inو 0 و STDIN.

يمكن تحديد اسم ملف كقيمة في قاموس.

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=>"/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

تحدد المصفوفة اسم الملف والرايات والأذونات. الرايات قد تكون سلاسل نصية أو أعدادًا صحيحة. إذا حُذفت الرايات أو أعطيت القيمة nil، فستُفترض File :: RDONLY. يجب أن يكون الإذن عددًا صحيحًا. إذا تم حذف الإذن أو كان يساوي nil، يتم افتراض القيمة 0644. إذا تم تحديد مصفوفة من كائنات IOs ومن الأعداد الصحيحة كمفتاح للقاموس، سيتم إعادة توجيه جميع العناصر.

# 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. لاحظ أن العناصر fds التي تم تعيين الراية 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 كقيمة قاموس لإغلاق عنصر fd بشكل فردي.

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)

تحدد مفاتيح القاموس واصفات الملفات في العملية الفرعية. فيما تحدد قيم القاموس واصفات الملفات في العملية الأم. بهذا يحدد المثال أعلاه تبادل المَجرّيين stdout و stderr. داخليًا، يستخدم spawn واصف ملف إضافي لحل هذا التعيين الدوري لواصفات الملفات.

راجع صفحة exec لأجل لمزيد من المعلومات بخصوص الصدفة (shell) القياسية.

البنية العامة

spawn([env,] command... [,options])   pid
spawn([env,] command... [,options])   pid

المعاملات

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: يستبدل التابع exec العملية (process) الحالية عبر تشغيل الأمر الخارجي المعطى command.

مصادر