Saya selalu terkejut bahwa di folder /bin
ada [
program.
Apakah ini yang disebut ketika kita melakukan sesuatu seperti if [ something ]
:?
Dengan memanggil [
program secara eksplisit dalam sebuah shell, ia meminta korespondensi ]
, dan ketika saya memberikan braket penutup sepertinya tidak melakukan apa pun, apa pun yang saya masukkan di antara kurung.
Tak perlu dikatakan, cara biasa untuk mendapatkan bantuan tentang suatu program tidak bekerja, yaitu tidak man [
juga tidak [ --help
berfungsi.
[
merujuk padatest
perintah, bukanexpr
, jadi seharusnyaman test
man '['
berfungsi dengan baik untuk saya - baik Anda lupa mengutip[
atau Anda memiliki definisi yang berbeda dari "karya".[
mengevaluasi argumennya, jadi Anda perlu memiliki ruang di antara semuanya.[ a=b ]
bukan perbandingan: itu akan selalu benar (itu adalah string tunggal: "a = b", yang selalu dievaluasi menjadi benar ) Dan Anda harus membatasi jumlah argumen hingga 4 (meskipun implementasi terbaru akan memungkinkan lebih banyak .. membatasi hingga 4 menjadikannya lebih portabel. Misalnya:[ "a" = "b" ]
sudah memiliki 4 argumen: "a" "=" "b" dan akhir uji arg yang tidak perlu: "]"). Jika Anda membutuhkan lebih banyak: tes berantai dengan misalnya:if [ "$Var_a" = "foo" ] && [ "$Var_b" = "bar" ] ; then : do something ; fi
!
dengan sendirinya (tidak dihapus dan tidak dikutip) tidak akan diganti, dan bahkan lebih baikif ! [ ...
. Semua ekspansi bash yang digunakan!
termasuk setidaknya pada karakter lain[
-builtin dibash
(dan mungkin juga kerang lain), dan ini bisa digunakan sebagai ganti/bin/[
. Juga adatest
perintah-, yang pada banyak sistem adalah tautan simbolis ke/bin/[
(atau sebaliknya) - tetapi pada yang lain adalah perintah yang terpisah.Jawaban:
Tugas
[
perintah adalah mengevaluasi ekspresi pengujian. Ia kembali dengan status keluar 0 (itu berarti benar ) ketika ekspresi diselesaikan menjadi benar dan sesuatu yang lain (yang berarti salah ) sebaliknya.Bukannya tidak melakukan apa-apa, hanya saja hasilnya ditemukan dalam status keluarnya. Dalam sebuah shell, Anda dapat mencari tahu tentang status keluar dari perintah terakhir di
$?
untuk shell mirip Bourne atau$status
di sebagian besar shell lainnya (fish / rc / es / csh / tcsh ...).Dalam bahasa lain seperti
perl
, status keluar dikembalikan misalnya dalam nilai pengembaliansystem()
:Perhatikan bahwa semua kerang mirip Bourne modern (dan
fish
) memiliki[
perintah bawaan. Yang masuk/bin
biasanya hanya akan dieksekusi ketika Anda menggunakan shell lain atau ketika Anda melakukan hal-hal sepertienv [ foo = bar ]
ataufind . -exec [ -f {} ] \; -print
atauperl
perintah di atas ...The
[
perintah juga dikenal dengantest
nama. Ketika dipanggil sebagaitest
, itu tidak memerlukan]
argumen penutup .Meskipun sistem Anda mungkin tidak memiliki halaman manual
[
, mungkin memiliki satu halaman untuktest
. Tetapi sekali lagi, perhatikan bahwa itu akan mendokumentasikan/bin/[
atau/bin/test
implementasi. Untuk mengetahui tentang[
builtin di shell Anda, Anda harus membaca dokumentasi untuk shell Anda.Untuk informasi lebih lanjut tentang sejarah utilitas itu dan perbedaannya dengan
[[...]]
ekspresi pengujian ksh, Anda mungkin ingin melihat pada Tanya Jawab lain di sini .sumber
[
. Saya tidak ingat apakah itu varian Bourne atau versi antik abu.[
dantest
sebagai bawaan dengan Unix System III. Sebelum itu, tidak ada[
dantest
hanya ada perintah biner eksternal.find . -exec [ f {} ] \; -print
? Perintah itufind . -type f -print
akan melakukan hal yang sama dengan jauh lebih efisien ...Anda benar terkejut. Itu salah satu perintah POSIX yang langka, dengan utilitas nol (
:
), yang tidak menghormati file perintah yang diizinkan konvensi karakter (kumpulan karakter nama file portabel).Tepatnya tetapi bisa digunakan tanpa
if
terlalu.Itu tidak terlihat tetapi benar-benar melakukan hal yang sama daripada ketika digunakan dengan
if
, yaitu menetapkan status keluar ke 0 (benar) atau apa pun (salah) tergantung pada apa yang Anda masukkan ke dalam kurung. Itu (karena suatu alasan) perilaku yang sama dengantest
perintah; satu-satunya perbedaan adalah bahwa ia mencari akhirannya]
. Lihatman test
detailnya.Itu tergantung pada Sistem Operasi Anda.
man [
pasti bekerja untuk saya di beberapa distribusi Gnu / Linux arus utama tetapi tidak pada Solaris.[ --help
mungkin bekerja atau tidak tergantung pada implementasi karena melanggar sintaks, melewatkan bagian akhirnya]
. Selain itu, standar POSIX untuk perintahtest
/[
secara eksplisit mengesampingkan semua opsi, termasuk--
penghentian opsi sehingga keduanya[ --help ]
dantest --help
perlu kembalitrue
dan diam dengan desain. Perhatikan bahwa apa yang Anda masukkan di dalam kurung atau setelah[
dan terlihat seperti pilihan (misalnya-f file
,-n string
, dan sejenisnya) tidak pilihan tapi operan .Semua Bourne gaya shell interpreter modern (seperti
bash
,ksh
,dash
danzsh
untuk beberapa nama) melaksanakantest
/[
utilitas internal sebagai builtin sehingga ketika Anda menggunakannya, halaman manual yang tepat untuk merujuk mungkin salah satu dari shell, bukantest
satu.Sebelum Unix System III (1981), shell Bourne tidak mengimplementasikan
test
utilitas sebagai builtin sehingga hanya implementasi perintah biner eksternal yang tersedia. Tidak ada[
perintah (internal atau builtin) sampai Unix System III jadi misalnya di bawah Unix Versi 7 Anda harus mengetik:dari pada:
sumber
man test
bekerja tetapi tidakman [
Di sisi lain, lingkungan cygwin saya diketahuiman [
!man [
tampaknya tidak berfungsi di Manjaro (Arch Linux based). Manual untuktest
daftar[ --help
sebagai doa sah yang harus menunjukkan bantuan, tetapi yang menarik tidak, dan sebaliknya mengeluh tentang yang hilang]
, sama dengan--version
. Menambahkan]
tidak melakukan apa-apa, jadi sepertinya tidak mungkin untuk mendapatkan bantuan selain dariman test
./usr/bin/[ --help
atau/bin/[ --help
.env [ --help
serta/usr/bin/[ --help
bekerja sepenuhnya baik-baik saja (meskipun saya perlu mengutip/usr/bin/[
atau mengeluh zsh).[
sebenarnya lebih dikenal sebagaitest
perintah. Penggunaan khas dari perintah ini hanya untuk mengevaluasi ekspresi dan mengembalikan kondisinya - benar atau salah. Ini sering digunakan dalamif-then-else-fi
pernyataan, meskipun dapat digunakan di luarif
pernyataan untuk menjalankan perintah lain secara kondisional melalui shell&&
atau||
operator, seperti itu.Lebih khusus lagi, evaluasi dikomunikasikan ke perintah lain melalui status keluar. Beberapa program mungkin memilih untuk mengeluarkan status keluar untuk menandakan berbagai jenis peristiwa - program berhasil diselesaikan, kesalahan jenis tertentu terjadi selama eksekusi, atau kesalahan sintaksis. Dalam hal
test
perintah, ada yang0
benar, dan yang1
salah. Seperti yang ditunjukkan Stephan, kesalahan sintaksis menghasilkan status keluar dari2
.Lokasinya tergantung pada sistem Anda, dan itu juga menjelaskan mengapa Anda tidak melihat halaman manual ketika Anda melihatnya
man [
. Misalnya, pada FreeBSD itu di bawah/bin
. Di Linux (atau dalam kasus khusus saya, Ubuntu 16.04) itu ada di/usr/bin/
. Jika Anda melakukannyaman [
atauman test
pada sistem Linux, Anda akan melihat dokumentasi yang sama terbuka. Penting juga untuk dicatat bahwa shell Anda mungkin memiliki implementasinya sendiritest
.Perlu juga dicatat bahwa perintah ini memiliki masalah , yang implementasi shell Korn (umumnya dikenal sebagai "ekspresi bersyarat" referensi dengan tanda kurung ganda,
[[ "$USER" = "root" ]]
) berusaha untuk menyelesaikan. Fitur ini juga digunakan oleh cangkang lain sepertibash
danzsh
.sumber
/usr/bin/
untuk Amazon Linux juga.Pada beberapa distro (misalnya Ubuntu),
man [
ikuti symlink ketest(1)
. Pada yang lain (mis. Lengkungan), ini bukan masalahnya. (Tetapitest
halaman manual tidak mendokumentasikan penggunaan[
juga)type -a [
menunjukkan kepada Anda bahwa ada shell builtin dan executable.bash-builtin
[ --help
hanya mencetak pesan kesalahan. (Tapi karena itu builtin, Anda dapat menggunakanhelp [
, atau melihat halaman bash man / docs)./usr/bin/[ --help
mencetak hasil bantuan penuh (untuk versi GNU Coreutils), yang dimulai dengan:dan kemudian menjelaskan sintaks yang diizinkan untuk EXPRESSION.
Ini adalah cara lain Anda bisa mengetahui
[
dantest
setara.BTW, jika Anda memprogram untuk bash (atau menulis one-liners secara interaktif), saya akan merekomendasikan
[[
sebagai gantinya[
. Lebih baik dalam beberapa hal, lihat tautan di jawaban Serg.sumber
[
perintah mengembalikan status keluar nol jika ekspresi, yang terkandung dalam argumennya, dianggap benar dan status keluar nol jika ekspresi, yang terkandung dalam argumennya, dianggap salah. Itu juga gagal dengan pesan kesalahan jika argumen terakhirnya tidak]
(ini dilakukan murni karena alasan estetika).Misalnya:
... akan menampilkan:
Namun, bash dan banyak shell lain biasanya tidak memanggil
/bin/[
(atau/usr/bin/[
) dalam kasus ini, tetapi panggil perintah built-in dengan perilaku yang persis sama sebagai gantinya (murni untuk alasan kinerja). Untuk memanggil/bin/[
(bukan shell built-in surrogate), Anda perlu menentukan pathnya secara eksplisit (misalnya/bin/[ hello ]
; Anda tidak perlu awalan]
dengan dirname ☺ ), atau untuk mengkonfigurasi shell agar tidak menggunakan pengganti built-in (misalnya,enable -n [
dalam bash).PS: Seperti yang dikatakan dalam jawaban lain
[
terkait dengantest
. Tapitest
, tidak seperti[
, tidak memerlukan]
sebagai argumen yang terakhir (dan tidak mengharapkan sama sekali, menambahkan ekstra]
untuktest
argumen dapat menyebabkan gagal dengan pesan kesalahan atau kembali hasil yang salah) . Itu/bin/test
dan/bin/[
dapat menyelesaikan ke file yang sama (misalnya satu adalah symlinked ; dalam hal ini pengalihan perilaku mungkin dilaksanakan dengan menganalisis perintah yang saat ini disebut dalamtest
/[
kode itu sendiri) atau ke file yang berbeda. Untuktest
, shell juga biasanya memanggil pengganti bawaan, kecuali path ditentukan secara eksplisit (/bin/test
) atau dikonfigurasi untuk tidak melakukannya (enable -n test
).PPS: Tidak seperti
test
dan[
, modernif
tidak pernah menjadi file nyata. Itu bagian dari sintaks shell (mis. Bash):if commandA; then commandB; fi
(baris baru dapat digunakan sebagai ganti titik koma) menyebabkancommandB
dieksekusi jika-dan-hanya-jikacommandA
keluar dengan status nol. Ini sangat cocok untuk perilakutest
atau[
, memungkinkan untuk menggabungkan mereka sukaif [ "$a" = foo ]; then …; fi
(atauif test "$a" = foo; then …; fi
- kurang dibaca) . Namun, skrip modern sering menggunakan[[
alih-alihtest
atau[
, yang (sebagaiif
) tidak pernah menjadi file nyata, tetapi selalu menjadi bagian dari sintaks shell.PPPS: Adapun
man
- jangan pernah berharapman
untuk memiliki artikel tentang setiap perintah di sistem file Anda. Info pada beberapa (bahkan "nyata", berkas-based) perintah mungkin hilang, info pada beberapa shell built-in mungkin hadir tidak hanya dalam sebuah artikel yang didedikasikan untuk shell tertentu (yang adalah tempat di mana Anda pasti akan menemukan info tentangtest
,[
,if
,[[
). Namun, banyak distribusi memilikiman
-artikel eksplisit untuktest
dan[
. (Tentang--help
, itu tidak dikenali dengantest
alasan yang jelas: perlu menangani kasus-kasus diam-diam sepertia=--help; test "$a"
; pada beberapa distribusi[ --help
(tanpa penutupan]
) masih menunjukkan bantuan, pada beberapa itu tidak.)sumber
if
itu adalah perintah hingga Unix V6. Unix V7 (1979) datang dengan shell Bourne (denganif-then-else-fi
konstruknya) dantest
perintah baru .