Diberikan potongan pesta ini:
PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo $PARMS
rsync ${PARMS} . ${TARGET}
Gema menunjukkan string PARMS seperti yang diharapkan, tidak ada kesalahan yang ditampilkan, tetapi rsync diam-diam bertindak seolah-olah opsi yang ditambahkan oleh + = tidak ada. Namun, ini berfungsi seperti yang diharapkan:
PARMS='-rvu'
rsync ${PARMS} --delete --exclude='.git' . ${TARGET}
Saya kira saya mengacaukan sesuatu dengan tanda kutip (selalu memiliki masalah dengan itu), tetapi tidak yakin apa dan mengapa opsi diabaikan meskipun string tampaknya telah dibangun dengan benar.
echo "$PARMS"
danrsync "${PARMS}"
...bash
versi 4.2.25 tanpa perubahan apa pun.Jawaban:
Ada perbedaan antara:
dan
Dalam yang pertama, tanda kutip tunggal berada di dalam tanda kutip itu sendiri, sehingga mereka secara harfiah hadir dalam teks pengganti yang diberikan
rsync
sebagai argumen.rsync
mendapat argumen yang nilainya--exclude='.git'
. Pada yang kedua, tanda kutip tunggal ditafsirkan oleh shell pada saat mereka ditulis, karena mereka tidak berada di dalam tanda kutip sendiri, danrsync
bisa melihat--exclude=.git
.Dalam hal ini, Anda tidak perlu tanda kutip tunggal sama sekali -
.git
adalah kata shell yang valid dengan sempurna, tanpa karakter khusus, sehingga Anda dapat menggunakannya secara harfiah dalam perintah.Lebih baik untuk hal semacam ini, adalah array :
Ini membangun perintah Anda sebagai kata-kata yang terpisah, dengan kutipan apa pun yang Anda inginkan ditafsirkan pada saat Anda menulis baris array.
"${PARMS[@]}"
memperluas ke setiap entri dalam array sebagai argumen terpisah, bahkan jika argumen itu sendiri memiliki karakter atau spasi khusus di dalamnya, jadirsync
lihat apa yang Anda tulis seperti yang Anda maksudkan.sumber
bash
melakukan pemisahan kata setelah${PARMS}
diperluas. Jadi kutipan tunggal juga ditafsirkan oleh shell.\
,'
dan"
. Yang tidak dihasilkan dari salah satu ekspansi di atas dihapus" "ekspansi di atas" termasuk Ekspansi Parameter yang melakukan perluasan${PARMS}
.IFS
(umumnya, spasi), Anda tidak perlu mengutipnya. Jika ya, Anda kurang beruntung kecuali jika Anda meretas sesuatu bersamaeval
- ini adalah kesalahan umum pada umumnya, dan array adalah cara yang tepat untuk menghadapinya.Selain jawaban @Michael Homer , Anda dapat menggunakan
bash
fungsi eval :sumber
eval
.