Siapa yang berurusan dengan bintang * dalam gema *

15

Siapa yang berurusan (menafsirkan) * in

echo *

Apakah gema melihat bintang atau shell merawatnya dan mengembalikan daftar nama file ..

Bagaimana dengan

cp temp temp*
faressoft
sumber
14
Bervariasi. Kerang Unix atau kerang Windows?
user1686
@grawity Unix shells. Maaf saya tidak menyebutkan itu.
faressoft
Untuk Unix, jawaban di bawah ini benar. (Pada Windows, ini dilakukan oleh program individual - meskipun biasanya secara otomatis oleh pustaka runtime sebelum main ().)
user1686

Jawaban:

24

bash (atau apa pun yang Anda gunakan sebagai shell), adalah hal pertama yang membaca input apa pun, dan akan mulai menafsirkan karakter khusus seperti ?dan *. *akan diperluas ke pertandingan apa pun dalam CWD , yang berarti bahwa tanda bintang diganti dengan pertandingan tersebut.

Dalam kebanyakan kasus, ini cukup maju, tetapi dapat menyebabkan beberapa kasus membingungkan dari waktu ke waktu.

Pertimbangkan yang berikut ini. Direktori memiliki konten ini:

  • test (file biasa)
  • test1 (direktori)
  • test2 (direktori)
  • test3 (direktori)

Jika Anda mengetik mv *sesuatu yang tampaknya aneh terjadi: test3ada di sana, tetapi sisanya hilang. Meski aneh pada awalnya, masuk akal setelah Anda memahami apa yang sebenarnya dilewati bash mv. Karena asterisk, bash mengartikan mv *sebagai mv test test1 test2 test3, dan ketika saya mendapatkan daftar itu, itu akan menganggap bahwa argumen terakhir adalah tujuan, yang mana semua file akan dipindahkan.

Adapun perintah yang Anda daftarkan:

  • echo *bisa berfungsi sebagai orang miskin ls. Shell akan memperluas tanda bintang ke apa pun yang ada di direktori itu, dan seperti yang saya yakin Anda sudah tahu, echosecara harfiah hanya akan menggemakan bash apa pun yang diteruskan ke bash sebagai argumen.
  • cp temp temp*akan berperilaku agak seperti mvperintah yang saya jelaskan di atas, kecuali hanya ada satu direktori bernama temp, di mana sumber dan nama tujuan sama, yaitu tidak akan melakukan apa-apa.
Jarmund
sumber
8
Tidak ada yang "miskin" tentang menggunakan *bukan ls. Sebagai contoh, for f in *; doadalah lebih dapat diandalkan dibandingkan for f in $(ls)jika nama file mengandung spasi atau karakter gumpal. (Akan tetapi, gagal jika tidak ada file di CWD, jadi Anda perlu memeriksa kasus itu.)
rici
1
@rici Itulah gunanya shopt nullglob.
CVn
3
Adapun echo *trik itu dapat menyelamatkan Anda dalam beberapa kasus.
CVn
2
Menyambung dengan: file yang diawali dengan "-" di folder sewenang-wenang yang memicu sakelar yang tidak diinginkan. Menghapusnya tidak terlalu menyenangkan sampai Anda menyadari bahwa rm ./-stupidfile berfungsi.
ǝɲǝɲbρɯͽ
1
@ ǝɲǝɲbρɯͽ Saya perhatikan ketika saya perlu menghapus isi direktori yang berisi file dengan nama file yang mewakili posisi dalam sistem koordinat, dari -1024x-1024 hingga 1024x1024. Saat itulah saya pertama kali belajar melarikan diri.
Jarmund
5

Seperti yang telah dinyatakan, shell mengembang *sehingga echomenerima sebagai argumen apapun shell menemukan di direktori saat ini. Namun, perhatikan bahwa jika ekspansi tidak menghasilkan apa-apa, yaitu dalam kasus itu jika direktori tidak berisi file yang tidak disembunyikan, maka *dibiarkan tidak berubah dan diteruskan sebagaimana perintah yang dipanggil (kecuali opsi non standar digunakan dengan beberapa shell seperti bash.) echo *tidak kemudian akan berperilaku seperti orang miskin lskarena yang pertama tidak akan mencetak apa-apa sementara yang kedua akan mencetak *.

