2008-08-19 9 views
10

Perl에서는 system() 또는``(backticks)를 사용하여 시스템 명령을 실행할 수 있습니다. 명령 출력을 변수로 캡처 할 수도 있습니다. 그러나 이렇게하면 스크립트를 실행하는 사람이 볼 수 없도록 프로그램 실행이 백그라운드에서 숨겨집니다.Perl의 system()이 실행중인 명령을 어떻게 인쇄 할 수 있습니까?

일반적으로 유용하지만 때로는 뒤에서 무슨 일이 일어나고 있는지보고 싶습니다. 실행 한 명령이 터미널에 인쇄되고 해당 프로그램의 출력이 터미널에 인쇄되도록하려면 어떻게해야합니까? 이것은 "@echo on"에 해당하는 .bat입니다.

답변

8

알다시피, system()은 명령의 결과를 인쇄하지만 할당하지는 않습니다. 예 :

[[email protected] /]$ perl -e '$ls = system("ls"); print "Result: $ls\n"' 
bin dev home lost+found misc net proc sbin  srv System tools var 
boot etc lib media  mnt opt root selinux sys tmp  usr 
Result: 0 

역 따옴표는 인쇄 명령의 출력을 캡처하지 않습니다 등

[[email protected] /]$ perl -e '$ls = `ls`; print "Result: $ls\n"' 
Result: bin 
boot 
dev 
etc 
home 
lib 

...

업데이트

:이되는 명령의 이름을 인쇄하려면 system() 'd뿐만 아니라, 나는 Rudd의 접근법이 좋다라고 생각한다.

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    system($cmd); 
} 

my $cmd = $ARGV[0]; 
execute($cmd); 
4

대신 열기를 사용하십시오. 그런 다음 명령 출력을 캡처 할 수 있습니다.

open(LS,"|ls"); 
print LS; 
18

내가이 작업을 수행 할 수있는 기본 방법을 알고하지 않습니다,하지만 당신은 당신을 위해 그것을 할 수있는 서브 루틴을 정의 할 수 있습니다 :

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    system($cmd); 
} 

my $cmd = $ARGV[0]; 
execute($cmd); 

을 그리고 행동에서 볼 통합 여기를 반복 :

pbook:~/foo rudd$ perl foo.pl ls 
ls 
file1 file2 foo.pl 
2

흠, 다른 사람들이이 다양한 방식으로 어떻게 반응하는지 흥미 롭습니다. mkDaniel Fone은 명령의 표준 출력을 보거나 조작하고 싶다고 해석합니다 (둘 다 해결책은 표준 오류를 캡처하지 않습니다). 나는 Rudd 가깝게되었다고 생각합니다. Rudd의 대답에 대한 한 가지 트위스트는 내장 된 system() 명령을 자신의 버전으로 덮어서 기존 코드를 다시 작성하여 execute() 명령을 사용하지 않아도되도록하는 것입니다. 러드의 게시물에서 자신의 실행() 서브를 사용

, 당신은 당신의 코드 상단에 이런 식으로 뭔가를 할 수 :

if ($DEBUG) { 
    *{"CORE::GLOBAL::system"} = \&{"main::execute"}; 
} 

내가 그 일을 생각하지만, 나는이 부두입니다 인정해야하고 그것은이었다 이 코드를 작성한 이후로

# importing into either the calling or global namespace _must_ be 
    # done from import(). Doing it elsewhere will not have desired results. 
    delete($opts{handle_system}); 
    if ($do_system) { 
    if ($do_system eq 'local') { 
     *{"$callpkg\::system"} = \&{"$_package\::system"}; 
    } else { 
     *{"CORE::GLOBAL::system"} = \&{"$_package\::system"}; 
    } 
    } 
+0

글로벌'system' 명령을 교체에 큰 문제는 system'에 의해 복제 될 수없는 복잡한 프로토 타입을 가지고'이다 사용자가 지정한 프로토 타입 시스템. 결과적으로'system'을 사용자 정의 버전으로 바꾸면 일부 코드가 작동하지 않습니다. – cjm

1

tee 명령을 사용하여 답변에 언급 된 다른 사람과 결합하는 또 다른 기술이다 : 여기에 모듈로드 시간에 내가 로컬 (호출 네임 스페이스)에 시스템 호출을 가로 챌 수 년 전에 쓴 코드 또는 글로벌 수준이다 . 예를 들어 :

open(F, "ls | tee /dev/tty |"); 
while (<F>) { 
    print length($_), "\n"; 
} 
close(F); 

이 모두 (tee /dev/tty의 결과로) 현재의 디렉토리에있는 파일을 인쇄하고도 읽고 각 파일 이름의 길이를 출력.여기에 그 결과를 인쇄하고이를 반환 실행으로 업데이트

4

:

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    my $ret = `$cmd`; 
    print $ret; 
    return $ret; 
} 
관련 문제