Penggunaan tanda hubung (-) sebagai ganti nama file

110

Untuk suatu perintah, jika digunakan -sebagai argumen sebagai pengganti nama file berarti STDIN atau STDOUT.

  1. Namun dalam contoh ini, ia membuat file dengan nama -:

    echo hello > -

    Bagaimana saya bisa membuat -contoh ini berarti STDOUT?

  2. Sebaliknya, bagaimana saya bisa membuat -file berarti bernama -dalam contoh seperti:

    cat -
Tim
sumber
3
Karena saya rupanya harus memiliki 50 reputasi untuk berkomentar langsung ... Pada komentar / dev / stdin / dev / stdout, AIX, yang merupakan turunan UNIX yang sah tidak memiliki layanan pseudode ini. Dan, sebagai komentar lebih lanjut, LINUX bukanlah turunan UNIX dalam hal apa pun. Ini adalah workalike mirip POSIX, dan yang paling populer dari OS UNIX-ish pada saat ini, tetapi jangan salah, ini bukan UNIX. Tapi, inti dari balasan di sini benar. Notasi "-" tidak ditafsirkan sebagai istimewa oleh shell, dan dengan demikian diteruskan langsung ke setiap aplikasi sebagai ARG. Jika aplikasi tidak recogni
Ada juga 2>&-konstruksi, yang berarti "tutup keterangan 2".
user3132194
@ user95873, apa yang saya kira Anda ingin katakan adalah: sementara Linux adalah seperti Unix, tidak semua seperti Unix (atau UNIX sejati) adalah Linux . Masalah apakah Linux UNIX benar atau tidak (yaitu memenuhi Spesifikasi UNIX Tunggal) tidak memiliki hubungan dengan masalah / dev / std {in, out, err}. Ketika / dev / std {in, out, err} ditambahkan fitur, tidak ada yang hilang .
sasha

Jawaban:

156

Menggunakan -sebagai nama file berarti stdin / stdout adalah konvensi yang banyak digunakan program. Ini bukan properti khusus dari nama file. Kernel tidak mengenali -sebagai istimewa sehingga panggilan sistem apa pun yang merujuk -sebagai nama file akan digunakan -secara harfiah sebagai nama file.

Dengan pengalihan bash, -tidak dikenali sebagai nama file khusus, jadi bash akan menggunakannya sebagai nama file literal.

Ketika catmelihat string -sebagai nama file, itu memperlakukannya sebagai sinonim untuk stdin. Untuk menyiasatinya, Anda perlu mengubah string yang catmelihat sedemikian rupa sehingga masih merujuk ke file yang disebut -. Cara biasa untuk melakukan ini adalah dengan mengawali nama file dengan path - ./-, atau /home/Tim/-. Teknik ini juga digunakan untuk mengatasi masalah serupa di mana opsi baris perintah berbenturan dengan nama file, jadi file yang disebut sebagai ./-etidak muncul sebagai -eopsi baris perintah ke suatu program, misalnya.

camh
sumber
37
Perlu ditambahkan /dev/stdindan /dev/stdouttersedia secara universal dan dapat digunakan sebagai pengganti -konvensi.
jmtd
Juga dalam catkasus ini, menggunakan pengalihan bukannya daftar argumen mungkin membantu cat <-:; namun, akan sulit untuk mencampur dan mencocokkannya dengan menggabungkan lebih dari satu file sekaligus.
jmtd
10
@jmtd: / dev / std {in, out} tidak tersedia secara universal. Tidak semua unix memilikinya.
camh
2
Menarik, saya berasumsi mereka adalah bagian dari POSIX (tetapi tidak dapat mengkonfirmasi). Mereka hadir setidaknya di Linux, BSD dan Solaris. Bisakah Anda memberi contoh UNIX modern yang tidak memilikinya?
jmtd
1
@camh Tidak yakin apakah Anda mendapat pemberitahuan, dan ini adalah topik yang sangat, sangat lama; Saya tidak yakin apakah Anda bisa, tetapi saya sangat ingin tahu apakah Anda tahu jawaban jmtdatas pertanyaan itu? :)
Putar
18
  1. Alih-alih echo hello > -, Anda bisa menggunakan echo hello > /dev/stdout.

    Sementara '-' adalah konvensi yang harus dilaksanakan oleh setiap program yang ingin mendukungnya /dev/stdin,, /dev/stdoutdan /dev/stderr, ketika didukung oleh OS (setidaknya Solaris, Linux dan BSD lakukan), independen dari aplikasi dan kemudian akan berfungsi seperti yang Anda inginkan. berniat.

Jlliagre
sumber
9

Seperti yang disebutkan camh , -hanyalah konvensi penamaan yang digunakan oleh beberapa program. Jika Anda ingin merujuk ke stream ini dengan deskriptor file yang akan dikenali shell, jiliagre benar karena Anda menggunakan namanya /dev/stdinatau /dev/stdoutsebaliknya. Nama-nama file itu harus bekerja di mana saja nama file normal akan berfungsi.

  1. Yang sedang berkata, contoh pertama Anda agak konyol. Setiap output yang akan ditangkap oleh operator pengarah untuk menulis ke file sudah pada standar-output, jadi mengarahkan dan menulis kembali ke tempat asalnya tidak berguna. Perilaku yang Anda gunakan di sana adalah pipa, bukan redirect:

    echo hello |
  2. Dalam contoh kedua Anda, Anda hanya perlu memberikan beberapa indikasi bahwa Anda menginginkan file litteral dari nama itu, bukan alias internal yang dimilikinya. Anda dapat melakukan ini dengan termudah dengan menentukan jalur ke file seperti ini:

    cat ./-
Caleb
sumber
6

Adapun 1, program harus mendukungnya. Anda tidak bisa begitu saja menggunakannya secara sewenang-wenang. Adapun 2, mengarahkan input dari (misalnya, cat < -).

bahamat
sumber
1

Pendekatan '-' memiliki banyak masalah. Pertama-tama membutuhkan interpretasi karakter '-' dan banyak program tidak melakukan interpretasi seperti itu. Dan lebih jauh lagi, ada beberapa program yang menafsirkan tanda hubung sebagai pembatas menandai akhir opsi baris perintah. Program ditulis untuk bekerja dengan argumen nama file, pendekatan '-' adalah hack, bagus tapi lemah.

Cara terbaik adalah:

$ echo hello > /dev/fd/1

/dev/stdout adalah tautan simbolik dari /dev/fd/1

b3h3m0th
sumber
Pengalihan ditafsirkan oleh shell, bukan program yang dipanggil.
sherrellbc