Katakanlah saya ingin menyimpan perintah berikut dalam sebuah variabel
cd "/cygdrive/c/Program Files/"
Jadi saya melakukan ini
dir="cd \"/cygdrive/c/Program Files/\""
Itu seharusnya menyimpan perintah untuk menavigasi ke direktori Program Files, jadi ketika saya mengetik $ dir itu membawa saya ke direktori itu. Untuk memeriksa apakah kutipan telah lolos dengan benar, saya mengetik
echo $dir
yang memberi saya
cd "/cygdrive/c/Program Files/"
Jadi semuanya harus bekerja dengan baik. Namun, saat saya mengetik,
$dir
saya mendapat
bash: cd: "/cygdrive/c/Program: No such file or directory
Apa yang saya lakukan salah? Saya menggunakan Cygwin, tetapi saya menganggap masalah ini berlaku untuk bash secara umum.
Jawaban:
Jawaban singkat: lihat BashFAQ # 050 ("Saya mencoba menempatkan perintah dalam variabel, tetapi kasus kompleks selalu gagal!").
Jawaban panjang: ketika bash mem-parsing sebuah perintah, ia mem-parsing tanda kutip sebelum ia menggantikan variabel; itu tidak pernah kembali dan mem-parsing tanda kutip dalam nilai-nilai variabel, sehingga mereka akhirnya tidak melakukan sesuatu yang berguna. Menggunakan gema untuk memeriksa perintah benar-benar menyesatkan karena itu menunjukkan perintah setelah diuraikan; jika Anda ingin melihat apa yang sebenarnya dieksekusi, gunakan
set -x
perintah print shell saat dieksekusi, atau gunakanprintf "%q " $dir; echo
sebagai ganti gema biasa.Jika Anda ingin menyimpan perintah yang kompleks (mis. Yang memiliki spasi atau karakter khusus lainnya di "kata"), Anda harus meletakkannya dalam array bukan variabel teks sederhana, dan kemudian perluas dengan idiom `" $ { array [@]} ", seperti ini:
Sekarang, jika tujuannya adalah untuk membuat steno yang mudah diketik, ini jelas bukan cara yang tepat. Gunakan alias shell atau fungsi sebagai gantinya:
atau
sumber
Ketika bash mengembang
$dir
, itu hanya melakukan pemisahan kata dan penggumpalan di atasnya. Kata membelah menghasilkan tiga kata:cd
,"/cygdrive/c/Program
danFiles/"
. Maka perintah untuk mengeksekusi adalahcd
dengan dua argumen;cd
hanya melihat argumen pertamanya"/cygdrive/c/Program
,, yang bukan direktori yang ada.Jika Anda ingin melakukan evaluasi shell penuh pada konten variabel, gunakan
eval
:Perhatikan bahwa Anda memerlukan tanda kutip ganda di sekitar
$dir
, jika tidak, pemisahan kata pertama-tama akan dilakukan, kemudianeval
akan menggabungkan argumennya dengan spasi. Ini akan terjadi untuk bekerja di sini, tetapi akan memburuk secara umum (misalnya jika ada dua spasi berturut-turut dalam nama file).Namun, string bukan cara yang tepat untuk menyimpan perintah shell yang ingin Anda jalankan. Kecuali Anda memiliki persyaratan yang tidak biasa, Anda harus menggunakan fungsi sebagai gantinya:
Jika Anda benar-benar tertarik dalam mengetik
$dir
untuk beralih ke direktori tertentu dan ini bukan hanya sebuah contoh sederhana, karena pesta 4, dimasukkanshopt -s autocd
dalam Anda.bashrc
set dansetelah itu Anda bisa mengetikkan saja
"/cygdrive/c/Program Files/"
atau"$dir"
pada prompt shell untuk beralih ke direktori itu. Anda masih membutuhkan tanda kutip ganda di sekitar$dir
; jika Anda tidak suka itu, gunakan zsh bukannya bash.sumber
Menyimpan perintah dalam variabel umumnya bukan ide yang baik. Itulah fungsi dan alias untuk apa.
Daripada
coba salah satu dari ini:
atau
atau
Bentuk pertama, menyimpan nama direktori dalam variabel, berarti mengetik lebih sedikit, tetapi lebih jelas ketika Anda menjalankan perintah yang Anda lakukan
cd
. Yang kedua paling dekat dengan apa yang ingin Anda capai. (Saya tidak menggunakan alias banyak di bash; Saya tidak benar-benar yakin apa kelebihan mereka daripada fungsi.)EDIT:
Dan
dir
mungkin nama yang buruk untuk alias atau fungsi, karena ada perintah yang ada dengan nama itu (itu pada dasarnya adalah versils
, setidaknya jika Anda memiliki GNU coreutils).sumber
Storing commands in variables is generally not a good idea. That's what functions and aliases are for.
Mencoba
Tetapi lebih khusus lagi:
/programming/4334467/cygwin-using-a-path-variable-containing-a-windows-path-with-a-space-in-it
sumber