Stavo lavorando attraverso un tutorial e ho visto l'uso di entrambi cat myfile.txt
e cat < myfile.txt
. C'è una differenza tra queste due sequenze di comandi? Sembra sia stampare il contenuto di un file sulla shell.
Stavo lavorando attraverso un tutorial e ho visto l'uso di entrambi cat myfile.txt
e cat < myfile.txt
. C'è una differenza tra queste due sequenze di comandi? Sembra sia stampare il contenuto di un file sulla shell.
Risposte:
Nel primo caso, cat
apre il file e nel secondo caso, la shell apre il file, passandolo come cat
input standard.
Tecnicamente, potrebbero avere effetti diversi. Ad esempio, sarebbe possibile avere un'implementazione della shell che fosse più (o meno) privilegiata rispetto al cat
programma. Per quello scenario, uno potrebbe non riuscire ad aprire il file, mentre l'altro potrebbe.
Questo non è il solito scenario, ma menzionato per sottolineare che la shell e cat
non sono lo stesso programma.
sudo cat myfile.txt
. Ma sudo cat < myfile.txt
non funzionerà se non si dispone dei privilegi per leggere il file.
ksh93
ha cat
incorporato (non abilitato per impostazione predefinita a meno che non si abbia /opt/ast/bin
presto nel tuo $PATH
però).
wc
stamperà il nome file prima dei conteggi quando viene fornito un argomento.
Non ci sono grandi differenze visibili nel tuo caso di test. Il più ovvio sarebbe il messaggio di errore che ricevi se non ci sono file nominati myfile.txt
nella directory corrente o se non ti è permesso leggerlo.
Nel primo caso, cat
si lamenterà e nel secondo caso, la shell lo farà, mostrando chiaramente quale processo sta tentando di aprire il file, cat
nel primo e la shell nel secondo.
$ cat myfile.txt
cat: myfile.txt: No such file or directory
$ cat < myfile.txt
ksh93: myfile.txt: cannot open [No such file or directory]
In un caso più generale, una grande differenza sta nell'utilizzare i reindirizzamenti non può essere usato per stampare il contenuto di più di un file, che è dopo tutto lo scopo originale del comando cat
(ie cat enate). Si noti che la shell tenterà comunque di aprire tutti i file passati come input reindirizzato, ma in realtà passa solo l'ultimo a cat
meno che non si usi zsh
e il suo multios
"zshism".
$ echo one > one
$ echo two > two
$ cat one two # cat opens one, shows one, opens two, shows two
one
two
$ cat < one < two # sh opens one then opens two, cat shows stdin (two)
two
$ rm one two
$ echo one > one
$ cat one two # cat opens and shows one, fails to open two
one
cat: two: No such file or directory
$ cat < one < two # the shell opens one then opens two, fails and
# displays an error message, cat gets nothing on stdin
# so shows nothing
ksh93: two: cannot open [No such file or directory]
Su un sistema standard, la shell cat
non ha alcuna differenza nei diritti di accesso ai file, quindi entrambi avranno esito negativo allo stesso modo. L'uso sudo
di aumentare cat
i privilegi farà una grande differenza nel comportamento, come già suggerito da Thomas Dickey e dai commenti allegati.
ksh
tua volontà, e se sì ... perché ?
bash
, ksh93
è di gran lunga il guscio migliore. è il guscio, quasi.
cat myfile.txt
legge il file myfile.txt
quindi lo stampa sull'output standard.
cat < myfile.txt
qui cat
non viene dato alcun file da aprire, quindi, come molti comandi Unix, legge i dati dall'input standard, che viene diretto dalla file.txt
shell, e stampa sull'output standard.
La risposta di Thomas Dickey è geniale.
Voglio solo aggiungere alcuni fatti ovvi sul caso di leggere diversi file (vagamente correlati alla tua domanda, ma comunque):
cat <file1 <file2 <file3
leggerà solo file3, almeno in bash. (In realtà, dipende dalla shell, ma la maggior parte delle shell duplica ogni file specificato su stdin, il che fa sì che l'ultimo abbia effetto.)cat file1 file2 file3
leggerà tutti i file specificati in sequenza (in realtà cat è la forma abbreviata della parola concatenata ).cat file1 file2 file3 <file4 <file5 <file6
leggerà solo file1, file2, file3 (poiché cat ignora lo stdin quando vengono passati gli argomenti del nome file).
cat file1 file2 - file3 <file4 <file5 <file6
leggerà file1, file2, file6, file3 (poiché il trattino forza il gatto a non ignorare lo stdin).E sugli errori. In caso di impossibilità di aprire alcuni dei file specificati come argomenti (senza <
), cat salterà i file non riusciti (con l'output del messaggio rilevante su stderr), ma continuerà a leggere altri file. In caso di impossibilità di aprire almeno uno dei file specificati come reindirizzamenti (con <
), la shell non avvierà nemmeno cat (ciò si verifica anche per i reindirizzamenti effettivamente non utilizzati da cat). In entrambi i casi verrà restituito un codice di uscita errato.
cat
sarà comunque aperto file1
e file2
, lo stesso con file4
e file5
nel tuo terzo esempio. Mostrerà solo file3
, resp. file6
contenuti se queste precedenti istruzioni aperte hanno esito positivo.
possiamo usare un altro comando per notare la differenza tra:
wc –w food2.txt
.
Uscita possibile:
6 food2.txt
.
il comando dice il nome del file poiché lo conosce (passato come argomento).
wc –w < food2.txt
.
Uscita possibile:
6
.
l'input standard viene reindirizzato al file food2.txt senza che il comando lo sappia.