Utilizzo del trattino (-) al posto di un nome file


110

Per un comando, se l'utilizzo -come argomento al posto del nome di un file significa STDIN o STDOUT.

  1. Ma in questo esempio, crea un file con il nome -:

    echo hello > -

    Come posso fare -in questo esempio dire STDOUT?

  2. Al contrario, come posso fare per -significare un file chiamato -in esempi come:

    cat -

3
Dal momento che apparentemente devo avere 50 reputazione per commentare direttamente ... Nel commento / dev / stdin / dev / stdout, AIX, che è un derivato UNIX legittimo, non ha questi pseudodispositivi. E, come ulteriore commento, LINUX non è in alcun modo un derivato UNIX. È un workalike conforme a POSIX, e il più popolare sistema operativo UNIX a questo punto, ma non commettere errori, questo non è UNIX. Ma l'essenza delle risposte qui è corretta. La notazione "-" non viene interpretata come speciale dalla shell e viene quindi passata direttamente ad ogni singola applicazione come un ARG. Se l'applicazione non viene riconosciuta

Ci sono anche 2>&-costruzioni, che significa "descrittore vicino 2".
user3132194

@ user95873, quello che suppongo tu volessi dire è: mentre Linux è simile a Unix, non tutti gli Unix (o veri UNIX) sono Linux . Il fatto che Linux sia o meno UNIX (ovvero conforme alla specifica UNIX singola) non ha relazione con / dev / std {in, out, err}. Come / dev / std {in, out, err} viene aggiunta la funzione, non mancante .
sasha,

Risposte:


156

Usare -come nome file per significare stdin / stdout è una convenzione che molti programmi usano. Non è una proprietà speciale del nome file. Il kernel non riconosce -come speciale, quindi qualsiasi chiamata di sistema che fa riferimento a -un nome file verrà utilizzata -letteralmente come nome file.

Con il reindirizzamento bash, -non viene riconosciuto come nome file speciale, quindi bash lo utilizzerà come nome file letterale.

Quando catvede la stringa -come un nome file, la tratta come sinonimo di stdin. Per ovviare a questo, è necessario modificare la stringa che catvede in modo tale da fare ancora riferimento a un file chiamato -. Il solito modo per farlo è quello di aggiungere il prefisso al nome del file con un percorso - ./-, o /home/Tim/-. Questa tecnica viene anche utilizzata per aggirare problemi simili in cui le opzioni della riga di comando si scontrano con i nomi dei file, quindi un file indicato come ./-enon appare come -eopzione della riga di comando di un programma, ad esempio.


37
Vale la pena aggiungerlo /dev/stdine /dev/stdoutsono universalmente disponibili e possono essere utilizzati al posto della -convenzione.
jmtd,

Anche nel catcaso, usare il reindirizzamento invece di elencare l'argomento potrebbe aiutare cat <-:; tuttavia, sarebbe difficile mescolarlo e abbinarlo a concatenare più di un file alla volta.
jmtd,

10
@jmtd: / dev / std {in, out} non sono universalmente disponibili. Non tutti gli unix ce l'hanno.
Camh,

2
Interessante, ho pensato che facessero parte di POSIX (ma non posso confermare). Sono presenti almeno su Linux, BSD e Solaris. Puoi fare un esempio di un moderno UNIX che manca di loro?
jmtd,

1
@camh Non sono sicuro se hai ricevuto la notifica, e questo è un argomento molto, molto vecchio; Non sono sicuro che tu possa, ma sono molto curioso di sapere la risposta alla jmtddomanda? :)
Girevolezza

18
  1. Invece di echo hello > -, puoi usare echo hello > /dev/stdout.

    Mentre '-' è una convenzione che deve essere implementata da ciascun programma che desidera supportarlo /dev/stdin, /dev/stdoute /dev/stderrsono, quando supportati dal sistema operativo (almeno Solaris, Linux e BSD), indipendente dall'applicazione e quindi funzionerà come te avere intenzione.


9

Come detto da Camh , -è solo una convenzione di denominazione utilizzata da alcuni programmi. Se vuoi fare riferimento a questi flussi con un descrittore di file che la shell riconoscerà, jiliagre ha ragione nel farti usare il nome /dev/stdino /dev/stdoutinvece. Quei nomi di file dovrebbero funzionare in qualsiasi posto in cui funzionerebbe un normale nome di file.

  1. Detto questo, il tuo primo esempio è un po 'sciocco. Qualsiasi output che verrebbe intercettato dall'operatore di reindirizzamento per scrivere su un file è già su output standard, quindi reindirizzarlo e riscriverlo da dove proviene è inutile. Il comportamento che usi lì è la pipe, non un reindirizzamento:

    echo hello |
  2. Nel tuo secondo esempio devi semplicemente dare qualche indicazione che vuoi un file di lettere con quel nome, non l'alias interno che ha. Puoi farlo più facilmente specificando un percorso al file come questo:

    cat ./-

6

Per quanto riguarda 1, il programma deve supportarlo. Non puoi semplicemente usarlo arbitrariamente. Come per 2, reindirizzare l'input da (ad es cat < -.).


1

L'approccio "-" presenta molti problemi. Innanzitutto richiede un'interpretazione del carattere "-" e molti programmi non eseguono tale interpretazione. Inoltre, ci sono alcuni programmi che interpretano un trattino come un delimitatore che segna la fine delle opzioni della riga di comando. I programmi sono scritti per funzionare con argomenti di nome file, l'approccio '-' è un hack, carino ma debole.

Il modo migliore è:

$ echo hello > /dev/fd/1

/dev/stdout è un link symbolik di /dev/fd/1


Il reindirizzamento viene interpretato dalla shell, non dal programma invocato.
Sherrellbc,
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.