Mengapa mkdir gagal (tidak ada file atau direktori seperti itu) dalam skrip dengan BIN_DIR = “~ / bin /”?

Jawaban:

11

Pesan kesalahan dihasilkan karena tilde ~dikutip, seperti yang dijelaskan dalam jawaban Zanna . Jika Anda ingin menggunakan ~, bagian skrip yang relevan adalah:

BIN_DIR=~/bin/

Jika karena alasan apa pun Anda ingin mengutip string, Anda dapat menggunakan variabel lingkungan $HOME:

BIN_DIR="$HOME/bin/"

Menurut saya pendekatan kedua adalah praktik yang lebih baik.

pa4080
sumber
6
Tidak ada yang salah dengan menggunakan ~skrip. ini bekerja dengan cara yang persis sama seperti pada baris perintah. Masalahnya adalah bahwa mengutip memblokir ekspansi tilde seperti yang dijelaskan dalam jawaban Zanna .
terdon
@terdon, saya setuju. Tapi saya belum bilang ada yang salah, tapi itu ide yang lebih baik, karena Anda harus kurang memperhatikan.
pa4080
5
Tapi sama sekali tidak ada perbedaan antara baris perintah dan skrip di sini. Fakta bahwa ini ada dalam naskah sama sekali tidak relevan, Anda akan memiliki kesalahan yang sama persis di baris perintah. Masalahnya adalah mengutip, bukan dalam skrip.
terdon
Meskipun itu sepenuhnya benar, benar juga bahwa menggunakan $HOMEskrip adalah ide yang bagus.
hidangan penutup
3
@ pa4080 Bisakah Anda menambahkan penjelasan mengapa menurut Anda lebih baik memperluas $HOMEdaripada menggunakan ekspansi tilde? Satu-satunya penjelasan yang Anda berikan adalah mengatakan, "itu adalah ide yang lebih baik, karena Anda harus kurang memperhatikan." Saya tidak tahu apa artinya itu. Bisakah Anda menjelaskannya secara sunting? Tanpanya, tidak ada yang mendukung jawaban Anda, jadi sudah pasti jawabannya. Perluasan Tilde telah dibutuhkan oleh POSIX untuk beberapa saat sekarang dan baris hashbang script #!/bin/bashjadi saya kira portabilitas bukan alasannya.
Eliah Kagan
23

Tidak berfungsi karena ~dikutip. Kutipan ganda " menekan ekspansi tilde . Tidak ada direktori dengan nama literal ~/bin. Seperti yang dijelaskan dalam man bash(penekanan saya):

Ekspansi Tilde

Jika sebuah kata diawali dengan karakter tilde yang tidak dikutip (`~ '), semua karakter yang mendahului slash tanpa tanda kutip pertama (atau semua karakter, jika tidak ada slash yang tidak dikutip) dianggap sebagai awalan tilde. Jika tidak ada karakter dalam awalan tilde yang dikutip, karakter dalam awalan tilde yang mengikuti tilde diperlakukan sebagai nama login yang memungkinkan. Jika nama login ini adalah string nol, tilde diganti dengan nilai parameter shell HOME. Jika HOME tidak disetel, direktori home dari pengguna yang menjalankan shell diganti. Jika tidak, awalan tilde diganti dengan direktori home yang dikaitkan dengan nama login yang ditentukan.

Anda dapat menghapus tanda kutip , karena ~hanya karakter di jalur ~/binyang akan menyebabkan shell melakukan ekspansi, dan kami ingin ekspansi dalam kasus ini. Shell tidak akan melakukan apa pun perluasan lebih lanjut pada hasil ekspansi tilde, setidaknya di Bash 4 , yang semua rilis saat ini atau jarak jauh terbaru dari Ubuntu memiliki . Jadi, bahkan jika direktori home Anda mengandung karakter yang tidak biasa seperti spasi, tidak apa-apa.

Atau Anda dapat menggunakan $HOMEbukan dari ~, karena ekspansi parameter tidak ditekan oleh tanda kutip ganda, hanya dengan tanda kutip tunggal . Tanda kutip ganda jangan memastikan bahwa nilai diperluas tidak sendiri tunduk pada perluasan lebih lanjut, sehingga kata membelah atau ekspansi nama file tidak akan terjadi. Jadi, $HOMEbekerja bahkan dengan direktori home dengan nama aneh juga, asalkan Anda menyimpan tanda kutip ganda.

Zanna
sumber
Menurut pernyataan ini "ekspansi parameter tidak ditekan oleh tanda kutip ganda, hanya dengan tanda kutip tunggal" : output dari cd '~'adalah -bash: cd: ~: No such file or directory.
pa4080
2
@ pa4080 Ekspansi ~bukan bagian dari ekspansi parameter.
Barmar