Rubi% x garfos no Linux de 64 bits, mas não em 32 e somente com sintaxe específica

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

  •  03-07-2019
  •  | 
  •  

Pergunta

Aqui está algum código Ruby:

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

Em 32-bit Ubuntu Dapper, eu recebo esta saída:

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

O que faz sentido para mim. Mas em 64-bit Ubuntu Hardy, fico com esta:

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

O que está sendo mostrado aqui é que garfos Ruby antes exec'ing em apenas um dos casos. Quando eu colocar o código em um arquivo e executá-lo sob strace -fF, parece que em 64-bit Hardy chama clone() (como fork()) antes execve(), Considerando que, em 32-bit Dapper que faz tal coisa.

versões Meu Ruby são:

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

Eu deveria tentar misturar e intérpretes de harmonização & palavra de & OS tamanhos mais, mas agora não é fácil desde que eu não administrar essas máquinas. Talvez alguém entre vós pode me dizer qual é a diferença mesmo é entre estes comandos no sistema de 64 bits, e muito menos por que eles funcionam da mesma por um 32-bit.

Foi útil?

Solução

executa rubi shell expansão quando% x é usado com um único argumento (como você está fazendo).

Aqui é o meu palpite sobre o que está acontecendo:

Rubi verifica o comando para determinar se existem quaisquer caracteres especiais que resultariam na necessidade de realizar a expansão shell, se assim ele chama o shell para fazer isso. No segundo exemplo, as aspas simples são suficientes para fazer o Ruby quer chamar a casca para fazer a expansão, daí o garfo. No primeiro exemplo Ruby pode determinar que a expansão da concha não é necessário que o comando não contém caracteres especiais (após expansão variável), portanto, nenhuma forquilha. A diferença entre as duas versões provavelmente tem a ver com uma mudança interna em como ruby ??tenta determinar é a expansão shell é necessário. Eu recebo um garfo para o segundo exemplo em ruby ??1.8.5 em uma máquina de 32 bits.

[EDIT]

Ok, eu dei uma olhada no código fonte para Ruby 1.8.4 e 1.8.6 e as duas versões utilizam os mesmos critérios para determinar se deve ou não chamar um shell para executar a expansão shell, se qualquer um dos seguintes caracteres existe na linha de comando do shell será chamado quando um argumento para% x é fornecido:

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

Ruby está realmente chamando o shell em ambos os casos (no exemplo que contém as aspas), a razão que você está vendo diferentes saídas de pstree é devido a diferenças no comando sh sobre as diferentes máquinas, um chamadas fork, o outro não. Para ver isso por si mesmo, executar este comando em ambas as máquinas:

/bin/sh -c "pstree $$"

Este é o comando que Ruby está usando para executar pstree no exemplo com citações em ambas as máquinas. Você deverá ver bash---pstree na máquina de 32 bits e bash---sh---pstree no outro.

Então, agora estou curioso, o que levou-o a descobrir esta diferença e é isso causando um problema?

Outras dicas

Eu passei por esta situação através do desenvolvimento de um trabalho de processador assíncrona que tem uma série de subprocessos (fork), e aconteceu quando o mestre estava em primeiro plano e recebeu um SIGINT.

Eu corro: puts "O resultado é% (atrasado-monstro-job)"

e a saída foi apenas: "o resultado é"

  • Sim, Im "armadilha" SIGINT no mestre

Andre

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top