Existem várias maneiras de executar um script, os que eu sei são:
/path/to/script # using the path (absolute or relative)
. script # using the . (dot)
source script # using the `source` command
São mais disso? Quais são as diferenças entre eles? Existem situações em que devo usar um e não outro?
shell-script
executable
phunehehe
fonte
fonte
Respostas:
Outra maneira é chamar o intérprete e passar o caminho para o script:
O ponto e a fonte são equivalentes. (EDIT: não, não são: como KeithB aponta em um comentário em outra resposta, "." Só funciona em shells relacionados ao bash, onde "source" funciona nos shells relacionados ao bash e csh.) Ele executa o script em -place (como se você tivesse copiado e colado o script ali). Isso significa que quaisquer funções e variáveis não locais no script permanecem. Isso também significa que, se o script gravar um CD em um diretório, você ainda estará lá quando terminar.
As outras maneiras de executar um script o executarão em seu próprio subshell. Variáveis no script ainda não estão ativas quando terminar. Se o script alterou os diretórios, não afetou o ambiente de chamada.
/ path / to / script e / bin / sh script são ligeiramente diferentes. Normalmente, um script tem um "shebang" no começo que se parece com isso:
Este é o caminho para o interpretador de scripts. Se ele especificar um intérprete diferente do que quando você o executa, ele pode se comportar de maneira diferente (ou pode não funcionar).
Por exemplo, scripts Perl e scripts Ruby começam com (respectivamente):
e
Se você executar um desses scripts executando
/bin/sh script
, eles não funcionarão.Na verdade, o Ubuntu não usa o shell bash, mas um muito semelhante chamado dash. Os scripts que requerem bash podem funcionar um pouco errados quando chamados,
/bin/sh script
porque você acabou de chamar um script bash usando o interpretador de traços.Outra pequena diferença entre chamar o script diretamente e passar o caminho do script para o intérprete é que o script deve ser marcado como executável para executá-lo diretamente, mas não para executá-lo passando o caminho para o intérprete.
Outra variação menor: você pode prefixar qualquer uma dessas maneiras de executar um script com eval, para poder ter
e assim por diante. Na verdade, não muda nada, mas pensei em incluí-lo por completo.
fonte
sh
corresponde adash
, mas não parabash
.A maioria das pessoas depura scripts shell adicionando os seguintes sinalizadores de depuração ao script:
Mas isso significa que você precisa abrir o arquivo com um editor (supondo que você tenha permissões para editar o arquivo), adicionar uma linha como
set -x
, salvar o arquivo e executar o arquivo. Quando terminar, você precisará seguir os mesmos passos e remover osset -x
etc. etc. Isso pode ser entediante.Em vez de fazer tudo isso, você pode definir os sinalizadores de depuração na linha de comando:
fonte
emulate sh 2>/dev/null
no topo dos meus scripts de shell. Quando executado com zsh, isso o coloca no modo compatível com POSIX. Quando executado com outras conchas, a linha não tem efeito. Então eu posso executar o script comzsh -x /path/to/script
. Eu gosto do zsh aqui porque fornece melhores traços do que o bash ou o ksh.Shawn J. Goff fez muitos pontos positivos, mas não incluiu toda a história:
Muitos scripts do sistema (como no init.d, no / etc e assim por diante) têm um shebang
#!/bin/sh
, mas/bin/sh
na verdade são um link simbólico para outro shell - nos tempos antigos/bin/bash
, atualmente/bin/dash
. Mas quando um deles é chamado como/bin/sh
, ele se comporta de maneira diferente, ou seja, adere ao modo de compatibilidade com POSIX.Como eles fazem isso? Bem, eles inspecionam como foram invocados.
O próprio shellscript pode testar como foi chamado e fazer coisas diferentes, dependendo disso? Sim pode. Portanto, a maneira como você o invoca sempre pode levar a resultados diferentes, mas é claro que raramente é feito para incomodá-lo. :)
Como regra geral: se você estiver aprendendo um shell específico, como o bash, e escrever comandos em um tutorial do bash, coloque
#!/bin/bash
o título, não#!/bin/sh
, exceto onde indicado em contrário. Caso contrário, seus comandos podem falhar. E se você não tiver escrito um script, invoque-o diretamente (./foo.sh
,bar/foo.sh
) em vez de adivinhar um shell (sh foo.sh
,sh bar/foo.sh
). O shebang deve chamar a concha certa.E aqui estão dois outros tipos de invocação:
fonte
.
esource
são equivalentes, pois não geram um subprocesso, mas executam comandos no shell atual. Isso é importante quando o script define variáveis de ambiente ou altera o diretório de trabalho atual.Usar o caminho ou atribuir a ele
/bin/sh
cria um novo processo no qual os comandos são executados.fonte
Estou pensando se há mais ...
.
esource
são os mesmos. Após a execução, quaisquer alterações no ambientescript
serão mantidas. Normalmente, ele seria usado para originar uma biblioteca Bash, para que a biblioteca possa ser reutilizada em muitos scripts diferentes.Também é uma boa maneira de manter o diretório atual. Se você alterar o diretório no script, ele não será aplicado no shell em que você executa esse script. Mas se você o originar para executá-lo, após a saída do script, o diretório atual será mantido.
fonte
.
só funciona em sh / bash e shells relacionados.source
também funciona em csh e shells relacionados." Userland exec " conta como uma maneira diferente? O Userland exec carrega o código e o executa sem o uso de uma chamada de sistema execve ().
fonte
Executa o script no shell atual quando o diretório não está no caminho.
fonte
. e source são um pouco diferentes no zsh pelo menos (é isso que eu uso) porque
Funciona, enquanto
não precisa
fonte