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 true
comando. 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 PATH
variá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
,, ksh
e mksh
o comportamento é consistente. Por exemplo, o /bin/sh
shell 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.trace
arquivo revela que csh
sai com o status de saída 0 (sem erros). Mas tcsh
gera 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 stderr
transmitir. 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 goto
instruçã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.com
e o Windows ' cmd.exe
tê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 COMMANDS
seçã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 ow
isso 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