Jawaban:
Di Bash, test
dan [
shell builtins.
The bracket ganda , yang merupakan kata kunci shell, memungkinkan fungsionalitas tambahan. Misalnya, Anda dapat menggunakan &&
dan ||
bukannya -a
dan -o
dan ada operator pencocokan ekspresi reguler =~
.
Juga, dalam tes sederhana, kurung kotak ganda tampaknya mengevaluasi cukup banyak lebih cepat daripada yang tunggal.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done
real 0m24.548s
user 0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done
real 0m33.478s
user 0m33.478s
sys 0m0.000s
Kawat gigi, selain membatasi nama variabel digunakan untuk ekspansi parameter sehingga Anda dapat melakukan hal-hal seperti:
Potong isi suatu variabel
$ var="abcde"; echo ${var%d*}
abc
Buat penggantinya mirip dengan sed
$ var="abcde"; echo ${var/de/12}
abc12
Gunakan nilai default
$ default="hello"; unset var; echo ${var:-$default}
hello
dan beberapa lainnya
Juga, ekspansi brace membuat daftar string yang biasanya diulang dalam loop:
$ echo f{oo,ee,a}d
food feed fad
$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")
$ for num in {000..2}; do echo "$num"; done
000
001
002
$ echo {00..8..2}
00 02 04 06 08
$ echo {D..T..4}
D H L P T
Perhatikan bahwa fitur zero and increment terdepan tidak tersedia sebelum Bash 4.
Terima kasih kepada gboffi untuk mengingatkan saya tentang ekspansi brace.
Tanda kurung ganda digunakan untuk operasi aritmatika :
((a++))
((meaning = 42))
for ((i=0; i<10; i++))
echo $((a + b + (14 * c)))
dan mereka memungkinkan Anda untuk menghilangkan tanda dolar pada variabel integer dan array dan menyertakan spasi di sekitar operator agar mudah dibaca.
Kurung tunggal juga digunakan untuk indeks array :
array[4]="hello"
element=${array[index]}
Curly brace diperlukan untuk referensi array (sebagian besar / semua?) Di sebelah kanan.
komentar ephemient mengingatkan saya bahwa tanda kurung juga digunakan untuk subkulit. Dan mereka digunakan untuk membuat array.
array=(1 2 3)
echo ${array[1]}
2
:
.
$[expression]
; ini adalah sintaks ekspresi aritmatika lama, usang untuk sintaks yang lebih baru, lebih disukai:$((expression))
bash
adalah menciptakan urutan, seperti yang disebutkan di bawah ini ( stackoverflow.com/a/8552128/2749397 ) Karena saya ingin sedikit mengomentari fitur ini (karena Anda tidak menyebutkannya ;-) Saya ' m mengambil kebebasan menggunakan jawaban yang paling banyak dipilih sebagai kendaraan ... Dua contoh urutan literal: echo {01..12}
-> 01 02 03 04 05 06 07 08 09 10 11 12
(perhatikan nol awal); echo {C..Q}
-> C D E F G H I J K L M N O P Q
. Penggunaan utamanya adalah dalam loop, misalnya, for cnt in {01..12} ; do ... ${cnt} ... ; done
echo {01..12..2}
-> "01 03 05 07 09 11". Terima kasih atas pengingat tentang urutan. Saya akan menambahkannya ke jawaban saya.
Braket tunggal ( [
) biasanya sebenarnya memanggil program bernama [
; man test
atau man [
untuk info lebih lanjut. Contoh:
$ VARIABLE=abcdef
$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi
yes
Braket ganda ( [[
) melakukan hal yang sama (pada dasarnya) sebagai braket tunggal, tetapi merupakan bash bawaan.
$ VARIABLE=abcdef
$ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi
no
Tanda kurung ( ()
) digunakan untuk membuat subkulit. Sebagai contoh:
$ pwd
/home/user
$ (cd /tmp; pwd)
/tmp
$ pwd
/home/user
Seperti yang Anda lihat, subkulit memungkinkan Anda untuk melakukan operasi tanpa mempengaruhi lingkungan shell saat ini.
(a) Kawat gigi ( {}
) digunakan untuk mengidentifikasi variabel secara jelas. Contoh:
$ VARIABLE=abcdef
$ echo Variable: $VARIABLE
Variable: abcdef
$ echo Variable: $VARIABLE123456
Variable:
$ echo Variable: ${VARIABLE}123456
Variable: abcdef123456
(B) Kawat gigi juga digunakan untuk mengeksekusi urutan perintah dalam konteks shell saat ini , misalnya
$ { date; top -b -n1 | head ; } >logfile
# 'date' and 'top' output are concatenated,
# could be useful sometimes to hunt for a top loader )
$ { date; make 2>&1; date; } | tee logfile
# now we can calculate the duration of a build from the logfile
Ada perbedaan sintaksis yang halus dengan ( )
, (lihat referensi bash ); pada dasarnya, tanda titik koma ;
setelah perintah terakhir dalam kawat gigi adalah suatu keharusan, dan kawat gigi {
, }
harus dikelilingi oleh spasi.
[
sebenarnya builtin di Bash, tetapi seharusnya bertindak seperti /bin/[
berlawanan dengan [[
builtin. [[
memiliki fitur yang berbeda, seperti operasi yang lebih logis dan peran kutipan yang berbeda. Selain itu: tanda kurung tunggal juga digunakan untuk array, substitusi proses, dan glob diperpanjang; tanda kurung ganda digunakan untuk aritmatika; kurung kurawal {}
digunakan untuk pengelompokan perintah atau banyak jenis ekspansi parameter atau ekspansi kurung atau ekspansi urutan. Saya yakin saya telah melewatkan beberapa kegunaan lain juga ...
if [ $VARIABLE == abcdef ]
adalah bashism yang - meskipun berfungsi - mungkin harus dihindari; baik menggunakan bash ( if [[ ...==...]]
) secara eksplisit atau memperjelas bahwa Anda menggunakan conditional ( if [ "$VARIABLE" = "abcdef" ]
) yang lebih tradisional . Dapat diperdebatkan, skrip harus dimulai sesederhana dan semudah mungkin, hingga benar-benar membutuhkan fitur khusus untuk bash (karena satu dan lain hal). Tetapi bagaimanapun juga, tujuannya harus jelas; "=" dan "==" dan "[[" dan "[" berfungsi secara berbeda dan penggunaannya harus konsisten.
[ "$var" = ".."]
alih-alih ==
, sedangkan di C akan menetapkan bukan pengujian (dan merupakan penyebab bug yang cukup umum) ... mengapa tidak bisa test
digunakan ==
bukan =
? ada yang tahu?
/usr/bin/[
bukan symlink ke /usr/bin/test
, dan banyak lagi: program-program ini bahkan memiliki beberapa ukuran yang berbeda!
)
adalah bagian dari case
sintaks pernyataan untuk mengakhiri garis kasus. Itu tidak memiliki tanda kurung buka. Ini melempar saya dari pertama kali saya melihatnya.
Kurung
if [ CONDITION ] Test construct
if [[ CONDITION ]] Extended test construct
Array[1]=element1 Array initialization
[a-z] Range of characters within a Regular Expression
$[ expression ] A non-standard & obsolete version of $(( expression )) [1]
[1] http://wiki.bash-hackers.org/scripting/obsolete
Kurung kurawal
${variable} Parameter substitution
${!variable} Indirect variable reference
{ command1; command2; . . . commandN; } Block of code
{string1,string2,string3,...} Brace expansion
{a..z} Extended brace expansion
{} Text replacement, after find and xargs
Tanda kurung
( command1; command2 ) Command group executed within a subshell
Array=(element1 element2 element3) Array initialization
result=$(COMMAND) Command substitution, new style
>(COMMAND) Process substitution
<(COMMAND) Process substitution
Tanda kurung ganda
(( var = 78 )) Integer arithmetic
var=$(( 20 + 5 )) Integer arithmetic, with variable assignment
(( var++ )) C-style variable increment
(( var-- )) C-style variable decrement
(( var0 = var1<98?9:21 )) C-style ternary operation
$(varname)
tidak terkait dengan sintaks bash. Itu adalah bagian dari sintaks Makefile .
$(varname)
tidak ada hubungannya dengan sintaks bash dalam kasus Anda.
Saya hanya ingin menambahkan ini dari TLDP :
~:$ echo $SHELL
/bin/bash
~:$ echo ${#SHELL}
9
~:$ ARRAY=(one two three)
~:$ echo ${#ARRAY}
3
~:$ echo ${TEST:-test}
test
~:$ echo $TEST
~:$ export TEST=a_string
~:$ echo ${TEST:-test}
a_string
~:$ echo ${TEST2:-$TEST}
a_string
~:$ echo $TEST2
~:$ echo ${TEST2:=$TEST}
a_string
~:$ echo $TEST2
a_string
~:$ export STRING="thisisaverylongname"
~:$ echo ${STRING:4}
isaverylongname
~:$ echo ${STRING:6:5}
avery
~:$ echo ${ARRAY[*]}
one two one three one four
~:$ echo ${ARRAY[*]#one}
two three four
~:$ echo ${ARRAY[*]#t}
one wo one hree one four
~:$ echo ${ARRAY[*]#t*}
one wo one hree one four
~:$ echo ${ARRAY[*]##t*}
one one one four
~:$ echo $STRING
thisisaverylongname
~:$ echo ${STRING%name}
thisisaverylong
~:$ echo ${STRING/name/string}
thisisaverylongstring
echo ${#ARRAY}
menampilkan tiga, karena elemen pertama ARRAY
berisi tiga karakter, bukan karena mengandung tiga elemen! Untuk mencetak jumlah elemen yang digunakan echo ${#ARRAY[@]}
.
${TEST:-test}
sama dengan $TEST
jika variabel TEST
ada, jika tidak, ia hanya mengembalikan string "test". Ada versi lain yang bahkan lebih: ${TEST:=test}
--- yang juga sama dengan $TEST
jika TEST ada, tetapi setiap kali tidak ada, itu menciptakan variabel TEST
dan memberikan nilai "tes" dan juga menjadi nilai dari keseluruhan ekspresi.
Perbedaan antara tes , [ dan [[ dijelaskan dengan sangat rinci di BashFAQ .
Singkat cerita: test mengimplementasikan sintaksis portabel yang lama dari perintah tersebut. Di hampir semua cangkang (cangkang Bourne tertua adalah pengecualian), [adalah sinonim untuk pengujian (tetapi membutuhkan argumen akhir]). Meskipun semua shell modern memiliki implementasi bawaan [, biasanya masih ada executable eksternal dari nama itu, misalnya / bin / [.
[[adalah versi baru yang disempurnakan, yang merupakan kata kunci, bukan program. Ini memiliki efek menguntungkan pada kemudahan penggunaan, seperti yang ditunjukkan di bawah ini. [[dipahami oleh KornShell dan BASH (mis. 2.03), tetapi tidak oleh POSIX atau BourneShell yang lebih lama).
Dan kesimpulannya:
Kapan seharusnya perintah uji yang baru [[digunakan, dan kapan yang lama [? Jika portabilitas ke BourneShell menjadi perhatian, sintaks lama harus digunakan. Jika di sisi lain skrip membutuhkan BASH atau KornShell, sintaks baru jauh lebih fleksibel.
Tanda kurung ()
sedang digunakan dalam definisi fungsi:
function_name () { command1 ; command2 ; }
Itulah alasan Anda harus keluar dari tanda kurung bahkan dalam parameter perintah:
$ echo (
bash: syntax error near unexpected token `newline'
$ echo \(
(
$ echo () { command echo The command echo was redefined. ; }
$ echo anything
The command echo was redefined.
unset -f echo
. Lihat help unset
.
Truncate the contents of a variable
$ var="abcde"; echo ${var%d*}
abc
Make substitutions similar to sed
$ var="abcde"; echo ${var/de/12}
abc12
Use a default value
$ default="hello"; unset var; echo ${var:-$default}
hello