Por que todos os arquivos de script começam com
#!/bin/sh
ou com
#!/bin/csh
Isso é necessário? Qual é o propósito disso? E qual é a diferença entre os dois?
Por que todos os arquivos de script começam com
#!/bin/sh
ou com
#!/bin/csh
Isso é necessário? Qual é o propósito disso? E qual é a diferença entre os dois?
Respostas:
Isso é conhecido como Shebang:
http://en.wikipedia.org/wiki/Shebang_(Unix)
#! intérprete [opcional-arg]
Um shebang só é relevante quando um script tem permissão de execução (por exemplo, chmod u + x script.sh).
Quando um shell executa o script, ele usa o interpretador especificado.
Exemplo:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
A #!linha informa ao kernel (especificamente, a implementação da execvechamada do sistema) que este programa foi escrito em uma linguagem interpretada; o caminho absoluto que segue identifica o intérprete. Os programas compilados em código de máquina começam com uma sequência de bytes diferente - na maioria dos Unixes modernos, 7f 45 4c 46( ^?ELF) que os identifica como tal.
Você pode colocar um caminho absoluto para qualquer programa que desejar após o #!, desde que esse programa não seja um #!script. O kernel reescreve uma invocação de
./script arg1 arg2 arg3 ...
onde ./scriptcomeça com, digamos, #! /usr/bin/perlcomo se a linha de comando tivesse realmente sido
/usr/bin/perl ./script arg1 arg2 arg3
Ou, como você viu, você pode usar #! /bin/shpara escrever um script para ser interpretado por sh.
A #!linha só é processada se você invocar diretamente o script ( ./scriptna linha de comando); o arquivo também deve ser executável ( chmod +x script). Se você fizer isso, sh ./scripta #!linha não será necessária (e será ignorada se estiver presente), e o arquivo não precisa ser executável. O objetivo do recurso é permitir que você invoque diretamente programas em linguagem interpretada sem precisar saber em que idioma eles estão escritos. (Faça grep '^#!' /usr/bin/*- você descobrirá que muitos programas de estoque estão de fato usando esse recurso.)
Aqui estão algumas regras para usar este recurso:
#!devem ser os dois primeiros bytes do arquivo. Em particular, o arquivo deve estar em uma codificação compatível com ASCII (por exemplo, UTF-8 funcionará, mas UTF-16 não) e não deve começar com uma "marca de ordem de byte", ou o kernel não o reconhecerá como um #!roteiro.#!deve ser um caminho absoluto (começa com /). Não pode conter espaço, tabulação ou caracteres de nova linha.#!e o /. Não coloque mais de um espaço lá.#!linha, elas não serão expandidas.#! /usr/bin/awk -f), às vezes é apenas útil ( #! /usr/bin/perl -Tw). Infelizmente, você não pode colocar dois ou mais argumentos após o caminho absoluto.#! /usr/bin/env interpretervez de #! /absolute/path/to/interpreter. Isso quase sempre é um erro. Isso faz com que o comportamento do seu programa dependa da $PATHvariável do usuário que invoca o script. E nem todos os sistemas têm, envem primeiro lugar.setuidou setgidnão podem ser usados com privilégios #!; eles devem ser compilados em código de máquina. (Se você não sabe o que setuidé, não se preocupe com isso.)No cshque diz respeito , refere-se shaproximadamente a como o Substituto Avançado de Chá Nutrimat se refere ao chá. Ele tem (ou melhor, teve; as implementações modernas do shalcançaram) várias vantagens em relação shao uso interativo, mas usá-lo (ou seu descendente tcsh) para scripts é quase sempre um erro . Se você é novo no shell scripting em geral, recomendo fortemente que você ignore e se concentre em sh. Se você estiver usando um cshparente como shell de login, mude para bashou zsh, para que a linguagem de comando interativa seja a mesma que a linguagem de script que você está aprendendo.
#!; nenhum comentário sobre se é um bom estilo. Veja esta pergunta e minha resposta para uma discussão sobre os prós e contras do #!/usr/bin/envhack.
#!/usr/bin/envera a coisa certa, mas continua sendo minha opinião que quase sempre é uma má ideia.
Isso define qual shell (interpretador de comando) você está usando para interpretar / executar seu script. Cada shell é ligeiramente diferente na maneira como interage com o usuário e executa scripts (programas).
Quando você digita um comando no prompt do Unix, está interagindo com o shell.
Por exemplo, #!/bin/cshrefere-se ao C-shell, /bin/tcsho t-shell, /bin/basho bash shell, etc.
Você pode dizer qual shell interativo está usando o
echo $SHELL
comando, ou alternativamente
env | grep -i shell
Você pode alterar seu shell de comando com o chshcomando.
Cada um tem um conjunto de comandos ligeiramente diferente e uma maneira de atribuir variáveis e seu próprio conjunto de construções de programação. Por exemplo, a instrução if-else com bash parece diferente daquela no C-shell.
Esta página pode ser de interesse, pois "traduz" entre os comandos / sintaxe bash e tcsh.
Usar a diretiva no script de shell permite executar programas usando um shell diferente. Por exemplo, eu uso o tcshshell interativamente, mas geralmente executo scripts bash usando / bin / bash no arquivo de script.
A parte, de lado:
Este conceito se estende a outros scripts também. Por exemplo, se você programa em Python, você colocaria
#!/usr/bin/python
no topo do seu programa Python
#! $SHELL? Isso colocaria a concha correta no Shebang?
!#/bin/bashdiretiva , por exemplo . Diz ao sistema qual shell usar para executar seu script de shell.
$SHELLnão indica necessariamente qual shell você está executando no momento; normalmente mostra seu shell padrão . conjuntos tcsh $versione $tcsh; conjuntos bash $BASH_VERSION. Nem todas as conchas têm necessariamente mecanismos semelhantes.
#!linha deve corresponder à sintaxe do script, não ao shell interativo usado por quem está executando o script.
#!/bin/csh -f; o-fdiz ao shell para não fornecer o.logine.cshrc, o que torna o script executado mais rápido e evita dependências na configuração do usuário. (Ou melhor ainda, não escreva scripts csh.) Não use-fpara scripts sh ou bash; não tem o mesmo significado.