Como o arquivo não é de nenhum dos tipos de executáveis reconhecidos pelo sistema e, assumindo que você tem permissão para executá-lo, a execve()chamada do sistema normalmente falhará com um erro ENOEXEC( não executável ).
O que acontece então depende da aplicação e / ou função da biblioteca usada para executar o comando.
Pode ser, por exemplo, um shell, a função execlp()/ execvp()libc.
A maioria dos outros aplicativos usará um deles quando executar um comando. Eles invocam um shell, por exemplo, por meio da system("command line")função libc, que normalmente invoca shpara analisar essa linha de comando (cujo caminho pode ser determinado em tempo de compilação (como /bin/shvs /usr/xpg4/bin/shno Solaris)), ou invoca o shell armazenado $SHELLpor eles mesmos, como vicom seu !comando ou com xterm -e 'command line'muitos outros comandos ( su user -cinvocará o shell de login do usuário em vez de $SHELL).
Geralmente, um arquivo de texto sem shebang que não inicia #é considerado como um shscript. Qual shé o que irá variar embora.
execlp()/ execvp(), ao execve()retornar ENOEXEC, normalmente o invocará sh. Para sistemas que possuem mais de um, shporque podem estar em conformidade com mais de um padrão, o que shnormalmente será determinado no momento da compilação (do aplicativo usando execvp()/ execlp()vinculando um blob diferente de código que se refere a um caminho diferente para sh). Por exemplo, no Solaris, isso será /usr/xpg4/bin/sh(um padrão, POSIX sh) ou /bin/sh(o shell Bourne (um shell antiquado) no Solaris 10 e mais antigo, ksh93 no Solaris 11).
Quando se trata de conchas, há muita variação. bash, AT&T ksh, o shell Bourne normalmente interpreta o próprio script (em um processo filho, a menos que execseja usado) depois de simular a execve(), que está desmarcada todas as variáveis não exportadas, fechou todos os fds de execução imediata, removeu todas as traps personalizadas, aliases, funções ... ( bashinterpretará o script no shmodo). yashse executará (com sho argv[0]modo no shmodo) para interpretá-lo.
zsh, pdksh, ashConchas baseados irá tipicamente invocar sh(o caminho de que determinado no momento da compilação).
Para cshe tcsh(e o shde alguns BSDs iniciais), se o primeiro caractere do arquivo for #, eles se executarão para interpretá-lo e de shoutra forma. Isso remonta a um período pré-shebang, onde cshele reconheceu #como comentários, mas não o shell Bourne, então #havia uma dica de que era um script csh.
fish(pelo menos versão 2.4.0), apenas retorna um erro se execve()falhar (ele não tenta tratá-lo como um script).
Alguns shells (como a bashAT&T ksh) primeiro tentarão determinar heuristicamente se o arquivo provavelmente deve ser um script ou não. Portanto, você pode achar que alguns shells se recusam a executar um script se ele tiver um caractere NUL nos primeiros bytes.
Observe também que, se houver execve()falha no ENOEXEC, mas o arquivo tiver uma linha shebang, alguns shells tentarão interpretar essa linha shebang.
Então, alguns exemplos:
- Quando
$SHELLestiver /bin/bash, xterm -e 'myscript with args'terá myscriptinterpretado por bashno shmodo. Enquanto estiver com xterm -e myscript with args, xtermusará execvp()para que o script seja interpretado por sh.
su -c myscriptno Solaris 10, onde rooto shell de logon é /bin/she /bin/shé o shell Bourne terá sido myscriptinterpretado pelo shell Bourne.
/usr/xpg4/bin/awk 'BEGIN{system("myscript")'no Solaris 10, ele será interpretado por /usr/xpg4/bin/sh(o mesmo para /usr/xpg4/bin/env myscript).
find . -prune -exec myscript {} \;no Solaris 10 (usando execvp()), ele será interpretado por /bin/sheven with /usr/xpg4/bin/find, mesmo em um ambiente POSIX (um erro de conformidade).
csh -c myscriptterá interpretado por cshse começa com #, com o shcontrário.
Em suma, você não pode ter certeza de qual shell será usado para interpretar esse script se você não souber como e pelo que será chamado.
De qualquer forma, read -pé bashapenas uma sintaxe, portanto, você deve garantir que o script seja interpretado por bash(e evitar essa .shextensão enganosa ). Você conhece o caminho do bashexecutável e usa:
#! /path/to/bash -
read -p ...
Ou você pode tentar confiar na $PATHpesquisa do bashexecutável (supondo que bashesteja instalado) usando:
#! /usr/bin/env bash
read -p ...
( envé quase onipresente encontrado em /usr/bin). Como alternativa, você pode torná-lo compatível com POSIX + Bourne e, nesse caso, você pode usá-lo /bin/sh. Todos os sistemas terão a /bin/sh. Na maioria deles, é (na maior parte) compatível com POSIX, mas você ainda pode encontrar de vez em quando um shell Bourne lá.
#! /bin/sh -
printf >&2 'Enter a user name: '
read user
printf '%s\n' "$user"