มีใครช่วยได้บ้าง ใน Perl ความแตกต่างระหว่าง:
exec "command";
และ
system("command");
และ
print `command`;
มีวิธีอื่นในการรันคำสั่งเชลล์ด้วยหรือไม่
มีใครช่วยได้บ้าง ใน Perl ความแตกต่างระหว่าง:
exec "command";
และ
system("command");
และ
print `command`;
มีวิธีอื่นในการรันคำสั่งเชลล์ด้วยหรือไม่
คำตอบ:
รันคำสั่งและไม่เคยให้ผลตอบแทน มันเหมือนreturn
คำสั่งในฟังก์ชั่น
หากไม่พบคำสั่งจะexec
ส่งคืนค่าเท็จ มันจะไม่ส่งคืนจริงเพราะถ้าพบคำสั่งมันจะไม่ส่งกลับเลย นอกจากนี้ยังมีจุดใดในการกลับมาSTDOUT
, STDERR
หรือออกจากสถานะของคำสั่ง คุณสามารถค้นหาเอกสารเกี่ยวกับมันใน perlfunc
เพราะมันเป็นฟังก์ชั่น
รันคำสั่งและสคริปต์ Perl ของคุณจะดำเนินการต่อหลังจากคำสั่งเสร็จสิ้น
ค่าส่งคืนคือสถานะออกของคำสั่ง perlfunc
คุณสามารถค้นหาเอกสารเกี่ยวกับมันใน
เช่นsystem
รันคำสั่งและสคริปต์ Perl ของคุณจะดำเนินต่อไปหลังจากคำสั่งเสร็จสิ้น
ตรงกันข้ามกับsystem
ค่าส่งคืนเป็นSTDOUT
ของคำสั่ง
qx//
เทียบเท่ากับ backticks คุณสามารถค้นหาเอกสารเกี่ยวกับมันได้perlop
เนื่องจากไม่เหมือนsystem
และexec
เป็นผู้ดำเนินการ
สิ่งที่หายไปจากด้านบนเป็นวิธีการดำเนินการคำสั่งแบบอะซิงโครนัส นั่นหมายความว่าสคริปต์ Perl และคำสั่งของคุณทำงานพร้อมกัน open
นี้สามารถทำได้ด้วย อนุญาตให้คุณอ่านSTDOUT
/ STDERR
และเขียนSTDIN
คำสั่งของคุณ มันขึ้นอยู่กับแพลตฟอร์มว่า
นอกจากนี้ยังมีอีกหลายโมดูลที่สามารถทำให้งานนี้ง่าย มีIPC::Open2
และIPC::Open3
และIPC::Run
เช่นเดียวกับ
Win32::Process::Create
ถ้าคุณอยู่บน windows
ในการใช้งานทั่วไป I system
, open
, IPC::Open2
หรือIPC::Open3
ขึ้นอยู่กับสิ่งที่ฉันต้องการจะทำ qx//
ผู้ประกอบการในขณะที่ง่ายเกินไป constraining ในการทำงานของที่จะอยู่นอกมีประโยชน์มากของแฮ็กได้อย่างรวดเร็ว ฉันพบว่าopen
มีความชำนาญมากกว่า
system
: เรียกใช้คำสั่งและรอให้คำสั่งส่งคืนใช้system
เมื่อคุณต้องการเรียกใช้คำสั่งไม่สนใจเกี่ยวกับเอาต์พุตและไม่ต้องการให้สคริปต์ Perl ทำอะไรจนกว่าคำสั่งจะเสร็จสิ้น
#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");
หรือ
#spawns a shell, arguments are interpreted by the shell, use only if you
#want the shell to do globbing (e.g. *.txt) for you or you want to redirect
#output
system("command arg1 arg2 arg3");
qx//
หรือ `` : เรียกใช้คำสั่งและจับ STDOUT ของมันใช้qx//
เมื่อคุณต้องการเรียกใช้คำสั่งจับภาพสิ่งที่เขียนไปยัง STDOUT และไม่ต้องการให้สคริปต์ Perl ทำอะไรจนกว่าคำสั่งจะเสร็จสิ้น
#arguments are always processed by the shell
#in list context it returns the output as a list of lines
my @lines = qx/command arg1 arg2 arg3/;
#in scalar context it returns the output as one string
my $output = qx/command arg1 arg2 arg3/;
exec
: แทนที่กระบวนการปัจจุบันด้วยกระบวนการอื่นใช้exec
คู่กับfork
เมื่อคุณต้องการเรียกใช้คำสั่งไม่สนใจเกี่ยวกับเอาต์พุตและไม่ต้องการรอให้คำสั่งส่งคืน system
เป็นเพียงแค่จริงๆ
sub my_system {
die "could not fork\n" unless defined(my $pid = fork);
return waitpid $pid, 0 if $pid; #parent waits for child
exec @_; #replace child with new process
}
คุณอาจต้องการอ่านwaitpid
และperlipc
คู่มือ
open
: เรียกใช้กระบวนการและสร้างไพพ์ไปยัง STDIN หรือ STDERRใช้open
เมื่อคุณต้องการเขียนข้อมูลไปยัง STDIN ของกระบวนการหรืออ่านข้อมูลจาก STDOUT ของกระบวนการ (แต่ไม่ใช่ทั้งสองอย่างในเวลาเดียวกัน)
#read from a gzip file as if it were a normal file
open my $read_fh, "-|", "gzip", "-d", $filename
or die "could not open $filename: $!";
#write to a gzip compressed file as if were a normal file
open my $write_fh, "|-", "gzip", $filename
or die "could not open $filename: $!";
ใช้IPC::Open2
เมื่อคุณต้องการอ่านและเขียนไปยัง STDIN และ STDOUT ของกระบวนการ
use IPC::Open2;
open2 my $out, my $in, "/usr/bin/bc"
or die "could not run bc";
print $in "5+6\n";
my $answer = <$out>;
ใช้IPC::Open3
เมื่อคุณต้องการจับกระบวนการจัดการไฟล์มาตรฐานทั้งสามตัว ฉันจะเขียนตัวอย่าง แต่มันก็ใช้งานได้เหมือนกันกับ IPC :: Open2 แต่ส่วนใหญ่แล้วจะเรียงตามลำดับของอาร์กิวเมนต์และตัวจัดการไฟล์ตัวที่สาม
ฟังก์ชั่น exec ดำเนินการคำสั่งระบบและไม่กลับ - ใช้ระบบแทนexecถ้าคุณต้องการที่จะกลับมา
ทำสิ่งเดียวกันกับ exec LIST ยกเว้นว่าจะทำ forkก่อนและกระบวนการพาเรนต์จะรอให้กระบวนการลูกสมบูรณ์
ตรงกันข้ามกับexecและระบบ backticks ไม่ให้ค่าตอบแทน แต่เป็น STDOUT ที่รวบรวมไว้
สตริงซึ่งเป็น (อาจ) สอดแทรกแล้วดำเนินการเป็นคำสั่งระบบที่มี/ bin / shหรือเทียบเท่า สัญลักษณ์แทนของเชลล์ไพพ์และการเปลี่ยนเส้นทางจะได้รับการยกย่อง ที่เก็บรวบรวมได้ออกมาตรฐานของคำสั่งจะถูกส่งกลับ ; ข้อผิดพลาดมาตรฐานไม่ได้รับผลกระทบ
ในสถานการณ์ที่ซับซ้อนมากขึ้นที่คุณต้องการดึงข้อมูล STDOUT, STDERR หรือรหัสส่งคืนคุณสามารถใช้ที่รู้จักกันดีโมดูลมาตรฐานเช่นIPC :: Open2และIPC :: Open3
ตัวอย่าง:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
ในที่สุดIPC :: เรียกใช้จาก CPAN ก็คุ้มค่าที่จะดู ...
ความแตกต่างระหว่าง backticks ของ Perl (คน`
) system
และexec
?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
รันคำสั่งและไม่ดำเนินการสคริปต์ Perl ต่อ มันเป็นสคริปต์เหมือนreturn
คำสั่งคือฟังก์ชั่น
หากไม่พบคำสั่งให้exec
ส่งคืน false มันจะไม่ส่งคืนจริงเพราะถ้าพบคำสั่งมันจะไม่ส่งกลับเลย นอกจากนี้ยังมีจุดใดในการกลับมาSTDOUT
, STDERR
หรือออกจากสถานะของคำสั่ง คุณสามารถค้นหาเอกสารเกี่ยวกับมันในperlfuncเพราะมันเป็นฟังก์ชั่น
เช่น:
#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";
ในรหัสข้างต้นมีสามprint
คำสั่ง แต่เนื่องจากexec
ออกจากสคริปต์จะมีการดำเนินการคำสั่งพิมพ์ครั้งแรกเท่านั้น นอกจากนี้exec
เอาต์พุตคำสั่งไม่ได้ถูกกำหนดให้กับตัวแปรใด ๆ
ที่นี่มีเพียงคุณเท่านั้นที่ได้รับผลลัพธ์ของprint
คำสั่งแรกและการดำเนินการls
คำสั่งตามมาตรฐาน
system
system
รันคำสั่งและสคริปต์ Perl ของคุณจะกลับมาทำงานต่อหลังจากคำสั่งเสร็จสิ้น ค่าส่งคืนคือสถานะออกของคำสั่ง คุณสามารถค้นหาเอกสารเกี่ยวกับมันในperlfunc
เช่น:
#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";
ในรหัสข้างต้นมีสามprint
คำสั่ง เมื่อสคริปต์ทำงานต่อหลังจากsystem
คำสั่งคำสั่งการพิมพ์ทั้งสามจะถูกดำเนินการ
นอกจากนี้ผลของการทำงานsystem
จะได้รับมอบหมายให้data2
แต่ค่าที่ได้รับมอบหมายเป็น0
(รหัสการออกจากls
)
ที่นี่คุณจะได้รับผลลัพธ์ของprint
คำสั่งแรกจากนั้นls
ตามด้วยคำสั่งตามด้วยผลลัพธ์ของสองคำสั่งสุดท้ายprint
คำสั่งที่ออกมาตรฐาน
`
)เช่นsystem
ล้อมรอบคำสั่งใน backticks รันคำสั่งนั้นและสคริปต์ Perl ของคุณจะกลับมาทำงานต่อหลังจากคำสั่งเสร็จสิ้น ตรงกันข้ามกับsystem
ค่าส่งคืนเป็นSTDOUT
คำสั่ง qx//
เทียบเท่ากับ backticks คุณสามารถค้นหาเอกสารเกี่ยวกับมันในperlopเพราะแตกต่างจากระบบและexec
มันเป็นผู้ประกอบการ
เช่น:
#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
ในรหัสข้างต้นมีสามprint
คำสั่งและทั้งสามกำลังถูกดำเนินการ เอาต์พุตของls
จะไม่ออกมาตรฐานโดยตรง แต่กำหนดให้กับตัวแปรdata2
แล้วพิมพ์โดยคำสั่งพิมพ์สุดท้าย
ความแตกต่างระหว่าง 'exec' และ 'system' คือ exec แทนที่โปรแกรมปัจจุบันของคุณด้วย 'command' และไม่กลับสู่โปรแกรมของคุณ ในทางกลับกันส้อมและรัน 'คำสั่ง' และส่งคืนสถานะการออกของ 'คำสั่ง' เมื่อคุณรันเสร็จแล้ว เครื่องหมายขีดด้านหลังรัน 'คำสั่ง' จากนั้นส่งคืนสตริงที่แทนค่ามาตรฐาน (สิ่งที่มันจะพิมพ์ไปที่หน้าจอ)
คุณยังสามารถใช้ popen เพื่อรันคำสั่งเชลล์และฉันคิดว่ามีโมดูลเชลล์ - 'use shell' ที่ให้คุณเข้าถึงคำสั่งเชลล์ทั่วไปได้อย่างโปร่งใส
หวังว่าจะชี้แจงให้คุณ
use Shell;
( search.cpan.org/dist/Shell/Shell.pm )? มันไม่ได้ติดตั้งกันอย่างแพร่หลายและไม่เป็นมันที่ใช้บังคับกับคำถามที่ฉันคิดว่า ...