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 $?;
מצב גלובלי שהוא נוגע בו#
דוגמאות#
לכידת שורת פלט אחת:
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 signalmask with
$? & 127to get the signal number,$? >> 8for 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 להפעלת תהליך$/- מפריד רשומות הקלט שמפצל פלט בהקשר רשימה