תהליכים

readpipe#

הרצת פקודת shell והחזרת הפלט הסטנדרטי שלה.

readpipe מעביר את EXPR ל־shell, ממתין לסיום הילד, ומחזיר את כל מה שהילד כתב לפלט הסטנדרטי שלו. זוהי הצורה בעלת השם של אופרטור qx (backticks) - `cmd` ו־qx/cmd/ מתהדרים שניהם ל־readpipe. יש לפנות לצורה בעלת השם כשרוצים את הפקודה במשתנה, כשרוצים לדכא את שיבוץ הגרשיים הכפולים ש־qx מבצע, או כשרוצים לקרוא פקודה שנלכדה מ־@ARGV. אם EXPR מושמט, נעשה שימוש ב־$_.

תקציר#

readpipe EXPR
readpipe
$out  = readpipe $cmd;
@rows = readpipe $cmd;

מה מקבלים בחזרה#

ההקשר מכריע את הצורה:

  • הקשר סקלר - מחרוזת אחת המכילה את כל הפלט שנלכד, כולל newlines.

  • הקשר רשימה - רשימה של רשומות, מפוצלת על $/ (מפריד רשומות הקלט, newline כברירת מחדל). המפריד נשאר צמוד לכל איבר אלא אם מבצעים עליו chomp.

$? נקבע לסטטוס ההמתנה של הילד לאחר שהפקודה מסתיימת, בדיוק כמו עם system. $? שונה מאפס הוא הסימן הרגיל לכך שהפקודה נכשלה - ערך ההחזרה לבדו אינו יכול לומר לך, כי פקודה כושלת עדיין יכולה לכתוב פלט (או כלום) לפני היציאה.

my $out = readpipe "uname -a";
die "uname failed: \$? = $?" if $?;

מצב גלובלי שהוא נוגע בו#

  • $_ - משמש כפקודה כאשר EXPR מושמט.

  • $/ - שולט באופן שבו פלט בהקשר רשימה מפוצל לרשומות. יש לקבוע אותו ל־undef כדי לבלוע את כל הפלט לאיבר יחיד, או ל־"" למצב פסקה.

  • $? - נקבע לסטטוס ההמתנה של הילד עם ההחזרה.

  • $! - נקבע אם ה־shell עצמו לא יכול היה להיות מופעל.

  • %ENV - ה־shell יורש את הסביבה הנוכחית.

דוגמאות#

לכידת שורת פלט אחת:

my $host = readpipe "hostname";
chomp $host;
print "running on $host\n";

פקודה המוחזקת במשתנה - הסיבה ש־readpipe קיים כפונקציה בעלת שם. Backticks היו עדיין עובדים כאן, אך readpipe הופך את הכוונה למפורשת ונמנע מהרעש החזותי של ציטוט מקונן:

my $cmd = "ls -1 /etc";
my @entries = readpipe $cmd;
chomp @entries;
print scalar(@entries), " entries under /etc\n";

בליעת הכל כמחרוזת אחת על־ידי ביטול הפרדת רשומות:

local $/;                               # slurp mode
my $log = readpipe "dmesg";
print length($log), " bytes of kernel log\n";

מצב פסקה - כל איבר הוא בלוק אחד מופרד בשורה ריקה:

local $/ = "";
my @paragraphs = readpipe "cat README";
print scalar(@paragraphs), " paragraphs\n";

בדיקת סטטוס היציאה כראוי. ערך ההחזרה הוא פלט; הצלחה גרה ב־$?:

my @files = readpipe "find . -name '*.tmp' 2>/dev/null";
if ($? == 0) {
    chomp @files;
    unlink @files;
} else {
    warn "find exited with status ", ($? >> 8), "\n";
}

שימוש ב־$_ כפקודה. לעיתים נדירות הצורה הברורה ביותר, אבל חוקי:

$_ = "date";
my $when = readpipe;                    # same as readpipe $_

מקרי קצה#

  • אין הגנת שיבוץ. readpipe משבץ את הארגומנט שלו בדיוק כמו מחרוזת בגרשיים כפולים - בדיוק כמו qx. readpipe "rm $path" כאשר $path מגיע מקלט משתמש הוא חור הזרקת shell. יש לצטט את הערך, או טוב מכך, לעבור ל־system בצורת רשימה / open בצינור ולדלג על ה־shell לחלוטין.

  • שגיאה סטנדרטית אינה נלכדת. רק הפלט הסטנדרטי של הילד חוזר. יש להפנות stderr בפקודה עצמה אם רוצים אותו מאוחד: readpipe "cmd 2>&1".

  • Shell הוא חובה. אפילו readpipe "true" במילה אחת עובר דרך /bin/sh, מה שאומר שציטוט shell, globbing, והרחבת משתני סביבה כולם חלים. לא קיימת צורת רשימה.

  • Buffers פלט גדולים בזיכרון. כל פלט הילד נקרא לפני ש־readpipe מחזיר. עבור פקודה שמייצרת ג׳יגה־בייטים, יש להשתמש ב־open בצינור ולקרוא בהדרגה במקום.

  • פלט ריק, יציאה אפס. פקודה מוצלחת שאינה כותבת דבר מחזירה את המחרוזת הריקה בהקשר סקלר ואת הרשימה הריקה בהקשר רשימה. יש להבחין בין ״רצה ולא אמרה דבר״ ל־״לעולם לא רצה״ על־ידי בדיקת $?.

  • Child died on signal. $? encodes both exit code and signal

    • mask with $? & 127 to get the signal number, $? >> 8 for the exit code.

  • כללי ציטוט של Windows. readpipe מעביר את המחרוזת ל־shell של הפלטפורמה; ב־Windows זהו cmd.exe, שכללי הציטוט וההפניה שלו שונים מ־POSIX. pperl הוא ללינוקס בלבד, ולכן זה רלוונטי רק כשמייבאים סקריפטים.

הבדלים מ־upstream#

תואם מלא ל־upstream Perl 5.42.

ראו גם#

  • qx - צורת האופרטור; `cmd` ו־qx/cmd/ הם קיצורים ל־readpipe ונושאים סמנטיקה זהה

  • system - הרצת פקודה ללא לכידת פלט; להשתמש כאשר אכפת רק מסטטוס היציאה

  • exec - החלפת התהליך הנוכחי בפקודה; ללא החזרה, ללא לכידה

  • open - open בצינור (open my $fh, "-|", @cmd) מזרים את פלט הילד שורה־שורה מבלי לעשות buffer לכולו

  • $? - סטטוס המתנה של ילד שנקבע על־ידי כל builtin להפעלת תהליך

  • $/ - מפריד רשומות הקלט שמפצל פלט בהקשר רשימה