.sh especificando extensão?

12

Por que alguns sistemas executam um arquivo .sh apenas especificando o nome do arquivo sem extensão e outros exigem nome mais extensão? No meu caso, estou tentando escrever uma série de comandos seguindo estas instruções .

Estou especificando a extensão agora, mas ser capaz de executar os comandos sem .sh seria preferível.

    
por Philip Kirkbride 28.04.2016 / 06:25

5 respostas

39

Você está confuso. A extensão .sh é apenas uma dica para humanos, e não tem absolutamente nenhum efeito sobre como o sistema lida com o arquivo. O Unix / Linux não tornou o erro Secrets.pdf.exe do Windows.

Aqui está o que acontece quando você digita foo :

  1. O redirecionamento para STDIN , STDOUT e STDERR está configurado.

  2. O shell verifica sua tabela de hash interna para ver se já conhece uma entrada $PATH para foo . Se nenhum existir, o shell pesquisará os diretórios em $PATH , procurando por um arquivo chamado foo que tenha o bit Execute definido em suas permissões de arquivo. Primeiro foo ganha.

  3. Se os dois primeiros bytes do arquivo foo forem #! , a próxima cadeia será o nome de um interpretador a ser executado. Assim, #!/bin/bash introduz um script Bash, #!/usr/bin/perl introduz um script Perl, etc.

  4. Se o arquivo começar com 7ELF , ele será um executável binário e ld.so iniciará.

Leia man execve e man ld.so para uma explicação mais detalhada.

    
por waltinator 28.04.2016 / 06:42
12

O ponto chave é este: As extensões são irrelevantes em qualquer sistema do sistema Unix-like. Um nome de arquivo é apenas nome e não tem efeito sobre se script ou executável compilado pode ou não ser executado . Um programador pode adicionar uma extensão .sh para designar que um arquivo é shell script, ou .py para script python, mas diferente do Windows, qualquer unix não se preocupa com nomes, ele se importa com permissões.

O que importa é a permissão executável concedida a um arquivo. Qual você pode verificar com

ls -l /path/to/file

Execução de executáveis

Para executar o script, geralmente há várias maneiras.

  • Se o seu diretório atual for o mesmo que o script e o script tiver permissões executáveis, você poderá executá-lo assim ./my_script_name . O . significa o diretório atual.
  • Se o seu diretório atual for diferente e o script tiver permissões executáveis, você poderá executá-lo especificando o caminho completo: /home/user/bin/my_script_name

(Os dois métodos acima dependem do conjunto de permissões executáveis; independentemente de o arquivo fazer parte da variável $PATH ser irrelevante. A presença da linha #! também é importante; sem ela, o script será executado pela corrente shell que você tem aberto.Se eu tiver csh script sem essa linha, e tentar executá-lo no bash com ./my_script.csh , ele irá falhar)

  • Se o seu script estiver localizado no diretório que faz parte da sua variável $PATH , você poderá executá-lo apenas chamando o nome. Você pode chamar o comando chmod na linha de comando apenas digitando seu nome porque está na pasta /bin . /bin é sempre parte da variável $PATH . Neste caso, permissões executáveis e localização do material do script
  • Especificando um interpretador como comando e script como argumento. Dessa forma, o script servirá como arquivo de entrada para o interpretador.
  • Fornecendo um arquivo. O . filename.sh ou source filename.sh fará com que o script seja tratado como se fosse uma entrada de teclado, ou seja, como se tivesse sido digitado diretamente na linha de comando. Neste caso, permissões e localização executáveis não importam

Exemplos

Exemplo # 1, em execução com o interpretador, para permissões de execução

$-> ls -l abc.py                                                               
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py                                                              
a
b
c

Exemplo # 2, em execução com o conjunto de permissões executáveis ./ , conjunto de linhas shebang.

$-> cat abc.py                                                                 
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
   print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py                                                                   
a
b
c

Exemplo # 3, rodando sem o conjunto de linhas shebang (falha, porque o bash não pode ler scripts python; nenhuma linha shebang assume o shell atual como intérprete)

$-> cat abc.py                                                                 
for letter in 'a' 'b' 'c' :
   print letter
$-> ./abc.py                                                                   
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")

Exemplo # 4, executando o script que possui permissões executáveis configuradas na pasta de formulário que faz parte de $PATH variable

#  /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh

$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.                    
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py          
$-> # after adding the line with vi text editor, we can run
$-> abc.py                                                                     
a
b
c

O exemplo # 5, removendo a extensão, ainda é executado porque as extensões não importam, mas tem permissões e faz parte de $PATH :

$-> mv ~/bin/abc.py  ~/bin/abc                                                 
$-> abc
a
b
c
    
por Sergiy Kolodyazhnyy 28.04.2016 / 06:35
6

Boas explicações aqui já. Eu só queria acrescentar que idealmente você não deveria usar extensões de arquivo para executáveis.

Normalmente, você precisa realizar algo relativamente fácil e começar com um pequeno script de shell. Com o tempo, você começa a adicionar mais e mais funcionalidades ao seu script, até chegar algum tempo em que ele se torne inatingível ou precise de alguma funcionalidade que não possa ser facilmente obtida com um shell script e pense em reescrever esse shell script em outro idioma , perl, ...?).

Reescrever a partir do zero é geralmente considerado um erro, mas para scripts pode fazer sentido, porque geralmente eles não são tão grandes ou têm muita funcionalidade. Mas vamos supor que é possível reescrever do zero em alguma outra linguagem, mantendo a funcionalidade e params / flags do shell script inicial.

Os usuários deste script não precisam estar cientes dessa alteração de idioma, eles continuarão executando o mesmo comando e continuarão funcionando.

Se o seu script foi nomeado do-something.sh , ele pode continuar sendo do-something.sh , mas agora está escrito em python (por exemplo), e sua dica inicial agora é totalmente enganosa .

    
por Carlos Campderrós 28.04.2016 / 10:31
4

Para executar arquivos sem uma extensão, você normalmente não precisa fazer muito, apenas certifique-se de ter (no caso de scripts bash) a linha correta da shebang na primeira linha:

#!/bin/bash

você também precisará tornar o arquivo executável para o sistema

chmod 755 yourfilename

Isto é o mesmo que usar chmod +x yourfilename , os números são facilmente explicados.

É um número triplo de octais adicionados, o primeiro número representa o usuário, o segundo para o grupo e o terceiro para os outros, mais sobre isso você pode encontrar aqui .

E se você estiver no mesmo diretório do seu script, não se esqueça de usar ./ da seguinte forma:

./yourfilename
    
por Videonauth 28.04.2016 / 06:28
0

O sufixo .sh pode realmente atrapalhar, porque, para executá-lo, é necessário digitar myscript.sh em vez de apenas myscript, o que não funcionará. É melhor chamá-lo de "myscript" sem o sufixo .sh, e um uso rápido do comando "file" dirá se é um executável binário (formato ELF no linux) ou um shell script, ou qualquer outro tipo de script.

QDOS (Sistema Operacional Rápido e Sujo, mais tarde renomeado para "DOS" pela IBM depois que a mirosoft piratou e ilegalmente o vendeu para eles) e outras cópias baratas de CP / M, incluindo janelas, misturam tudo isso porque naqueles sistemas não existem permissões de execução em arquivos. Isso resultou em inúmeros fóruns de segurança nos últimos 30 a 40 anos. Na verdade, apenas alguns minutos atrás eu acabei de receber vários e-mails indesejados com um arquivo zip preso a MYPICTURE.JPG.zip:)

    
por delt 03.05.2016 / 19:56