Demikian pula, cp /tmp/temp temp*akan membuat file bernama temp*di direktori saat ini jika belum ada setidaknya satu file yang namanya dimulai temp.

Akhirnya, jika Anda ingin *agar tidak terjadi perubahan apa pun yang terjadi, Anda dapat melindunginya dari ekspansi baik menggunakan tanda kutip tunggal '*', tanda kutip ganda "*"atau garis miring terbalik \*.

Jlliagre
sumber
4

Di Bash, shell berurusan dengannya. Anda melihat bahwa jika Anda bahkan mencoba *tanpa gema

Catatan- berdasarkan beberapa komentar, saya akan menyarankan ketika menjalankan * ENTER, untuk membuat direktori dan menggunakan perintah sentuh untuk membuat beberapa file, dan pastikan tidak ada satu pun, atau setidaknya pastikan yang pertama secara alfabet, bukan nama skrip atau perintah apa pun di jalur.

$ *
bash: a: command not found

$ echo *
a a.aa a.ab a.b a.htm a.tx

Begitu ls *juga sedikit klise

Di Windows, *ditangani oleh perintah, jadi dir *.*bukan klise.

Catatan - Melihat beberapa komentar, saya akan menambahkan, ada risiko berjalan * kemudian ENTER. Jika Anda memiliki file bernama rm yang pertama dalam daftar direktori, maka itu berbahaya karena apa pun setelah itu akan dihapus. Juga, dan ini lebih kecil kemungkinannya, jika file pertama dalam daftar direktori adalah nama skrip di path, maka itu akan menjalankannya.

barlop
sumber
4
Catatan mungkin ada file yang bernama rm, tentu saja.
Volker Siegel
1
... dan satu lagi bernama -rf
ǝɲǝɲbρɯͽ
1
@ ǝɲǝɲbρɯͽ dapatkah Anda memiliki file dengan nama file -rf? Saya mencoba touch -rfdan touch \-rftetapi tidak membuatnya.
barlop
@barlop saya berkomentar di atas; gui (seperti gedit) menangani mereka dengan baik, tetapi karena shell (setidaknya bash) melewati ini membutuhkan ./ di depan. Jika Anda secara tidak sengaja membuat file seperti itu, rm mencoba memberi petunjuk, tetapi jika tidak: Saya harap ini hanya berakhir di folder temp dengan anak-anak sekali pakai.
ǝɲǝɲbρɯͽ
@ ǝɲǝɲbρɯͽ Saya sama sekali tidak mengerti maksud Anda, saya bertanya bagaimana Anda bisa membuat file yang dinamai -rf? (Saya mengerti bahaya dari sebuah file bernama rm dan sebuah file bernama -rf, dan masalah mengetik * dan mendorong masuk ke folder penting, saya tidak berencana untuk melakukan itu)
barlop
-1

Shell melakukan beberapa ekspansi sebelum argumen diserahkan ke perintah.

Lihat juga https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion

Tidak khusus untuk bash, lihat http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01

glenn jackman
sumber
Secara teknis apa yang Anda tulis benar, tetapi tanpa tautan, jawaban ini tidak benar-benar melakukan apa pun untuk menjawab pertanyaan. Pertimbangkan untuk memasukkan perincian yang relevan.
CVn
@ MichaelKjörling Saya setuju dengan hal tentang tautan, tetapi OP hanya bertanya apakah shell atau perintah itu sendiri menangani argumen. Jawaban Glenn hanya menyatakan bahwa shell menanganinya, jadi itu adalah jawaban yang dapat diterima untuk pertanyaan itu.
slhck
@ slhck Itulah sebabnya saya tidak menandai sebagai NAA: ada sesuatu yang tersisa yang menjawab pertanyaan setelah menelanjangi tautan. Itu tidak berarti ini menurut saya jawaban yang bagus . (Saya sekarang melihat bahwa komentar awal saya dapat ditafsirkan sebaliknya; untuk itu, saya minta maaf, tapi saya masih berpikir itu memiliki nilai yang cukup untuk membiarkannya di tempat itu.)
a CVn
@ MichaelKjörling Setuju. Saya baru saja meninggalkan komentar untuk mereka yang melakukan (dan akan) menandainya sebagai NAA.
slhck