
Esperamos que esta questão não seja muito genérica. Sou muito novo em scripts de shell e tenho experiência em arquitetura de computadores/programação sem scripts. Tenho notado nos scripts do meu trabalho que raramente os scripts são escritos criando um sub-shell em torno de todo o script. Nos scripts que estou escrevendo, quando consigo envolvê-lo com um sub-shell, o faço, pois evita que ele mexa com outros scripts que chamam o meu (por precaução). Esta não é uma prática comum devido a alguma sobrecarga associada a esta abordagem? Estou tendo dificuldade em encontrar isso online.
Exemplo:
#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell
Responder1
Subshells têm sobrecarga.
No meu sistema, o custo mínimo de fork-exec (quando você executa um programa a partir do disco quando o arquivo não está frio) é de cerca de 2ms
e o custo mínimo de bifurcação é de cerca de 1ms
.
Com subshells, você está falando apenas do custo de bifurcação, já que nenhum arquivo precisa ser exec
editado. Se os subshells forem mantidos razoavelmente baixos, 1ms
isso é bastante insignificante em programas voltados para humanos. Acredito que os humanos não conseguem perceber nada que acontece mais rápido do que 50ms
(e esse é o tempo que tende a levar para que os intérpretes de linguagem de script modernos comecem (estou falando python
e Ruby rvm
aqui) com o que nodejs
há de mais novo por aí 100ms
).
No entanto, ele adiciona loops, e então você pode querer substituir, por exemplo, o bacick ou $()
padrão bastante comum onde você return
algo de uma função imprimindo-o em stdout para o shell pai para catpure com bashisms como printf -v
(ou use um externo rápido programa para processar todo o lote).
Oconclusão do bashpacote evita especificamente esse custo de subshell retornando por meio de nomes de variáveis passados usando uma técnica descrita emhttp://fvue.nl/wiki/Bash:_Passing_variables_by_reference
Comparando
time for((i=0;i<10000;i++)); do echo "$(echo hello)"; done >/dev/null
com
time for((i=0;i<10000;i++)); do echo hello; done >/dev/null
deve fornecer uma boa estimativa de qual fork
é a sobrecarga do seu sistema.
Responder2
A execução do excelente código fornecido por PSkocik em meu sistema mostrou resultados insignificantes.
No entanto, este exemplo realmente atinge o alvo - comandos nativos versus comandos subshell:
MyPath="path/name.ext"
# this takes forever
time for((i=0;i<10000;i++)); do echo "$(basename ${MyPath} )"; done >/dev/null
#this is over 100x less time
time for((i=0;i<10000;i++)); do echo "${MyPath##*/}"; done >/dev/null