Qual é a diferença entre ./ e sh para executar um script?

61

Eu escrevi um script simples. Quando executo sh <myscriptname.sh> , obtive a saída correta, mas quando executo ./<myscriptname.sh> , recebo um erro.

Qual é a diferença entre quando eu faço sh e ./ ?

    
por mr_eclair 23.01.2011 / 16:16

6 respostas

59

Quando você executa qualquer script passando o nome do arquivo para o programa do interpretador de scripts, você está executando o programa do interpretador com o script como um argumento passado para ele. Por exemplo, isso seria parecido com o processo 'sh' com o argumento 'filename.sh'. O interpretador sh está abrindo o arquivo.

Por outro lado, se você executar o script em si, o sistema chamará o programa do interpretador especificado e alimentará o conteúdo dos scripts. Neste caso, o processo se parece com 'filename.sh' sem argumentos.

Você deve se certificar de ter uma linha de destaque:

#!/bin/bash
# bash script here

Uma linha bang é a primeira linha no script e começa com os mesmos dois caracteres #! , são eles que o sistema lê quando tenta executar o script e depois o sistema passa o script para o programa imediatamente depois. Note que esta linha não tem nada a ver com bash e funciona tão bem para python e perl, apesar de serem linguagens muito diferentes. Você usaria #!/usr/bin/python por exemplo e depois seguiria com código python.

Depois de ter seu script, verifique se você definiu as permissões de execução:

chmod a+x filename.sh

Depois, você pode executar o script como seu próprio processo:

./filename.sh

Ou coloque o arquivo em um local conhecido com um nome de programa legal, como /usr/sbin e execute em qualquer lugar:

sudo cp filename.sh /usr/sbin/program-name
program-name

E esse é realmente o benefício prático de usar a linha bang com as permissões certas - é tudo sobre implantação . É muito difícil conseguir que os usuários executem um script se tiverem que lembrar qual programa executar o script. Lembre-se de dar um caminho completo para o script toda vez que quiser executá-lo. Onde colocar em /usr/local/bin , por exemplo, e torná-lo executável, pode economizar muita dor para as pessoas que tentam usar seu script. Esses programas ficam disponíveis para todos os usuários no seu computador.

Também é bom para identificação. Se você entrar no programa top , um script executado sem a linha bang terá apenas o nome do interpretador, ou seja, bash , perl ou python . Mas se um script for executado com as permissões corretas, o nome do script será exibido.

Nota: Se você deseja distribuir um script acessível a todos, crie uma página man e um pacote deb para instalá-lo. Precisamos reduzir o número de scripts aleatórios on-line e aumentar o número de debs que podem ser desinstalados.

    
por Martin Owens -doctormo- 23.01.2011 / 16:31
32

A versão curta:

  • sh é o interpretador de linha de comando (traço).
    Executar sh my_script faz o traço interpretar o script.

  • ./ tenta descobrir qual interpretador usar, observando a primeira linha. Por exemplo. #!/bin/bash , ou mesmo #!/bin/ruby (como em oposição a executar ruby my_script ).

por Stefano Palazzo 23.01.2011 / 16:44
3

Existem três motivos principais pelos quais você pode estar recebendo um erro:

  • o arquivo não é executável
    execute chmod +x <myscriptname.sh> para corrigir isso
  • a partição não permite executar scripts (está montada " noexec ")
    copie o script para /usr/local/bin
  • a linha #! tem um erro
    verifique se a primeira linha é #!/bin/sh ou #!/bin/bash

Se a sua primeira linha parece certa, mas ainda não está funcionando, verifique se o arquivo não tem finais de linha do DOS.

O erro seria algo como isto:

$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory

Você pode consertá-lo executando dos2unix <myscriptname.sh> ou, se não tiver, perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh> .

    
por Mikel 03.02.2011 / 23:03
2

A diferença que você faz é,

  • com sh , você está executando um programa que irá interpretar as linhas em seu script da mesma forma que as teria digitado no prompt interativo do terminal,

  • com ./ você está fazendo um atalho supondo que o script está bem aqui no diretório atual em que você está sentado E será executável (porque, por exemplo, você emitiu chmod +x myscript.sh ), salvando você tempo inestimável para tempos futuros: -)

por meduz 23.01.2011 / 23:13
0

E a resposta é que sh é o nome do shell muito popular. Mas desatualizado e substituído por outros. Atualmente, sh está ligado a outros shells instalados na máquina. por exemplo. Tenho bash putted lá. Executar qualquer shell de sh geralmente aciona algum modo de 'compatibilidade' com o comportamento original de 'shell'.

Portanto, a solução é bem simples. Veja o que está por trás do comando sh (ls -al / bin / sh), e coloque #! / Bin / whatever_you_find_there como primeira linha (ou se houver algo parecido em seu script, edite-o).

E, alternativamente, pode haver algum bug no próprio script. Como a dependência que é atendida por sh, mas não pelo intérprete que é realmente usado.

    
por przemo_li 23.01.2011 / 18:09
0
mkdir ~/bin ; cp myscript.sh ~/bin/

echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ; 

Não é /usr/sbin , ou seja, para ferramentas administrativas não essenciais, /usr/local/bin é a melhor opção se você não quiser ter um ~/bin/ , mas evitando sudo tanto quanto possível é aconselhável.

    
por Joey1978 24.01.2011 / 08:25