Eu criei uma pasta em ~ / bin para colocar meus scripts de shell e colocá-la no meu $ PATH e também anexei uma Ação de Pasta à pasta ~ / bin para definir automaticamente as permissões de execução, porque é muito fácil esquecer isso.
Kaydell
Respostas:
22
Se você estiver executando seu script a partir do shell, na verdade não precisará do #!/bin/shshebang descrito nesta resposta - todo sistema semelhante ao Unix que usei, incluindo o OS X, será padronizado /bin/shse nenhum intérprete for especificado especificamente ( embora seja uma boa ideia, pois os não-shells não saberão como executar seu script, a menos que você dê o shebang.)
Você também não precisa de uma .shextensão. Você fazer necessidade de definir as permissões executáveis, por exemplo,
$ chmod +x script.sh
(O $prompt é o shell; estou usando-o para ilustrar os comandos que você fornece ao shell interativo. Não digite!)
No entanto, acho que sua confusão é que você criou um script, por exemplo script.sh, no diretório atual, e está tentando executá-lo simplesmente digitando script.sh. por exemplo
$ cat >script.sh
echo hello, world
^D
$ chmod +x script.sh
$ script.sh
-bash: script.sh: command not found
( ^Dsignifica control- D. Você encontrará essa notação em muitos artigos sobre o uso do Unix.)
O fato de script.sh, neste caso, ser um script de shell é apenas metade do problema; seu problema real é que, por padrão, o shell não pesquisará no diretório atual por um programa. No entanto, isso funciona:
$ sh script.sh
hello, world
porque shestá tomando o script como argumento.
Você pode executar um script - ou, novamente, qualquer executável - no diretório atual, se estiver marcado como executável (ou seja chmod +x), especificando que deseja executar o script no diretório atual:
$ ./script.sh
hello, world
Você também pode mover o script para um diretório no seu PATH. Eu recomendo /usr/local/binisso se o seu script se destina a ser usado em todo o sistema ou um bindiretório em sua casa, se o script for apenas para você. O último requer que você adicione $HOME/bin, o que se expande ao seu novo diretório bin, ao seu PATHadicionando as seguintes linhas ao seu .profileno seu diretório pessoal:
PATH=$HOME/bin:$PATH
export PATH
Por fim, você pode, se quiser, adicionar o diretório atual ao seu PATH, o que permitirá que você acesse um diretório que contenha script.sh–ou qualquer outro executável– e digite
$ script.sh
para executá-lo. No entanto, eu não recomendo esta prática , pois agora um invasor pode induzi-lo a executar um executável arbitrário soltando um script executável (nomeado, por exemplo ls) em um diretório em que você estará. Se você realmente deseja fazê-lo, basta adicionar o seguinte ao seu .profile:
Coloque o '.' no final de $ PATH, em vez de no começo, e agora você não precisa se preocupar com um fantasma 'ls'. (Embora se alguém pode entrar em seu sistema, você tem problemas maiores.)
TJ Luoma
2
@TJ, mas você não precisa se preocupar com coisas como slou llsou l... ou seja, erros de digitação. Apenas deixe de .fora $PATH. Além disso, você não pode (ou não deve) necessariamente confiar em todos no seu sistema. Por exemplo, suponha que haja alguma exploração que permita que um invasor solte um arquivo arbitrário em algum diretório, mas eles precisam que você execute esse arquivo para escalar para uma exploração melhor (por exemplo, coletar dados e telefonar para casa). Defesa em profundidade!
Reid
@TJLuoma O que o @Reid disse, além de ter em mente que existem muitos casos de uso para um sistema Unix além de um desktop OS X pessoal. Ainda não tentei, mas aposto que até a conta de convidado pode deixar um desses itens em /tmpalgum diretório gravável no mundo.
zigg
Se você estiver usando um sistema em que outras pessoas tenham acesso aos diretórios que você usa, você terá problemas maiores.
TJ Luoma
@TJLuoma É melhor você nunca usar várias contas em qualquer sistema Unix. /tmpet al. vem com o território.
zigg
10
Você não precisa ligar shse o arquivo de script estiver marcado como executável. Nesse caso, você pode chamá-lo de meu nome, como faria com qualquer outro comando do shell existente.
Para ser totalmente adequado, você deve fazer duas coisas:
Edite seu script para incluir uma diretiva shebang na parte superior do seu script:
#!/bin/sh
... Isso diria ao shell qual intérprete usar para executar o script; neste caso, o /bin/shexecutável.
Marque o script como executável por você com o comando chmod :
chmod u+x scriptname.sh
Depois de fazer os dois, você poderá executar seu script digitando o nome do arquivo do script na linha de comando. Você precisará estar no mesmo diretório do seu script, a menos que você também execute a etapa adicional de adicionar a pasta que contém sua variável PATH . Se você não se importa com o shell que executa o script, não precisa da etapa um para especificar, shmas geralmente é melhor ser preciso e definir o "shebangsh".
Shebangs não são realmente necessários /bin/sh, embora não machuquem.
zigg
@ zigg - Você está correto. Espero que Chris não se importe com minhas edições… Nuke ou
reedite
@bmike As edições funcionam para mim. Quanto aos shebangs, meu hábito era sempre especificar, porque eu costumava escrever muitos kshscripts nos meus dias no HP-UX - mas é bom saber que não é estritamente necessário.
Chris W. Rea
11
Acho que preciso me afastar da minha declaração anterior sobre a necessidade de shebang (embora o restante da minha resposta ainda permaneça.) Você pode executar um script sem shebang a partir de um shell, mas se você usar um execsyscall, obtém ENOEXEC(erro de formato exec ) Desculpe por isso, @bmike, @ ChrisW.Rea. Vou editar minha resposta agora.
Respostas:
Se você estiver executando seu script a partir do shell, na verdade não precisará do
#!/bin/sh
shebang descrito nesta resposta - todo sistema semelhante ao Unix que usei, incluindo o OS X, será padronizado/bin/sh
se nenhum intérprete for especificado especificamente ( embora seja uma boa ideia, pois os não-shells não saberão como executar seu script, a menos que você dê o shebang.)Você também não precisa de uma
.sh
extensão. Você fazer necessidade de definir as permissões executáveis, por exemplo,(O
$
prompt é o shell; estou usando-o para ilustrar os comandos que você fornece ao shell interativo. Não digite!)No entanto, acho que sua confusão é que você criou um script, por exemplo
script.sh
, no diretório atual, e está tentando executá-lo simplesmente digitandoscript.sh
. por exemplo(
^D
significa control- D. Você encontrará essa notação em muitos artigos sobre o uso do Unix.)O fato de
script.sh
, neste caso, ser um script de shell é apenas metade do problema; seu problema real é que, por padrão, o shell não pesquisará no diretório atual por um programa. No entanto, isso funciona:porque
sh
está tomando o script como argumento.Você pode executar um script - ou, novamente, qualquer executável - no diretório atual, se estiver marcado como executável (ou seja
chmod +x
), especificando que deseja executar o script no diretório atual:Você também pode mover o script para um diretório no seu
PATH
. Eu recomendo/usr/local/bin
isso se o seu script se destina a ser usado em todo o sistema ou umbin
diretório em sua casa, se o script for apenas para você. O último requer que você adicione$HOME/bin
, o que se expande ao seu novo diretório bin, ao seuPATH
adicionando as seguintes linhas ao seu.profile
no seu diretório pessoal:Por fim, você pode, se quiser, adicionar o diretório atual ao seu
PATH
, o que permitirá que você acesse um diretório que contenhascript.sh
–ou qualquer outro executável– e digitepara executá-lo. No entanto, eu não recomendo esta prática , pois agora um invasor pode induzi-lo a executar um executável arbitrário soltando um script executável (nomeado, por exemplo
ls
) em um diretório em que você estará. Se você realmente deseja fazê-lo, basta adicionar o seguinte ao seu.profile
:fonte
sl
oulls
oul
... ou seja, erros de digitação. Apenas deixe de.
fora$PATH
. Além disso, você não pode (ou não deve) necessariamente confiar em todos no seu sistema. Por exemplo, suponha que haja alguma exploração que permita que um invasor solte um arquivo arbitrário em algum diretório, mas eles precisam que você execute esse arquivo para escalar para uma exploração melhor (por exemplo, coletar dados e telefonar para casa). Defesa em profundidade!/tmp
algum diretório gravável no mundo./tmp
et al. vem com o território.Você não precisa ligar
sh
se o arquivo de script estiver marcado como executável. Nesse caso, você pode chamá-lo de meu nome, como faria com qualquer outro comando do shell existente.Para ser totalmente adequado, você deve fazer duas coisas:
Edite seu script para incluir uma diretiva shebang na parte superior do seu script:
#!/bin/sh
... Isso diria ao shell qual intérprete usar para executar o script; neste caso, o
/bin/sh
executável.Marque o script como executável por você com o comando chmod :
chmod u+x scriptname.sh
Depois de fazer os dois, você poderá executar seu script digitando o nome do arquivo do script na linha de comando. Você precisará estar no mesmo diretório do seu script, a menos que você também execute a etapa adicional de adicionar a pasta que contém sua variável PATH . Se você não se importa com o shell que executa o script, não precisa da etapa um para especificar,
sh
mas geralmente é melhor ser preciso e definir o "shebangsh".fonte
/bin/sh
, embora não machuquem.ksh
scripts nos meus dias no HP-UX - mas é bom saber que não é estritamente necessário.exec
syscall, obtémENOEXEC
(erro de formato exec ) Desculpe por isso, @bmike, @ ChrisW.Rea. Vou editar minha resposta agora.