64 비트 리눅스에서 Ruby %X 포크이지만 32는 아니며 특정 구문 만으로만

StackOverflow https://stackoverflow.com/questions/214205

  •  03-07-2019
  •  | 
  •  

문제

루비 코드는 다음과 같습니다.

puts %x{ pstree #{$$} }   # never forks
puts %x{ pstree '#{$$}' } # forks on amd64 only

32 비트 Ubuntu Dapper에서는이 출력을 얻습니다.

t.rb---pstree
t.rb---pstree

나에게 의미가 있습니다. 그러나 64 비트 우분투 하디에서 나는 이것을 얻는다 :

t.rb---sh---pstree
t.rb---pstree

여기에 표시되는 것은 Ruby Forks가 사례 중 하나에서 실행하기 전입니다. 코드를 파일에 넣고 Strace -ff 아래로 실행하면 64 비트 Hardy에서 호출되는 것으로 보입니다. clone() (처럼 fork()) 전에 execve(), 32 비트 다퍼에는 그런 일이 없습니다.

내 루비 버전은 다음과 같습니다.

ruby 1.8.4 (2005-12-24) [i486-linux]
ruby 1.8.6 (2007-09-24 patchlevel 111) [x86_64-linux]

통역사 및 OS 및 Word 크기를 더 혼합하고 일치 시키려고 노력해야하지만,이 기계를 관리하지 않기 때문에 지금은 쉽지 않습니다. 어쩌면 누군가가 64 비트 시스템의 이러한 명령 사이에 차이가 무엇인지 말해 줄 수있을 것입니다.

도움이 되었습니까?

해결책

루비는 %X가 단일 인수 (당신이하는 것처럼)와 함께 사용될 때 쉘 확장을 수행합니다.

무슨 일이 일어나고 있는지에 대한 내 추측은 다음과 같습니다.

루비는 명령을 스캔하여 쉘 팽창을 수행 할 필요가있는 특수 문자가 있는지 확인하여 쉘을 호출하는 경우이를 수행합니다. 두 번째 예에서 단일 따옴표는 루비가 쉘을 호출하여 확장을 수행하기에 충분합니다. 따라서 포크입니다. 첫 번째 예에서 루비는 명령에 특수 문자가 포함되어 있지 않으므로 (가변 확장 후) 포크가 없기 때문에 쉘 확장이 필요하지 않다고 결정할 수 있습니다. 두 버전의 차이점은 아마도 루비가 결정하려고 시도하는 방법의 내부 변화와 관련이있을 것입니다. 쉘 확장이 필요합니다. 32 비트 기계의 Ruby 1.8.5의 두 번째 예제에 대한 포크를 얻습니다.

편집하다

좋아, 나는 루비 1.8.4 및 1.8.6의 소스 코드를 살펴 보았고 두 버전 모두 동일한 기준을 사용하여 다음 문자가 명령에 존재하는 경우 쉘 확장을 수행하기 위해 쉘을 호출할지 여부를 결정합니다. 줄 라인 %X에 대한 하나의 인수가 제공되면 쉘이 호출됩니다.

*?{}[]<>()~&|\\$;'`"\n

루비는 실제로 두 경우 모두 (인용문이 포함 된 예)에서 쉘을 호출하고 있습니다. pstree The의 차이 때문입니다 sh 다른 기계의 명령, 하나의 호출 fork, 다른 하나는 그렇지 않습니다. 이것을 직접 보려면 두 기계 에서이 명령을 실행하십시오.

/bin/sh -c "pstree $$"

이것은 루비가 실행하는 데 사용하는 명령입니다. pstree 두 기계에 따옴표가있는 예에서. 넌 봐야 해 bash---pstree 32 비트 기계에서 bash---sh---pstree 다른 하나에.

이제 궁금한 점이 있습니다. 왜이 차이를 발견하게되었고 문제가 발생 했습니까?

다른 팁

나는 일련의 하위 프로세서 (Fork)가있는 비동기 프로세서 작업을 개발 하여이 상황을 겪었으며, 마스터가 전경에있을 때 Sigint를 받았을 때 일어났다.

나는 실행 : "결과는 %(Monster-delayed-Job)"를 넣었다.

그리고 출력은 "결과는"

  • 예, 마스터에서 "Trap"Sigint

안드레

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top