Se eu digitar
::
em um shell bash, recebo:
-bash: ::: command not found
Mas, apenas um :resulta em nenhuma saída. Por que é isso?
Se eu digitar
::
em um shell bash, recebo:
-bash: ::: command not found
Mas, apenas um :resulta em nenhuma saída. Por que é isso?
Respostas:
:shell embutido vs inexistente::O : comando interno do shell existe (observe a diferença entre comandos externos e internos ) que não faz nada; apenas retorna sucesso, assim como o truecomando. O :built-in é padrão e definido pelo padrão POSIX , onde também é conhecido como "utilitário nulo". É freqüentemente usado para testar ou executar loops infinitos, como emwhile : ; do ...;done
bash-4.3$ type :
: is a shell builtin
No entanto, ::- dois caracteres de dois pontos juntos - são interpretados como uma "palavra" no shell e supõe ser um comando digitado pelo usuário. O shell passará pelo processo de verificação de built-ins e, em seguida, qualquer diretório na PATHvariável para a existência desse comando. Mas não existe um :: comando interno nem externo ::. Portanto, isso produz um erro.
Bem, qual é o formato típico para um erro?
<shell>: <command user typed>: error message
Portanto, o que você vê não são três pontos, mas o que você digitou colou no formato de erro padrão.
Observe também que isso :pode receber argumentos de linha de comando, ou seja, é legal fazer:
: :
Nesse caso, o shell considerará isso como duas "palavras", uma das quais é um comando e a outra um parâmetro posicional. Isso também não produzirá nenhum erro! (Veja também a nota histórica (mais adiante nesta resposta) sobre o uso de :com parâmetros posicionais.)
Observe que a formatação também pode variar entre diferentes shells. Para bash,, kshe mksho comportamento é consistente. Por exemplo, o /bin/shshell padrão do Ubuntu (que é realmente /bin/dash):
$ dash
$ ::
dash: 1: ::: not found
onde 1 é o número do comando (equivalente ao número da linha em um script).
csh por outro lado, não produz nenhuma mensagem de erro:
$ csh
% ::
%
De fato, se você executar strace -o csh.trace csh -c ::, a saída de rastreamento no csh.tracearquivo revela que cshsai com o status de saída 0 (sem erros). Mas tcshgera o erro (sem exibir seu nome):
$ tcsh
localhost:~> ::
::: Command not found.
Em geral, o primeiro item na mensagem de erro deve ser o processo ou função em execução (seu shell tenta executar ::, portanto, a mensagem de erro vem do shell). Por exemplo, aqui o processo de execução é stat:
$ stat noexist
stat: cannot stat 'noexist': No such file or directory
De fato, o POSIX define a função perror () , que, de acordo com a documentação, utiliza um argumento de seqüência de caracteres, emite uma mensagem de erro após dois pontos e, em seguida, nova linha. Citar:
A função perror () deve mapear o número do erro acessado através do símbolo errno para uma mensagem de erro dependente do idioma, que deve ser gravada no fluxo de erros padrão da seguinte maneira:
Primeiro (se s não for um ponteiro nulo e o caractere apontado por s não for o byte nulo), a cadeia de caracteres apontada por s seguida por dois pontos e um <espaço>.
Em seguida, uma sequência de mensagens de erro seguida por um <newline>.
E o argumento da cadeia de caracteres para perror()tecnicamente pode ser qualquer coisa, mas é claro, para maior clareza, normalmente é o nome da função ou argv[0].
Por outro lado, o GNU possui seu próprio conjunto de funções e variáveis para tratamento de erros , com as quais um programador pode usar fprintf()para stderrtransmitir. Como mostra um dos exemplos na página vinculada, algo como isto pode ser feito:
fprintf (stderr, "%s: Couldn't open file %s; %s\n",
program_invocation_short_name, name, strerror (errno));
No antigo Unix e Thompson, o shell :era usado com a gotoinstrução (que, de acordo com o usuário chamado Perderabo neste segmento, não era um shell interno ). Citação do manual:
O arquivo de comando inteiro é procurado por uma linha que começa com a: como o primeiro caractere não em branco, seguido por um ou mais espaços em branco e, em seguida, o rótulo. Se essa linha for encontrada, goto reposiciona o deslocamento do arquivo de comando para a linha após o rótulo e sai. Isso faz com que o shell seja transferido para a linha rotulada.
Então você pode fazer algo assim para criar um script de loop infinito:
: repeat
echo "Hello World"
goto repeat
command.come o Windows ' cmd.exetêm uma situação semelhante, mas oposta: :é explicitamente um rótulo de goto (não um comando) e é frequentemente redirecionado como um caractere de comentário (por exemplo :: This is a comment).
Os últimos dois pontos são apenas parte da mensagem padrão "não encontrado":
$ x
x: command not found
$ ::
::: command not found
A razão pela qual um único dois pontos não produz nada é que : é um comando válido - embora não faça nada (exceto retornar TRUE). Na SHELL BUILTIN COMMANDSseção de man bash:
: [arguments]
No effect; the command does nothing beyond expanding arguments
and performing any specified redirections. A zero exit code is
returned.
Você às vezes verá isso em construções como
while :
do
something
done
Veja, por exemplo, a que finalidade serve o cólon incorporado?
Os dois pontos adicionados fazem parte da própria mensagem de erro. Se alguém digitar cd owisso resulta bash: cd: ow: No such file or directory, o que mostra que o erro está colocando dois pontos extras: No such file or directory
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found
o terceiro é um espaçador da formatação
no bash a :é uma instrução de linha vazia