التابع spawn
الخاص بالصنف Kernel
في روبي
ينفذ التابع 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
.