Bisakah saya dengan aman menghilangkan tanda kutip di sisi kanan tugas lokal?
function foo {
local myvar=${bar}
stuff()
}
Saya terutama tertarik bash, tetapi setiap info tentang kasus sudut di kulit lain dipersilakan.
Bisakah saya dengan aman menghilangkan tanda kutip di sisi kanan tugas lokal?
function foo {
local myvar=${bar}
stuff()
}
Saya terutama tertarik bash, tetapi setiap info tentang kasus sudut di kulit lain dipersilakan.
Jawaban:
Kutipan diperlukan dalam export foo="$var"atau local foo="$var"(atau readonly, typeset, declaredan variabel menyatakan lainnya perintah ) di:
dashshdari NetBSD (juga didasarkan pada Almquist shell).shFreeBSD 9.2 atau lebih tua (lihat perubahan di 9.3 )yashzshdengan versi sebelum 5.1 dalam kshatau shemulasi (atau di export var="$(cmd)"mana zshakan melakukan pemisahan kata sebaliknya (tidak menggumpal)).Seperti sebaliknya, ekspansi variabel akan dikenakan pemisahan kata dan / atau pembuatan nama file seperti dalam argumen apa pun terhadap perintah lain.
Dan tidak diperlukan di:
bashksh (semua implementasi)shdari FreeBSD 9.3 atau yang lebih barush(sejak 2005)zshIn zsh, split + glob tidak pernah dilakukan pada ekspansi parameter, kecuali dalam shatau kshemulasi, tetapi split (bukan glob) dilakukan pada substitusi perintah. Sejak versi 5.1, export/ localdan perintah deklarasi lainnya telah menjadi kata kunci ganda / perintah builtin seperti pada shell lain di atas, yang berarti mengutip tidak diperlukan, bahkan dalam sh/ kshemulasi dan bahkan untuk substitusi perintah.
Ada kasus-kasus khusus di mana mengutip diperlukan bahkan dalam cangkang tersebut seperti:
a="b=some value"
export "$a"
Atau lebih umum, jika sesuatu yang tersisa dari =(termasuk =) dikutip atau hasil dari ekspansi (seperti export 'foo'="$var", export foo\="$var"atau export foo$((n+=1))="$var"(yang $((...))juga harus dikutip sebenarnya) ...). Atau dengan kata lain ketika argumen untuk exporttidak akan menjadi tugas variabel yang valid jika ditulis tanpa export.
Jika export/ localnama perintah itu sendiri dikutip (bahkan di bagian seperti "export" a="$b", 'ex'port a="$b", \export a="$b", atau bahkan ""export a="$b"), tanda kutip sekitar $bdiperlukan kecuali pada AT & T kshdan mksh.
Jika export/ localatau sebagian dari itu adalah hasil dari ekspansi (seperti dalam cmd=export; "$cmd" a="$b"atau bahkan export$(:) a="$b") atau dalam hal-hal seperti dryrun=; $dryrun export a="$b"), maka tanda kutip diperlukan di setiap shell.
Dalam hal > /dev/null export a="$b", kuotasi diperlukan dalam pdkshdan beberapa turunannya.
Karena command export a="$b", tanda kutip diperlukan di setiap shell tetapi mkshdan ksh93(dengan peringatan yang sama tentang commanddan exporttidak menjadi hasil dari ekspansi).
Mereka tidak diperlukan dalam shell apa pun ketika ditulis:
foo=$var export foo
(Sintaks itu juga kompatibel dengan shell Bourne tetapi dalam versi terbaru zsh, hanya berfungsi ketika di sh/ kshemulasi).
(perhatikan bahwa var=value local vartidak boleh digunakan karena perilaku bervariasi di seluruh cangkang).
Perhatikan juga bahwa menggunakan exportdengan penugasan juga berarti bahwa status keluar cmdmasuk export var="$(cmd)"hilang. Melakukannya karena export var; var=$(cmd)tidak memiliki masalah itu.
Waspadalah terhadap kasus khusus ini dengan bash:
$ bash -c 'IFS=; export a="$*"; echo "$a"' bash a b
ab
$ bash -c 'IFS=; export a=$*; echo "$a"' bash a b
a b
Saran saya adalah selalu mengutip.
zshtanda kutip yang dibutuhkan untuk local foo="$(cmd)"karena wordsplitting (tapi tidak nama file generasi) yang dilakukan untuk substitusi perintah kuotasi (tetapi tidak untuk ekspansi parameter kuotasi), kecuali KSH_TYPESETdiaktifkan, di mana kutipan kasus tidak diperlukan. Masuk akal? Tidak? Maka selalu kutip semuanya kecuali Anda tahu persis apa yang Anda lakukan.
Saya biasanya mengutip setiap penggunaan variabel di mana mungkin ada karakter seperti spasi putih. Kalau tidak, Anda akan mengalami masalah seperti ini:
#!/bin/bash
bar="hi bye"
function foo {
local myvar=${bar}
printf "%s\n" $myvar
printf "%s\n" "$myvar"
}
foo
Penggunaan variabel dalam suatu tugas tampaknya tidak membutuhkan tanda kutip, tetapi ketika Anda menggunakannya, printfAnda akan membutuhkannya yang dikutip di sana:
printf "%s\n" "$myvar"
CATATAN: Ingat bahwa variabel $IFSadalah apa yang mengatur apa karakter pemisah.
IFS The Internal Field Separator that is used for word splitting after
expansion and to split lines into words with the read builtin command.
The default value is ``<space><tab><newline>''.
Dengan debugging diaktifkan di Bash kita dapat melihat apa yang terjadi di balik layar.
$ bash -x cmd.bash
+ bar='hi bye'
+ foo
+ local 'myvar=hi bye'
+ printf '%s\n' hi bye
hi
bye
+ printf '%s\n' 'hi bye'
hi bye
Dalam contoh di atas kita dapat melihat bahwa variabel, $bardibagikan dengan baik ke $myvartetapi kemudian ketika kita pergi untuk menggunakan $myvarkita harus menyadari isi $myvarketika kita pergi untuk menggunakannya.
bashdan kshdi local/ typeset... builtin khusus).