it-swarm-id.com

$ VAR vs $ {VAR} dan mengutip atau tidak mengutip

Saya bisa menulis

VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"

hasil akhirnya bagi saya semua tampak hampir sama. Mengapa saya harus menulis yang satu atau yang lain? apakah semua ini tidak portabel/POSIX?

150
xenoterracide

VAR=$VAR1 Adalah versi sederhana dari VAR=${VAR1}. Ada hal-hal yang kedua dapat lakukan yang pertama tidak bisa, misalnya referensi indeks array (tidak portabel) atau menghapus substring (POSIX-portable). Lihat bagian Lebih lanjut tentang variabel pada Panduan Bash untuk Pemula dan Ekspansi Parameter dalam spesifikasi POSIX.

Menggunakan kutipan di sekitar variabel seperti dalam rm -- "$VAR1" Atau rm -- "${VAR}" Adalah ide yang bagus. Ini menjadikan isi variabel sebagai unit atom. Jika nilai variabel berisi kosong (well, karakter dalam variabel khusus $IFS, Kosong secara default) atau karakter globbing dan Anda tidak mengutipnya, maka setiap Word dipertimbangkan untuk pembuatan nama file (globbing) yang ekspansi yang dilakukan oleh banyak argumen untuk apa pun yang Anda lakukan.

$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'

$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename

Pada portabilitas: Menurut POSIX.1-2008 bagian 2.6.2 , kurung kurawal adalah opsional.

108
Shawn J. Goff

${VAR} dan $VAR persis sama. Untuk ekspansi variabel biasa, satu-satunya alasan untuk menggunakan ${VAR} adalah ketika penguraian sebaliknya akan mengambil terlalu banyak karakter ke dalam nama variabel, seperti pada ${VAR1}_$VAR2 (yang tanpa kawat gigi akan setara dengan ${VAR1_}$VAR2). Ekspansi yang paling dihiasi (${VAR:=default}, ${VAR#prefix}, ...) membutuhkan kawat gigi.

Dalam penugasan variabel, pemisahan bidang (yaitu pemisahan di whitespace dalam nilai) dan ekspansi pathname (mis. Globbing) dimatikan, jadi VAR=$VAR1 persis sama dengan VAR="$VAR1", di semua shell POSIX dan semua sh pre-POSIX yang pernah saya dengar. (POSIX ref: perintah sederhana ). Untuk alasan yang sama, VAR=* andal mengatur VAR ke string literal *; tentu saja VAR=a b set VAR ke a karena b adalah kata yang terpisah. Secara umum, tanda kutip ganda tidak diperlukan di mana sintaks Shell mengharapkan satu kata, misalnya dalam case … in (tetapi tidak dalam pola), tetapi bahkan di sana Anda perlu berhati-hati: misalnya POSIX menentukan bahwa target pengalihan (>$filename) tidak perlu mengutip dalam skrip, tetapi beberapa shell termasuk bash memang membutuhkan kutip ganda bahkan dalam skrip. Lihat Kapan perlu kutip ganda? untuk analisis yang lebih menyeluruh.

Anda membutuhkan tanda kutip ganda dalam kasus lain, khususnya dalam export VAR="${VAR1}" (yang dapat ditulis secara setara export "VAR=${VAR1}") di banyak shell (POSIX membiarkan case ini terbuka). Kesamaan kasus ini dengan penugasan sederhana, dan sifat daftar kasus yang tersebar di mana Anda tidak perlu tanda kutip ganda, itulah sebabnya saya sarankan hanya menggunakan tanda kutip ganda kecuali jika Anda ingin membagi dan menggumpal.

Kutipan

Pertimbangkan bahwa kutipan ganda digunakan untuk ekspansi variabel, dan kutipan tunggal digunakan untuk kutipan kuat, yaitu, ekspansi sans.

Ekspansi:

this='foo'
that='bar'
these="$this"
those='$that'

Keluaran:

for item in "$this" "$that" "$these" "$those"; do echo "$item"; done
foo
bar
foo
$that

Mungkin bermanfaat untuk menyebutkan bahwa Anda harus menggunakan kutipan sedapat mungkin karena beberapa alasan, di antaranya adalah yang dianggap praktik terbaik, dan untuk keterbacaan. Juga karena Bash kadang-kadang unik dan sering untuk cara yang tampaknya tidak logis atau tidak masuk akal/tidak terduga, dan kutipan mengubah ekspektasi implisit menjadi eksplisit, yang mengurangi permukaan kesalahan (atau potensi-untuknya).

Dan sementara itu sepenuhnya legal untuk tidak kutipan, dan akan bekerja dalam banyak kasus, fungsionalitas itu disediakan untuk kenyamanan dan mungkin lebih mudah dibawa-bawa. praktik formal sepenuhnya dijamin untuk mencerminkan niat dan harapan adalah mengutip.

Pengganti

Sekarang perhatikan juga bahwa konstruk "${somevar}" digunakan untuk operasi substitusi. Beberapa kasus penggunaan, seperti penggantian, dan array.

Penggantian (pengupasan):

thisfile='foobar.txt.bak'
foo="${thisfile%.*}"   # removes shortest part of value in $thisfile matching after '%' from righthand side
bar="${thisfile%%.*}"  # removes longest matching

for item in "$foo" "$bar"; do echo "$item"; done
foobar.txt
foobar

Penggantian (replacement):

foobar='Simplest, least effective, least powerful'
# ${var/find/replace_with}
foo="${foobar/least/most}"   #single occurrence
bar="${foobar//least/most}"  #global occurrence (all)

for item in "$foobar" "$foo" "$bar"; do echo "$item"; done
Simplest, least effective, least powerful
Simplest, most effective, least powerful
Simplest, most effective, most powerful

Array:

mkdir temp
# create files foo.txt, bar.txt, foobar.txt in temp folder
touch temp/{foo,bar,foobar}.txt
# alpha is array of output from ls  
alpha=($(ls temp/*))

echo "$alpha"         #  temp/foo.txt
echo "${alpha}"       #  temp/foo.txt
echo "${alpha[@]}"    #  temp/bar.txt  temp/foobar.txt  temp/foo.txt
echo "${#alpha}"      #  12 # length of first element (implicit index [0])
echo "${#alpha[@]}"   #  3  # number of elements
echo "${alpha[1]}"    #  temp/foobar.txt # second element
echo "${#alpha[1])"   #  15 # length of second element

for item in "${alpha[@]}"; do echo "$item"; done
temp/bar.txt
temp/foobar.txt
temp/foo.txt

Semua ini nyaris tidak menggores permukaan "${var}" konstruksi substitusi. Referensi definitif untuk skrip Bash Shell adalah referensi online gratis, TLDP The Linux Documentation Project https://www.tldp.org/LDP/abs/html/parameter-substitution.html

9
SYANiDE
ls -la

lrwxrwxrwx.  1 root root      31 Nov 17 13:13 prodhostname
lrwxrwxrwx.  1 root root      33 Nov 17 13:13 testhostname
lrwxrwxrwx.  1 root root      32 Nov 17 13:13 justname

akhir saja:

env=$1
    if [ ! -f /dirname/${env}hostname ]

layak disebut sebagai contoh yang lebih jelas dari menggunakan ikal

0
ninjabber