yazabilirim
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
Bana sonuçta hepsi aynı görünüyor. Neden birini veya diğerini yazmalıyım? bunlardan herhangi biri taşınabilir değil / POSIX?
yazabilirim
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
Bana sonuçta hepsi aynı görünüyor. Neden birini veya diğerini yazmalıyım? bunlardan herhangi biri taşınabilir değil / POSIX?
Yanıtlar:
VAR=$VAR1
basitleştirilmiş bir sürümüdür VAR=${VAR1}
. İkincisinin yapamayacağı şeyler vardır, örneğin bir dizi dizinine referans verebilir (taşınabilir değil) veya bir alt dizgiyi kaldırabilir (POSIX taşınabilir). POSIX özelliklerinde Yeni Başlayanlar İçin Bash Kılavuzu ve Parametre Genişletme bölümündeki Değişkenler hakkında daha fazlası bölümüne bakın .
Bir değişkenin etrafındaki tırnak işaretlerini kullanarak rm -- "$VAR1"
ya da rm -- "${VAR}"
olduğu gibi iyi bir fikirdir. Bu, değişkenin içeriğini atomik bir birim yapar. Değişken değeri boşluklar ( $IFS
özel değişkendeki karakterler, varsayılan olarak boşluklar) veya globbing karakterleri içeriyorsa ve alıntı yapmıyorsanız, her kelime, genişlemesi size ne kadar argüman yaparsa, dosya adı oluşturma (globbing) olarak kabul edilir. yapıyorum.
$ 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
Taşınabilirlikte: POSIX.1-2008 bölüm 2.6.2'ye göre , küme parantezleri isteğe bağlıdır.
var1=$var
Genişlemenin hata verdiği herhangi bir gerçek kabuk örneğiniz var mı?
export VAR=$VAR1
. Parantezlere gelince, isteğe bağlıdırlar (alıntı yaptığınız bölümün dördüncü paragrafını kontrol edin; bu durum tüm POSIX ve POSIX kabuklarında geçerlidir).
${VAR}
ve $VAR
tam olarak eşdeğerdir. Düz değişken bir genişleme için, kullanmanın tek nedeni ${VAR}
, ayrıştırmanın değişken ismine çok fazla karakter girmesidir ${VAR1}_$VAR2
(olduğu gibi (parantez olmadan eşdeğer olur ${VAR1_}$VAR2
)). Çoğu süslenmiş genişleme ( ${VAR:=default}
,, ${VAR#prefix}
…) diş telleri gerektirir.
Bir değişken atamasında, alan bölme (yani değerdeki boşlukta bölme) ve yol adı genişletme (yani globbing) kapatılır, yani tüm POSIX kabuklarında ve duyduğum tüm POSIX öncesi sh'lerinde VAR=$VAR1
tam olarak eşdeğerdir VAR="$VAR1"
. (POSIX ref: basit komutlar ). Aynı nedenden dolayı, değişmez dizgeye VAR=*
güvenilir bir şekilde ayarlanır ; Tabii setleri için çünkü ilk etapta ayrı kelimedir. Genel konuşmak kabuk sözdizimi, örneğin tek bir kelime beklediğini nerede, çift tırnak gereksizdir içinde (ancak desende), ancak orada bile dikkatli olmak gerekir: örneğin POSIX belirtirVAR
*
VAR=a b
VAR
a
b
case … in
yönlendirme hedefleri ( >$filename
), komut dosyalarında alıntı yapılmasını gerektirmez, ancak bash dahil olmak üzere birkaç kabuk, komut dosyalarında bile çift tırnak işareti gerektirir. Bkz . Çift alıntı ne zaman gereklidir? daha kapsamlı bir analiz için.
Diğer durumlarda, özellikle birçok kabukta ( export VAR="${VAR1}"
aynı anda yazılabilir export "VAR=${VAR1}"
) çift tırnaklara ihtiyacınız vardır (POSIX bu davayı açık bırakır). Bu davanın basit ödevlerle benzerliği ve çift tırnak kullanmaya gerek duymadığınız davalar listesinin dağınık doğası, bölmek ve kürek almak istemediğiniz sürece neden sadece çift tırnak kullanmanızı öneririm.
IFS
karakter içermediğini bildiğim halde , alışkanlıkta olmak istediğim için değişken açılımları her zaman alıntılayacağım . Bunun tek istisnası, değişken ataması yaparken değeri alıntılamıyorum (değer boşluk içerdiği zaman gerekli olmadıkça). Bu, editör sözdizimini, bunun gibi komut ikameleri olduğunda daha kullanışlı hale getirir FOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
. Her şeyi "string" rengini renklendirmek yerine iç içe geçmiş kodun sözdizimini vurgularım. Bu da geri tepmelerden kaçınmamın nedeni budur.
>$file
POSIX betiklerinde TAMAM iken , etkileşimli olmasa bile bash değil (POSIX uyumluluğu $POSIXLY_CORRECT
veya --posix
... ile zorlanmadıkça ).
VAR=$VAR1
, bazen local VAR=$VAR1
bazı yönlerden, en azından bazı mermilerde farklı şekilde çalıştığımı hatırladığım için şaşırdım . Ama atm, ayrılığı yeniden üretemiyorum.
local VAR=$VAR1
gibidir export VAR=$VAR1
, kabuğa bağlıdır.
İkili teklifin değişken genişleme için kullanıldığını ve tekli teklifin güçlü alıntı için, yani genişleme için kullanıldığını düşünün.
this='foo'
that='bar'
these="$this"
those='$that'
for item in "$this" "$that" "$these" "$those"; do echo "$item"; done
foo
bar
foo
$that
Bir kaç nedenden dolayı, en iyi uygulama olarak kabul edilenler arasında ve okunabilirlik için mümkün olan her yerde tırnak kullanmanız gerektiğini belirtmek faydalı olabilir. Ayrıca Bash, zaman zaman ve çoğu zaman görünüşte mantıksız veya mantıksız / beklenmedik şekillerde ilginç olduğu için ve tırnak, beklentilerin açıkça ortaya çıkmasına neden olur ve bu da bu hata yüzeyini (veya bunun potansiyelini) azaltır.
Ve alıntı yapmamak tamamen yasal olsa da ve çoğu durumda çalışacak olsa da, bu işlevsellik kolaylık sağlamak için sağlanmıştır ve muhtemelen daha az taşınabilirdir. niyet ve beklentiyi yansıtmayı garanti eden tamamen resmi bir uygulama alıntı yapmaktır.
Şimdi yapının "${somevar}"
ikame işlemleri için kullanıldığını da göz önünde bulundurun . Değiştirme ve diziler gibi birkaç kullanım durumu.
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
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
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
Bunların hepsi, "${var}"
ikame yapısının yüzeyini zar zor çiziyor . Bash kabuk komut dosyası için kesin referans libre çevrimiçi referansıdır, TLDP Linux Belgelendirme Projesihttps://www.tldp.org/LDP/abs/html/parameter-substitution.html
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
sonra o zaman:
env=$1
if [ ! -f /dirname/${env}hostname ]
kıvrım kullanmanın daha net bir örneği olarak görülmeye değer