Perché il messaggio di errore per due due punti come comando (: :) in bash ha tre punti, ma un singolo punto non fornisce alcun risultato?


Risposte:


40

La :shell integrata vs inesistente::

Il : guscio di comando integrato esiste (notare la differenza fra esterna e comandi incorporati ), che non fa nulla; restituisce solo successo, proprio come il truecomando. Il :built-in è standard e definito dallo standard POSIX , dove è anche noto come "null utility". Viene spesso utilizzato per i test o per l'esecuzione di loop infiniti come inwhile : ; do ...;done

bash-4.3$ type :
: is a shell builtin

Tuttavia, ::- due caratteri di due punti insieme - vengono interpretati come una "parola" nella shell e presuppone che sia un comando immesso dall'utente. La shell passerà attraverso il processo di controllo degli built-in, quindi qualsiasi directory nella PATHvariabile per l'esistenza di quel comando. Ma non esiste un :: comando incorporato né esterno ::. Pertanto, ciò produce un errore.

Bene, qual è un formato tipico per un errore?

<shell>: <command user typed>: error message

Pertanto, ciò che vedi non sono 3 punti, ma ciò che hai digitato incollato nel formato di errore standard.

Nota anche che :può accettare argomenti da riga di comando, vale a dire che è legale fare:

: :

In questo caso, la shell lo considererà come due "parole", una delle quali è un comando e l'altra un parametro posizionale. Anche questo non produrrà alcun errore! (Vedi anche la nota storica (più avanti in questa risposta) sull'uso di of :con parametri posizionali.)


In conchiglie diverse da bash

Si noti che la formattazione può variare anche tra shell diverse. Per bash, kshe mkshil comportamento è coerente. Ad esempio, la /bin/shshell predefinita di Ubuntu (che in realtà è /bin/dash):

$ dash
$ ::
dash: 1: ::: not found

dove 1 è il numero del comando (equivalente al numero di riga in uno script).

csh al contrario non produce alcun messaggio di errore:

$ csh
% ::
%

In effetti, se si esegue strace -o csh.trace csh -c ::, l'output di traccia nel csh.tracefile rivela che cshesce con lo stato di uscita 0 (nessun errore). Ma tcshgenera l'errore (senza emetterne il nome, però):

$ tcsh
localhost:~> ::
::: Command not found.

Messaggio di errore

In generale, il primo elemento nel messaggio di errore dovrebbe essere il processo o la funzione di esecuzione (la shell tenta di eseguire ::, quindi il messaggio di errore proviene dalla shell). Ad esempio, qui il processo di esecuzione è stat:

$ stat noexist
stat: cannot stat 'noexist': No such file or directory

Infatti, POSIX definisce la funzione perror () , che secondo la documentazione accetta un argomento stringa, quindi genera un messaggio di errore dopo i due punti e quindi newline. Citazione:

La funzione perror () deve mappare il numero di errore a cui si accede tramite il simbolo errno su un messaggio di errore dipendente dalla lingua, che deve essere scritto nel flusso di errore standard come segue:

  • Innanzitutto (se s non è un puntatore nullo e il carattere indicato da s non è il byte null), la stringa a cui fa riferimento s è seguita da due punti e da uno <spazio>.

  • Quindi una stringa di messaggio di errore seguita da una <nuova>.

E l'argomento stringa a perror()tecnicamente potrebbe essere qualsiasi cosa, ma ovviamente per chiarezza è in genere il nome della funzione o argv[0].

Al contrario, GNU ha il proprio set di funzioni e variabili per la gestione degli errori , che un programmatore può usare fprintf()per lo stderrstreaming. Come mostra uno degli esempi nella pagina collegata, si potrebbe fare qualcosa del genere:

  fprintf (stderr, "%s: Couldn't open file %s; %s\n",
           program_invocation_short_name, name, strerror (errno));

Nota storica

Nella vecchia shell Unix e Thompson, :veniva usato con la gotodichiarazione (che secondo l'utente chiamato Perderabo su questo thread non era una shell integrata). Citazione dal manuale:

L'intero file di comando viene cercato per una riga che inizia con un: come primo carattere non vuoto, seguito da uno o più spazi vuoti, quindi dall'etichetta. Se viene trovata una tale linea, goto riposiziona l'offset del file di comando sulla riga dopo l'etichetta ed esce. Questo fa sì che la shell si trasferisca sulla linea etichettata.

Quindi potresti fare qualcosa del genere per creare uno script loop infinito:

: repeat
echo "Hello World"
goto repeat

Errore di battitura "3 colonne" per "3 punti"
Barmar il

1
DOS command.come Windows ' cmd.exehanno una situazione simile ma opposta: :è esplicitamente un'etichetta goto (non un comando) e spesso riproposta come carattere di commento (ad es :: This is a comment.).
Grawity il

54

Gli ultimi due punti sono solo una parte del messaggio predefinito "non trovato":

$ x
x: command not found
$ ::
::: command not found

La ragione per cui un singolo colon non produce nulla è che : è un comando valido, sebbene non faccia nulla (tranne il ritorno TRUE). Dalla SHELL BUILTIN COMMANDSsezione di man bash:

   : [arguments]
          No effect; the command does nothing beyond  expanding  arguments
          and  performing any specified redirections.  A zero exit code is
          returned.

A volte lo vedrai in costruzioni come

while :
do
  something
done

Vedi per esempio A che cosa serve il colon incorporato?


sì, questo è il commento più completo .. molto più eloquente del mio .. molto meglio spiegato: D
John Orion

8

Prova qualsiasi altro comando inesistente e vedrai che :serve allo scopo normale in inglese:

$ ---
---: command not found

6

I due punti aggiunti fanno parte del messaggio di errore stesso. Se si digita, cd owne risulta uno bash: cd: ow: No such file or directory, il che dimostra che l'errore sta mettendo i due punti in più: No such file or directory


6
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

il terzo è un distanziatore dalla formattazione

in bash a :è un'istruzione vuota vuota


4

ottieni 3 due punti perché il formato dell'errore contiene due punti:

bash: <command>: command not found
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.