Mengapa kutipan diperlukan untuk argumen file saat memanggil skrip Bash ini?


13

Saya cukup baru dalam skrip Bash. Saya memiliki "skrip test", yang saya gunakan sebagai dasar untuk skrip yang lebih maju / berguna:

#!/bin/bash
files=$1
for a in $files
do
    echo "$a"
done

Ketika saya memanggil ini tanpa tanda kutip, itu hanya mengambil satu file di direktori:

testscript *.txt

Tetapi ketika saya menyebutnya dengan tanda kutip, ia bekerja dengan benar dan memilih semua file teks:

testscript '*.txt'

Apa yang terjadi disini?


Untuk menjadi sangat, sangat jelas, cara yang tepat untuk memperbaikinya adalah dengan menjalankan for a in "$@"; do(atau for a; do) dalam skrip Anda, sehingga meninggalkan globbing ke kulit terluar, bukan untuk meninggalkan tanda kutip.
Charles Duffy


Ini layak untuk dilihat. guide.bash.academy
vascowhite

Jawaban:


29

Saat Anda memanggil suatu program

testscript *.txt

maka shell Anda melakukan ekspansi dan menghitung semua nilai. Jadi mungkin, secara efektif memanggil program Anda sebagai

testscript file1.txt file2.txt file3.txt file4.txt

Sekarang program Anda hanya melihat $1dan hanya berfungsi file1.txt.

Dengan mengutip pada baris perintah Anda memberikan string literal *.txtke skrip, dan itulah yang disimpan $1. forLingkaran Anda lalu perluas.

Biasanya Anda akan menggunakan "$@"dan tidak $1dalam skrip seperti ini.

Ini adalah "gotcha" untuk orang-orang yang berasal dari skrip CMD, di mana shell perintah tidak melakukan globbing (seperti diketahui) dan selalu melewati string literal.


6
Hanya untuk memperjelas (bagi orang selain penulis jawaban di atas), menggunakan "$@"(sebagai lawan $@atau $1 $2 $3) akan menyebabkan setiap nama file dikutip "file1.txt" "file2.txt"dll. Untuk file1.txtini tidak ada artinya, tetapi jika Anda punya my file.txt, kutipan sangat penting untuk mencegah shell parsing untuk mengubahnya menjadi dua nama file, satu bernama mydan satu bernama file.txt. Selalu kutip input pengguna dan ekspansi glob agar Anda tidak bahagia suatu hari nanti.
Seth Robertson

2
Dan ini bukan hanya teori - Mac OS X pernah dikirim dengan skrip pembaruan yang tidak mengutip argumen dengan benar dan akhirnya menghapus hard drive orang dalam beberapa keadaan.
mengembang

2
@Fluffy, apakah Anda memiliki tautan tentang itu?
Wildcard

@ Kartu Memori Sayangnya saya tidak dapat menemukan artikel tentang itu, tapi itu adalah berita besar di dunia teknologi ketika itu terjadi. Saya ingin mengatakan itu pada 2003/2004 atau sekitar itu, kembali ketika Apple masih terbiasa menjadi distributor UNIX.
mengembang

1
@ kartu Ah, temukan! xlr8yourmac.com/OSX/itunes2_erased_drives.html - sebenarnya skrip upgrade iTunes yang menjadi penyebabnya.
mengembang

7

Tanpa tanda kutip shell mengembang *.txtsebelum menjalankan script, jadi $1hanya file pertama yang diperluas. Semua txtfile adalah argumen untuk skrip Anda pada saat itu (dengan asumsi tidak terlalu banyak).

Dengan kutipan bahwa string dilewatkan tanpa diperluas ke skrip, yang kemudian memungkinkan formelakukan ekspansi, seperti yang Anda harapkan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.