CINXE.COM
class Proc | Raku Documentation
<!DOCTYPE html> <html lang="en" class="fontawesome-i2svg-active fontawesome-i2svg-complete" style="scroll-padding-top:60px"> <head> <title>class Proc | Raku Documentation</title> <meta charset="UTF-8" /> <link href="/assets/images/Camelia.ico" rel="icon" type="image/x-icon"/> <link rel="stylesheet" href="/assets/css/Website.css"/> <link rel="stylesheet" href="/assets/css/typegraph-styling.css"/> <link rel="stylesheet" href="/assets/css/typegraph-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/typegraph-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/filtered-toc-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/filtered-toc-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/announce-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/announce-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/all.min.css"/> <link rel="stylesheet" href="/assets/css/listf-styling-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/listf-styling-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/options-search-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/options-search-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/page-styling-main.css"/> <link rel="stylesheet" href="/assets/css/css/page-styling-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/page-styling-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/chyronToggle-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/chyronToggle-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/centreToggle-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/centreToggle-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/tm-styling.css"/> <link rel="stylesheet" href="/assets/css/tm-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/tm-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/rainbow-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/rainbow-light.css" title="light"/> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tarekraafat/autocomplete.js@10.2.7/dist/css/autoComplete.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-light.min.css" title="light" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css" title="dark" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="/assets/scripts/all.min.js"></script><script src="/assets/scripts/filter-script.js"></script><script src="/assets/scripts/tableManager.js"></script><script src="https://cdn.jsdelivr.net/npm/fuzzysort@2.0.4/fuzzysort.min.js"></script><script src="https://cdn.jsdelivr.net/npm/@tarekraafat/autocomplete.js@10.2.7/dist/autoComplete.min.js"></script><script src="/assets/scripts/filtered-toc.js"></script><script src="/assets/scripts/options-search.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/haskell.min.js"></script><script src="/assets/scripts/page-styling.js"></script><script src="/assets/scripts/announcements.js"></script><script src="/assets/scripts/rainbow.js"></script> </head> <body class="has-navbar-fixed-top"> <div id="class_Proc" class="top-of-page"></div> <nav class="navbar is-fixed-top is-flex-touch" role="navigation" aria-label="main navigation"> <div class="navbar-item" style="margin-left: auto;"> <div class="left-bar-toggle" title="Toggle Table of Contents & Index"> <label class="chyronToggle left"> <input id="navbar-left-toggle" type="checkbox"> <span class="text">Contents</span> </label> </div> </div> <div class="container is-justify-content-space-around"> <div class="navbar-brand"> <div class="navbar-logo"> <a class="navbar-item" href="/"> <img src="/assets/images/camelia-recoloured.png" alt="Raku" width="52.83" height="38"> </a> <span class="navbar-logo-tm">tm</span> </div> <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navMenu"> <span aria-hidden="true"></span> <span aria-hidden="true"></span> <span aria-hidden="true"></span> </a> </div> <div id="navMenu" class="navbar-menu"> <div class="navbar-start"> <a class="navbar-item" href="/introduction" title="Getting started, Tutorials, Migration guides"> Introduction </a> <a class="navbar-item" href="/reference" title="Fundamentals, General reference"> Reference </a> <a class="navbar-item" href="/miscellaneous" title="Programs, Experimental"> Miscellaneous </a> <a class="navbar-item" href="/types" title="The core types (classes) available"> Types </a> <a class="navbar-item" href="/routines" title="Searchable table of routines"> Routines </a> <a class="navbar-item" href="https://raku.org" title="Home page for community"> Raku<sup>®</sup> </a> <a class="navbar-item" href="https://web.libera.chat/#raku" title="IRC live chat"> Chat </a> <div class="navbar-item has-dropdown is-hoverable"> <a class="navbar-link"> More </a> <div class="navbar-dropdown is-right is-rounded"> <hr class="navbar-divider"> <a class="navbar-item js-modal-trigger" data-target="download-ebook"> Download E-Book (epub) </a> <hr class="navbar-divider"> <a class="navbar-item" href="/about"> About </a> <hr class="navbar-divider"> <a class="navbar-item has-text-red" href="https://github.com/raku/doc-website/issues"> Report an issue with this site </a> <hr class="navbar-divider"> <a class="navbar-item" href="https://github.com/raku/doc/issues"> Report an issue with the documentation content </a> <hr class="navbar-divider"> <label class="navbar-item centreToggle" title="Enable/Disable Announcements" style="--switch-width: 18"> <input id="cancelAnnouncements" type="checkbox"> <span class="text">Announcements</span> <span class="on">suppressed</span> <span class="off">allowed</span> </label> </div> </div> </div> <div class="navbar-end navbar-search-wrapper"> <div class="navbar-item"> <div class="field has-addons"> <div class="autoComplete_options"> <input class="control input" id="autoComplete" type="search" dir="ltr" spellcheck=false autocorrect="off" autocomplete="off" autocapitalize="off" placeholder="🔍 Type f to search for ..."> </div> <div class="control" title="Search options"> <a class="button is-primary js-modal-trigger" data-target="options-search-info"> <span class="icon"> <i class="fas fa-cogs"></i> </span> </a> </div> </div> </div> </div> <div id="options-search-info" class="modal"> <div class="modal-background"></div> <div class="modal-content"> <div class="box"> <p>The last search was: <span id="selected-candidate" class="ss-selected"></span></p> <div class="control is-grouped is-grouped-centered options-search-controls"> <label class="centreToggle" title="Include extra information (Alt-E)" style="--switch-width: 10.5"> <input id="options-search-extra" type="checkbox"> <span class="text">Extra info</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>The search response can be shortened by excluding the extra information line (Alt-E)</p> <label class="centreToggle" title="Search engine type Strict/Loose (Alt-L)" style="--switch-width: 10.5"> <input id="options-search-loose" type="checkbox"> <span class="text">Search type</span> <span class="on">loose</span> <span class="off">strict</span> </label> <p> The search engine can perform a strict search (only the characters in the search box) or a loose search (Alt-L)</p> <label class="centreToggle" title="Search in headings (Alt-H)" style="--switch-width: 10.5"> <input id="options-search-headings" type="checkbox"> <span class="text">Headings</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Search through headings in all web-pages (Alt-H)</p> <label class="centreToggle" title="Search indexed items (Alt-I)" style="--switch-width: 10.5"> <input id="options-search-indexed" type="checkbox"> <span class="text">Indexed</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Search through all indexed items (Alt-I)</p> <label class="centreToggle" title="Search composite pages (Alt-C)" style="--switch-width: 10.5"> <input id="options-search-composite" type="checkbox"> <span class="text">Composite</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Search in the names of composite pages, which combine similar information from the main web pages (Alt-C)</p> <label class="centreToggle" title="Search primary sources (Alt-P)" style="--switch-width: 10.5"> <input id="options-search-primary" type="checkbox"> <span class="text">Primary</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Search through the names of the main web pages (Alt-P)</p> <label class="centreToggle" title="Open in new tab (Alt-Q)" style="--switch-width: 10.5"> <input id="options-search-newtab" type="checkbox"> <span class="text">New tab</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Once a search candidate has been chosen, it can be opened in a new tab or in the current tab (Alt-Q)</p> <p>If all else fails, an item is added to use the Google search engine on the whole site</p> <button class="button is-warning" id="options-search-reset-defaults">Clear options, reset to defaults</button> <p>Exit this page by pressing <Escape>, or clicking on X or on the background.</p> </div> </div> </div> <button class="modal-close is-large" aria-label="close"></button> </div> </div> <div id="download-ebook" class="modal"> <div class="modal-background"></div> <div class="modal-content"> <div class="box"> <p><a href="/RakuDocumentation.epub" download>RakuDocumentation.epub</a> is a work in progress e-book. It targets the <a href="https://www.w3.org/publishing/epub3/">EPUB v3 specification</a>. It needs testing on a variety of ereaders (some of which may still implicitly expect compliance with EPUB v2). The CSS definitely needs enhancing (especially for code snippets). The Ebook opens in a Calibre reader, which is available on all operating systems.</p> <p>Suggestions are welcome and should be addressed by opening an issue on the Raku/doc-website repository</p> <p>Exit this popup by pressing <Escape>, or clicking on X or on the background.</p> </div> </div> <button class="modal-close is-large" aria-label="close"></button> </div> <div id="announcement-modal" class="modal"> <div class="modal-background"></div> <div class="modal-content"> <div class="box"> <div id="raku-doc-announcement"></div> <p>For more see <a href="/announcements">Announcements page</a>.</p> <p>Exit this popup by pressing <Escape>, or clicking on X or on the background.</p> </div> </div> <button class="modal-close is-large" aria-label="close"></button> </div> </div> </nav> <div class="tile is-ancestor section"> <div class="page-edit"> <a class="button page-edit-button" href="https://github.com/Raku/doc/edit/main/doc/Type/Proc.rakudoc" title="Edit this page. Commit: eb7c31dad 2024-07-22"> <span class="icon is-right"> <i class="fas fa-pen-alt is-medium"></i> </span> </a> </div> <div id="left-column" class="tile is-parent is-2 is-hidden"> <div id="left-col-inner"> <div class="tabs" id="tabs"> <ul> <li class="is-active" id="toc-tab"> <a>Table of Contents</a> </li> <li id="index-tab"> <a>Index</a> </li> </ul> </div> <div class="field"> <div class="control has-icons-right"> <input id="toc-filter" class="input" type="text" placeholder="Filter"> <span class="icon is-right has-text-grey"> <i class="fas fa-search is-medium"></i> </span> </div> </div> <div class="raku-sidebar"> <aside id="toc-menu" class="menu"> <ul class="menu-list"> <li><a href="#Potential_Deadlocks">Potential Deadlocks</a></li> <li><a href="#Methods">Methods</a></li> <ul> <li><a href="#routine_new">routine new</a></li> <li><a href="#method_sink">method sink</a></li> <li><a href="#method_spawn">method spawn</a></li> <li><a href="#method_shell">method shell</a></li> <li><a href="#method_command">method command</a></li> <li><a href="#method_Bool">method Bool</a></li> <li><a href="#method_pid">method pid</a></li> <li><a href="#method_exitcode">method exitcode</a></li> <li><a href="#method_signal">method signal</a></li> </ul> </aside> <aside id="index-menu" class="menu is-hidden"> <ul class="menu-list"> <li>Subroutines<ul> <li><a href="#index-entry-run-run">run</a></li> </ul></li> </ul> </aside> </div> </div> </div> <div id="main-column" class="tile is-parent" style="overflow-x: hidden;"> <div id="main-col-inner"> <section class="raku page-header"> <div class="container px-4"> <div class="raku page-title has-text-centered"> class Proc </div> <div class="raku page-subtitle has-text-centered"> <p>Running process (filehandle-based interface)</p> </div> </div> </section> <section class="raku page-content"><div class="container px-4"><div class="columns one-col"> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">class</span> <span class="highlite-TYPE">Proc</span> {}</pre> </div> </div> <p><code>Proc</code> is a representation of an invocation of an external process. It provides access to the input, output and error stream as well as the exit code. It is typically created through the <a name="index-entry-run-run" class="index-entry"><span class="glossary-entry" data-index-text="⦃〚Subroutines〛 〚run〛⦄"><code>run</code></span></a> subroutine:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$proc</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">run</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">echo</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">Hallo world</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> :out; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$captured-output</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$proc</span>.out.slurp: :close; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Output was </span><span class="highlite-NAME_SCALAR">$captured-output</span><span class="highlite-STRING">.raku()</span><span class="highlite-STRING_DELIMITER">"</span>;<span class="highlite-COMMENT"># OUTPUT: «Output was "Hallo world\n"» </span></pre> </div> </div> <p>Piping several commands is easy too. To achieve the equivalent of the pipe <code>echo "Hello, world" | cat -n</code> in Raku, and capture the output from the second command, you can do</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$p1</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">run</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">echo</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">Hello, world</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> :out; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$p2</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">run</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">cat</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">-n</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> :in(<span class="highlite-NAME_SCALAR">$p1</span>.out)<span class="highlite-OPERATOR">,</span> :out; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$p2</span>.out.<span class="highlite-ROUTINE">get</span>; </pre> </div> </div> <p>You can also feed the <code>:in</code> (standard input) pipe directly from your program, by setting it to <code>True</code>, which will make the pipe available via <code>.in</code> method on the <code>Proc</code>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$p</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">run</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">cat</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">-n</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> :in<span class="highlite-OPERATOR">,</span> :out; <span class="highlite-NAME_SCALAR">$p</span>.<span class="highlite-ROUTINE">in</span>.say: <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Hello,</span><span class="highlite-ESCAPE">\n</span><span class="highlite-STRING">world!</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-NAME_SCALAR">$p</span>.<span class="highlite-ROUTINE">in</span>.<span class="highlite-ROUTINE">close</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$p</span>.out.slurp: :close; <span class="highlite-COMMENT"># OUTPUT: «1 Hello, </span><span class="highlite-COMMENT"># 2 world!» </span></pre> </div> </div> <p>In order to capture the standard error, <code>:err</code> can be supplied:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$p</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">run</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">ls</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">-l</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">.</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">qqrq</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> :out<span class="highlite-OPERATOR">,</span> :err; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$captured-output</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$p</span>.out.slurp: :close; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$captured-error</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$p</span>.err.slurp: :close; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$exit-code</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$p</span>.<span class="highlite-ROUTINE">exitcode</span>; </pre> </div> </div> <p>In sink context, a <code>Proc</code> will call its <code>sink</code> method, throwing an exception if the process has exited with an exit code different from zero:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">shell</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">exit 1</span><span class="highlite-STRING_DELIMITER">'</span> <span class="highlite-COMMENT"># OUTPUT: «(exit code 1) The spawned command 'exit 1' exited unsuccessfully (exit code: 1)» </span></pre> </div> </div> <p><strong>Note:</strong> Versions of <a href="/language/glossary#Rakudo">Rakudo</a> older than 2017.04 do not have <code>.slurp</code> available on <a href="/type/IO/Pipe"><code>IO::Pipe</code></a> objects; use <a href="/routine/slurp-rest"><code>.slurp-rest</code></a> instead.</p><p>Use <a href="/type/Proc/Async"><code>Proc::Async</code></a> for non-blocking operations.</p> <h1 id="Potential_Deadlocks" class="raku-h1"><a href="#class_Proc" title="go to top of document">Potential Deadlocks<a class="raku-anchor" title="direct link" href="#Potential_Deadlocks">§</a></a></h1> <p>If you run an external program with <code>:out</code> and <code>:err</code> (so capturing standard output and standard error separately), a deadlock can occur, for example in the following scenario:</p> <ul class="rakudoc-item"> <li><p>Your Raku script reads from the program's standard output until the End of File (EOF) marker).</p></li> <li><p>The external program writes to its standard error stream.</p></li> <li><p>The external program runs into the standard error's buffer limit.</p></li> <li><p>Your Raku script blocks, waiting for input on the output stream, while the external program blocks until its standard error buffer is being drained.</p></li> </ul> <p>You can avoid this by using <code>:merge</code> to join the external program's standard output and error streams, so that you only need to read from one pipe. This presupposes that you do not need separate access to the two streams. If you do, the only safe approach is to use <a href="/type/Proc/Async"><code>Proc::Async</code></a>.</p><p>A similar deadlock can occur when you call an external program with both the <code>:in</code> option (to open a pipe to its standard input) and one of the <code>:out</code>, <code>:err</code> or <code>:merge</code> options. In this scenario, it can happen that your Raku script blocks reading from the external program's output while it waits for input, and vice versa.</p><p>In this scenario, switching to <a href="/type/Proc/Async"><code>Proc::Async</code></a> is the most robust solution.</p> <h1 id="Methods" class="raku-h1"><a href="#class_Proc" title="go to top of document">Methods<a class="raku-anchor" title="direct link" href="#Methods">§</a></a></h1> <h2 id="routine_new" class="raku-h2"><a href="#class_Proc" title="go to top of document">routine new<a class="raku-anchor" title="direct link" href="#routine_new">§</a></a></h2> <!-- defnmark routine_new 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">new</span>(Proc:U: <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$in</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">-</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$out</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">-</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$err</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">-</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">Bool</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$bin</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">False</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">Bool</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$chomp</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">True</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">Bool</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$merge</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">False</span><span class="highlite-OPERATOR">,</span> Str:D <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$enc</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">UTF-8</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> Str:D <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$nl</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-ESCAPE">\n</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> <span class="highlite-KEYWORD">--></span> Proc:D) <span class="highlite-KEYWORD">sub</span> <span class="highlite-ROUTINE">shell</span>( <span class="highlite-NAME_SCALAR">$cmd</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$in</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">-</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$out</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">-</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$err</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">-</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">Bool</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$bin</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">False</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">Bool</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$chomp</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">True</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">Bool</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$merge</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">False</span><span class="highlite-OPERATOR">,</span> Str:D <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$enc</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">UTF-8</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> Str:D <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$nl</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-ESCAPE">\n</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$cwd</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$*CWD</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">Hash</span>() <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$env</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_HASH">%*ENV</span> <span class="highlite-KEYWORD">--></span> Proc:D) </pre> </div> </div> <p><code>new</code> creates a new <code>Proc</code> object, whereas <code>run</code> or <code>shell</code> create one and spawn it with the command and arguments provided in <code>@args</code> or <code>$cmd</code>, respectively.</p><p><code>$in</code>, <code>$out</code> and <code>$err</code> are the three standard streams of the to-be-launched program, and default to <code>"-"</code> meaning they inherit the stream from the parent process. Setting one (or more) of them to <code>True</code> makes the stream available as an <a href="/type/IO/Pipe"><code>IO::Pipe</code></a> object of the same name, like for example <code>$proc.out</code>. You can set them to <code>False</code> to discard them. Or you can pass an existing <a href="/type/IO/Handle"><code>IO::Handle</code></a> object (for example <a href="/type/IO/Pipe"><code>IO::Pipe</code></a>) in, in which case this handle is used for the stream.</p><p>Please bear in mind that the process streams reside in process variables, not in the dynamic variables that make them available to our programs. Thus, modifying <a href="/language/variables#Special_filehandles:_STDIN,_STDOUT_and_STDERR">the dynamic filehandle variables (such as <code>$*OUT</code>)</a> inside the host process will have no effect in the spawned process, unlike <code>$*CWD</code> and <code>$*ENV</code>, whose changes will be actually reflected in it.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$p-name</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">/tmp/program.raku</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$program</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">Q:to/END/</span>; <span class="highlite-STRING"> #!/usr/bin/env raku $*OUT.say( qq/\t$*PROGRAM: This goes to standard output/ );</span><span class="highlite-STRING_DELIMITER"> END</span> <span class="highlite-ROUTINE">spurt</span> <span class="highlite-NAME_SCALAR">$p-name</span><span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$program</span>; <span class="highlite-NAME_SCALAR">$*OUT</span>.put: <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">1. standard output before doing anything weird</span><span class="highlite-STRING_DELIMITER">"</span>; { <span class="highlite-KEYWORD">temp</span> <span class="highlite-NAME_SCALAR">$*OUT</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">open</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">/tmp/out.txt</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> :w; <span class="highlite-NAME_SCALAR">$*OUT</span>.put: <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">2. temp redefine standard output before this message</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">shell</span>( <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">raku </span><span class="highlite-NAME_SCALAR">$p-name</span><span class="highlite-STRING_DELIMITER">"</span> ).<span class="highlite-OPERATOR">so</span>; } <span class="highlite-NAME_SCALAR">$*OUT</span>.put: <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">3. everything should be back to normal</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-COMMENT"># OUTPUT </span><span class="highlite-COMMENT"># 1. standard output before doing anything weird </span><span class="highlite-COMMENT"># /tmp/program.raku: This goes to standard output </span><span class="highlite-COMMENT"># 3. everything should be back to normal </span> <span class="highlite-COMMENT"># /tmp/out.txt will contain: </span><span class="highlite-COMMENT"># 2. temp redefine standard output before this message </span></pre> </div> </div> <p>This program shows that the program spawned with <code>shell</code> is not using the temporary <code>$*OUT</code> value defined in the host process (redirected to <code>/tmp/out.txt</code>), but the initial <code>STDOUT</code> defined in the process.</p><p><code>$bin</code> controls whether the streams are handled as binary (i.e. <a href="/type/Blob"><code>Blob</code></a> object) or text (i.e. <a href="/type/Str"><code>Str</code></a> objects). If <code>$bin</code> is False, <code>$enc</code> holds the character encoding to encode strings sent to the input stream and decode binary data from the output and error streams.</p><p>With <code>$chomp</code> set to <code>True</code>, newlines are stripped from the output and err streams when reading with <code>lines</code> or <code>get</code>. <code>$nl</code> controls what your idea of a newline is.</p><p>If <code>$merge</code> is set to True, the standard output and error stream end up merged in <code>$proc.out</code>.</p> <h2 id="method_sink" class="raku-h2"><a href="#class_Proc" title="go to top of document">method sink<a class="raku-anchor" title="direct link" href="#method_sink">§</a></a></h2> <!-- defnmark method_sink 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">sink</span>(<span class="highlite-KEYWORD">--></span> <span class="highlite-TYPE">Nil</span>)</pre> </div> </div> <p>When sunk, the <code>Proc</code> object will throw <a href="/type/X/Proc/Unsuccessful"><code>X::Proc::Unsuccessful</code></a> if the process it ran exited unsuccessfully.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">shell</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">ls /qqq</span><span class="highlite-STRING_DELIMITER">'</span>; <span class="highlite-COMMENT"># OUTPUT: </span><span class="highlite-COMMENT"># (exit code 1) ls: cannot access '/qqq': No such file or directory </span><span class="highlite-COMMENT"># The spawned command 'ls /qqq' exited unsuccessfully (exit code: 2) </span><span class="highlite-COMMENT"># in block <unit> at /tmp/3169qXElwq line 1 </span><span class="highlite-COMMENT"># </span></pre> </div> </div> <h2 id="method_spawn" class="raku-h2"><a href="#class_Proc" title="go to top of document">method spawn<a class="raku-anchor" title="direct link" href="#method_spawn">§</a></a></h2> <!-- defnmark method_spawn 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">spawn</span>(<span class="highlite-OPERATOR">*</span><span class="highlite-NAME_ARRAY">@args</span> ($<span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">*</span>@)<span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$cwd</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$*CWD</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">Hash</span>() <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$env</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_HASH">%*ENV</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$arg0</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$win-verbatim-args</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">False</span> <span class="highlite-KEYWORD">--></span> Bool:D)</pre> </div> </div> <p>Runs the <code>Proc</code> object with the given command, argument list, working directory, and environment.</p><p>If <code>:arg0</code> is set to a value, that value is passed as arg0 to the process instead of the program name.</p><p>On Windows the flag <code>$win-verbatim-args</code> disables all automatic quoting of process arguments. See <a href="https://docs.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way">this blog</a> for more information on windows command quoting. The flag is ignored on all other platforms. The flag was introduced in Rakudo version 2020.06 and is not present in older releases.</p> <h2 id="method_shell" class="raku-h2"><a href="#class_Proc" title="go to top of document">method shell<a class="raku-anchor" title="direct link" href="#method_shell">§</a></a></h2> <!-- defnmark method_shell 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">shell</span>(<span class="highlite-NAME_SCALAR">$cmd</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$cwd</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$*CWD</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$env</span> <span class="highlite-KEYWORD">--></span> Bool:D)</pre> </div> </div> <p>Runs the <code>Proc</code> object with the given command and environment which are passed through to the shell for parsing and execution. See <a href="/type/independent-routines#sub_shell"><code>shell</code></a> for an explanation of which shells are used by default in the most common operating systems.</p> <h2 id="method_command" class="raku-h2"><a href="#class_Proc" title="go to top of document">method command<a class="raku-anchor" title="direct link" href="#method_command">§</a></a></h2> <!-- defnmark method_command 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">command</span>(Proc:D: <span class="highlite-KEYWORD">--></span> List:D)</pre> </div> </div> <p>The command method is an accessor to a list containing the arguments that were passed when the Proc object was executed via <code>spawn</code> or <code>shell</code> or <code>run</code>.</p> <h2 id="method_Bool" class="raku-h2"><a href="#class_Proc" title="go to top of document">method Bool<a class="raku-anchor" title="direct link" href="#method_Bool">§</a></a></h2> <!-- defnmark method_Bool 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">multi</span> <span class="highlite-KEYWORD">method</span> <span class="highlite-TYPE">Bool</span>(Proc:D:)</pre> </div> </div> <p>Awaits for the process to finish and returns <code>True</code> if both exit code and signal of the process were 0, indicating a successful process termination. Returns <code>False</code> otherwise.</p> <h2 id="method_pid" class="raku-h2"><a href="#class_Proc" title="go to top of document">method pid<a class="raku-anchor" title="direct link" href="#method_pid">§</a></a></h2> <!-- defnmark method_pid 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">pid</span>()</pre> </div> </div> <p>Returns the <code>PID</code> value of the process if available, or <a href="/type/Nil"><code>Nil</code></a>.</p> <h2 id="method_exitcode" class="raku-h2"><a href="#class_Proc" title="go to top of document">method exitcode<a class="raku-anchor" title="direct link" href="#method_exitcode">§</a></a></h2> <!-- defnmark method_exitcode 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">exitcode</span>(Proc:D: <span class="highlite-KEYWORD">--></span> Int:D)</pre> </div> </div> <p>Returns the exit code of the external process, or -1 if it has not exited yet.</p> <h2 id="method_signal" class="raku-h2"><a href="#class_Proc" title="go to top of document">method signal<a class="raku-anchor" title="direct link" href="#method_signal">§</a></a></h2> <!-- defnmark method_signal 2 --> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">signal</span>(Proc:D:)</pre> </div> </div> <p>Returns the signal number with which the external process was killed, or <code>0</code> or an undefined value otherwise.</p> <h1 id="typegraphrelations" class="raku-h1"><a href="#" title="go to top of document">Typegraph<a class="raku-anchor" title="direct link" href="#typegraphrelations">§</a></a></h1> <figure class="typegraph" > <figcaption>Type relations for <code>Proc</code></figcaption> <svg width="68pt" height="188pt" viewBox="0.00 0.00 67.79 188.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)"> <title>raku-type-graph</title> <polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-184 63.79,-184 63.79,4 -4,4"/> <!-- Proc --> <g id="node1" class="node"> <title>Proc</title> <g id="a_node1"><a xlink:href="/type/Proc" xlink:title="Proc"> <ellipse fill="none" stroke="#000000" cx="29.9" cy="-18" rx="29.8" ry="18"/> <text text-anchor="middle" x="29.9" y="-14.3" font-family="FreeSans" font-size="14.00" fill="#000000">Proc</text> </a> </g> </g> <!-- Any --> <g id="node3" class="node"> <title>Any</title> <g id="a_node3"><a xlink:href="/type/Any" xlink:title="Any"> <ellipse fill="none" stroke="#000000" cx="29.9" cy="-90" rx="28.7" ry="18"/> <text text-anchor="middle" x="29.9" y="-86.3" font-family="FreeSans" font-size="14.00" fill="#000000">Any</text> </a> </g> </g> <!-- Proc->Any --> <g id="edge1" class="edge"> <title>Proc->Any</title> <path fill="none" stroke="#000000" d="M29.9,-36.3C29.9,-44.02 29.9,-53.29 29.9,-61.89"/> <polygon fill="#000000" stroke="#000000" points="26.4,-61.9 29.9,-71.9 33.4,-61.9 26.4,-61.9"/> </g> <!-- Mu --> <g id="node2" class="node"> <title>Mu</title> <g id="a_node2"><a xlink:href="/type/Mu" xlink:title="Mu"> <ellipse fill="none" stroke="#000000" cx="29.9" cy="-162" rx="27" ry="18"/> <text text-anchor="middle" x="29.9" y="-158.3" font-family="FreeSans" font-size="14.00" fill="#000000">Mu</text> </a> </g> </g> <!-- Any->Mu --> <g id="edge2" class="edge"> <title>Any->Mu</title> <path fill="none" stroke="#000000" d="M29.9,-108.3C29.9,-116.02 29.9,-125.29 29.9,-133.89"/> <polygon fill="#000000" stroke="#000000" points="26.4,-133.9 29.9,-143.9 33.4,-133.9 26.4,-133.9"/> </g> </g> </svg> <p class="fallback"> <a rel="alternate" href="/assets/typegraphs/Proc.svg"> Expand chart above </a></p> </figure> </div></div></section> </div> </div> </div> <footer class="footer main-footer"> <div class="container px-4"> <nav class="level"> <div class="level-left"> <div class="level-item"> <a href="/about">About</a> </div> <div class="level-item"> <a id="toggle-theme">Toggle theme</a> </div> <div class="level-item" title="eb7c31dad 2024-07-22"> <a>Commit</a> </div> </div> <div class="level-right"> <div class="level-item"> <a href="/license">License</a> </div> </div> </nav> </div> </footer> </body> </html>