2013-10-08 1 views
3
irb(main):001:0> require 'benchmark' 
=> true 
irb(main):002:0> puts Benchmark.measure { system "xclip .bashrc" } 
    0.000000 0.000000 0.000000 ( 0.008030) 
=> nil 
irb(main):003:0> puts Benchmark.measure { `xclip .bashrc` } 
    0.000000 0.000000 0.000000 (33.215158) 
=> nil 
irb(main):004:0> RUBY_VERSION 
=> "2.0.0" 

나는 루비 스크립트에서 쉘 명령을 호출하는 다양한 방법에 대해 인터넷에서 alomost 모든 것을 읽고,하지만 Kernel#`가 훨씬 더 Kernel#system보다 오래 걸리는 이유는 단지 알아낼 수 없습니다.왜`xclip .bashrc`가 루비의 시스템 ("xclip .bashrc")보다 훨씬 오래 걸리나요?

업데이트는 :

Kernel#`xclip 훨씬 느립니다. 다른 모든 명령은 거의 같은 시간이 걸립니다.

+0

@platzhirsch'xclip'은 표준 출력에 아무 것도 출력하지 않습니다. 왜'xclip'만이 백틱으로 느리게 느려지는지 설명하지 못하고'cat'과 같은 다른 명령은 완벽하게 작동합니다. – toctan

답변

3

난 당신이 좀 바꿔 역 따옴표를 사용하는 경우 xclip 그냥 종료하는 데 시간이 오래 걸리는 것을 의심한다. 이것은 선택과 관련이 있습니다. -sel을 통해 제공되는 선택 사항이 없으면 가운데 마우스 버튼을 통해 복사 및 붙여 넣기를 구현하는 데 일반적으로 사용되는 XA_PRIMARY이 기본값으로 사용됩니다. 당신이

$ xclip text.txt 

을 실행하면

콘텐츠는 당신이 당신의 마우스 가운데 버튼 또는 $ xclip -o을 붙여 넣을 수 있습니다 의미 XA_PRIMARY를 통해 사용할 수 있습니다. 당신이 아무것도하지 않는 경우

ruby -e '`xclip text.txt` 

그것은 결코 정말 종료 : 그것은 당신이 루비에서 쉘 thorugh을 실행할 때 이상한 얻을 시작합니다. X11 시스템에서 someting을 선택할 때 종료됩니다 (예 : 콘솔 또는 다른 모든 곳). 그냥 선택, 마우스로 뭔가를 표시합니다. 당신이하지 않으면, 그것은 어느 시점에서 멈추거나 및/또는 타임 아웃 할 것이다.

당신이 상세 모드를 사용할 때 동일한 동작을 관찰 할 수있다 :

$ xclip -verbose text.txt 

Connected to X server. 
Using UTF8_STRING. 
Reading text.txt... 
Waiting for selection requests, Control-C to quit 
    Waiting for selection request number 1 

당신이 뭔가를 선택할 때 요청이 다시 게재되는보세요.

이것에 대한 좋은 분석 도구가 strace 인 선택이 될 때까지이 달려 마지막 줄에서

$ strace -f ruby -e '`xclip text.txt`' 

... 
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}]) 
writev(3, [{"\20\0\3\0\4\0\200\2INCR", 12}, {NULL, 0}, {"", 0}], 3) = 12 
poll([{fd=3, events=POLLIN}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN}]) 
recvfrom(3, "\1\0\f\0\0\0\0\0\235\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 4096,                  0, NULL, NULL) = 32 
recvfrom(3, 0x165e964, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable) 
recvfrom(3, 0x165e964, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable) 
poll([{fd=3, events=POLLIN}], 1, 4294967295 

합니다 (-f 옵션도 추적 포크입니다). poll()은 파일 설명자에서 파일 이벤트를 기다리는 데 사용됩니다. 그것은 어느 시점에서 종료되지만, 4,294,967,295 ms는 다소 길다. 그냥 strace -f xclip text.txt으로 추적 할 수 있습니다.

ls -l /proc/PID/fd을 통해 파일 설명자를 살펴볼 수 있습니다. 숫자가 3 인 파일 설명자는 xclip이 선택을 기다리는 위치입니다.

디버그를 어렵게 만드는 이유는 바로 if가 strace xclip text.txt으로 즉시 종료되지만 strace -f text.txt으로 종료하지 않는 것입니다. 포크를 추적하고자하는 순간 더 이상 작동하지 않습니다. 그것은 Ruby와 동일한 문제입니다. Kernel#`이 출력을 리턴하려고하므로 출력을 추적하려고 시도합니다. 이것은 아마도 티켓 #9 Not closing stdout when setting clipboard from stdin과 관련이 있습니다.

이것은 제 이론입니다. 여러분이 쉘 아웃했을 때 출력을 xclip, 표준 출력을 읽으려면 Ruby, 포크를 추적하려면 strace을 따르고 싶을 때까지는 표준 출력이 선택 될 때까지 닫히지 않습니다.

아주 잘 설명하지는 않지만 루비에 대해 아무 것도 할 필요가 없음을 보여줍니다. 나는 xclip에만 초점을 맞추고 루비의 맥락에서는 초점을 맞추지 않는 질문을 만들 것입니다.

-1

xclip을 사용하여 수행중인 작업에 대한 자세한 내용을 제공해야합니다. B/c (왜냐하면) 내 루비 1.9.3은 "echo hello"를 사용하여 최소한의 차이점을 보여줍니다.

$ irb 
irb(main):001:0> require 'benchmark' 
=> true 
irb(main):002:0> puts Benchmark.measure { `echo hello` } 
    0.000000 0.000000 0.000000 ( 0.001471) 
=> nil 
irb(main):003:0> puts Benchmark.measure { system "echo hello" } 
hello 
    0.000000 0.000000 0.000000 ( 0.001598) 
=> nil 
irb(main):004:0> RUBY_VERSION 
=> "1.9.3" 
+0

난 xclip으로 리눅스 클립 보드를 조작하려고하고있다. 'echo'도 내 시스템에서 괜찮아요, 단지'xclip'은 백틱으로 훨씬 느립니다. – toctan

+0

커널 #'및 커널 # 시스템 호출 순서를 여러 번 뒤집어 여러 번 테스트 해 볼 수 있습니다. 아마도 Ruby보다는 xclip에서 타이밍을보고있을 것입니다. – ChuckCottrill

+0

나는이 문제에 몇 시간 동안 고생했다. 믿어 라. 나는 여러 번 시험 해 본다. 내 친구의 컴퓨터에서 테스트했다. 같은 결과가 나온다. 'system "xclip file" 터미널에 입력 한 후 RET을 누르면'\'xclip file \''이 완료되기까지 수십 초가 걸리며 파일이 커지면 속도가 느려집니다. – toctan