Eu escrevi um script simples. Quando executo sh <myscriptname.sh>
, obtive a saída correta, mas quando executo ./<myscriptname.sh>
, recebi um erro.
Qual a diferença entre quando eu faço sh
e ./
?
Eu escrevi um script simples. Quando executo sh <myscriptname.sh>
, obtive a saída correta, mas quando executo ./<myscriptname.sh>
, recebi um erro.
Qual a diferença entre quando eu faço sh
e ./
?
Respostas:
Ao executar qualquer script, passando o nome do arquivo para o programa interpretador de scripts, você está executando o programa 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 sh
intérprete está abrindo o arquivo.
Por outro lado, se você executar o próprio script, o sistema chamará o programa interpretador especificado e alimentará o conteúdo do script. Nesse caso, o processo se parece com 'filename.sh' sem argumentos.
Você deve ter uma linha de estrondo:
#!/bin/bash
# bash script here
Uma linha de estrondo é a primeira linha do script e começa com os mesmos dois caracteres #!
; é isso que o sistema lê quando tenta executar o script e, em seguida, o sistema passa o script para o programa imediatamente depois. Observe que essa linha não tem nada a ver com o bash e funciona tão bem com python quanto perl, mesmo que sejam linguagens muito diferentes. Você usaria, #!/usr/bin/python
por exemplo, e o seguiria com código python.
Depois de ter seu script, verifique se você definiu permissões de execução:
chmod a+x filename.sh
Então você pode executar o script como seu próprio processo:
./filename.sh
Ou coloque o arquivo em um local conhecido com um bom nome de programa, curta /usr/sbin
e execute de qualquer lugar:
sudo cp filename.sh /usr/sbin/program-name
program-name
E esse é realmente o benefício prático de usar a linha de bate-papo com as permissões corretas - é tudo sobre implantação . É muito difícil fazer com que os usuários executem um script se precisarem se lembrar de qual programa executar o script. Lembre-se de fornecer um caminho completo para o script sempre que ele quiser executá-lo. Onde, /usr/local/bin
por exemplo, colocá-lo em executável e torná-lo executável, pode economizar muito sofrimento 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 top
programa, um script executado sem a linha de interrupção terá apenas o nome do intérprete bash
, perl
ou seja , 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 de manual e um pacote deb para instalá-lo. Precisamos reduzir o número de scripts aleatórios online e aumentar o número de debs que podem ser desinstalados.
bash
não é sh
.
PATH
.
/usr/local/bin
provavelmente é melhor então /usr/sbin
- indica que o programa é local para esta máquina, em vez de fazer parte da distribuição.
A versão curta:
sh
é o intérprete da linha de comandos (traço).
A execução sh my_script
faz o traço interpretar o script.
./
tenta descobrir qual intérprete usar, observando a primeira linha. Por exemplo #!/bin/bash
, ou mesmo #!/bin/ruby
(em oposição à execução ruby my_script
).
./
que encontra alguma coisa, é o método de execução do sistema que analisa os dois primeiros bytes do arquivo.
sh
e o arquivo contém um sha-bang, isso significa que o sha-bang será ignorado ou abrirá o shell onde os sh
links também estão e, em seguida, talvez algum outro shell ou o que ele faz :)?
A diferença que você faz é
com sh
, você está executando um programa que interpretará as linhas do seu script da mesma forma que as digitaria no prompt interativo do terminal,
com ./
você criando um atalho, assumindo que o script esteja exatamente aqui no diretório atual em que está sentado E será executável (porque, por exemplo, você o emitiu chmod +x myscript.sh
), economizando um tempo inestimável para tempos futuros :-)
sh
o arquivo não deve ser necessariamente executável.
Há três razões principais para você estar recebendo um erro:
chmod +x <myscriptname.sh>
para corrigir issonoexec
") /usr/local/bin
#!
linha tem um erro, #!/bin/sh
ou#!/bin/bash
Se sua primeira linha parecer correta, mas ainda não estiver funcionando, verifique se o arquivo não possui terminações 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 corrigi-lo executando dos2unix <myscriptname.sh>
ou, se não tiver
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
,.
E a resposta é que sh é o nome do shell muito popular. Mas desatualizado e substituído por outros. Atualmente, o sh está vinculado a outros shells instalados na máquina. por exemplo, eu bash putted lá. A execução de qualquer shell a partir do sh geralmente aciona algum modo de 'compatibilidade' com o comportamento original do 'shell'.
Portanto, a solução é bastante 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 assim no seu script, edite-o).
E, como alternativa, pode haver algum bug no próprio script. Como dependência que é atendida por sh, mas não intérprete que é realmente usado.
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
Não /usr/sbin
, isso é para ferramentas administrativas não essenciais, /usr/local/bin
é uma escolha melhor se você não quiser ~/bin/
, mas sudo
é aconselhável evitar o máximo possível.
~/.profile
já possui código para adicionar ~/bin
, se existir, a PATH
. Em outra nota, não coloque extensões nos scripts.
ls ~/bin/|wc -l = 428
) Eu coloquei um monte de coisas lá dentro;)
/bin
e /usr/bin
perceber que eles não usam extensões.