Saya telah meretas banyak skrip shell, dan kadang-kadang hal paling sederhana membuat saya bingung. Hari ini saya menemukan skrip yang memanfaatkan :
bash builtin (usus besar) secara ekstensif .
The documenation tampaknya cukup sederhana:
: (a colon) : [arguments]
Jangan lakukan apa pun selain memperluas argumen dan melakukan pengalihan. Status pengembalian adalah nol.
Namun saya sebelumnya hanya melihat ini digunakan dalam demonstrasi ekspansi shell. Kasus penggunaan dalam skrip yang saya temui memanfaatkan struktur ini secara ekstensif:
if [ -f ${file} ]; then
grep some_string ${file} >> otherfile || :
grep other_string ${file} >> otherfile || :
fi
Sebenarnya ada ratusan greps, tetapi mereka hanya lebih sama. Tidak ada pengalihan input / output selain struktur sederhana di atas. Tidak ada nilai kembali yang diperiksa kemudian dalam skrip.
Saya membaca ini sebagai konstruksi tidak berguna yang mengatakan "atau tidak melakukan apa-apa". Tujuan apa yang bisa mengakhiri greps ini dengan "atau tidak melakukan apa-apa" melayani? Dalam hal apa konstruksi ini menyebabkan hasil yang berbeda dari hanya meninggalkan || :
dari semua contoh?
sumber
:
sebagai alternatiftrue
. Mungkinerrexit
diatur dan penulis tidak peduli dengan status keluar dari beberapa perintah.Jawaban:
Tampaknya
:
s dalam skrip Anda digunakan sebagai penggantitrue
. Jikagrep
tidak menemukan kecocokan dalam file, itu akan mengembalikan kode keluar bukan nol; seperti jw013 menyebutkan dalam komentar, jikaerrexit
disetel, mungkin oleh-e
pada baris shebang, skrip akan keluar jika ada yanggrep
gagal menemukan kecocokan. Jelas, bukan itu yang diinginkan penulis, jadi dia menambahkan|| :
untuk membuat status keluar dari perintah majemuk tertentu selalu nol, seperti yang lebih umum (dalam pengalaman saya)|| true
/|| /bin/true
.sumber
true
sebagai gantinya, tetapi maksud semantiknya jauh lebih jelastrue
.:
lebih cocok ketika NOP eksplisit diinginkan.:
daripadatrue
karena:
merupakanbash
built-in di mana sepertitrue
biasanya biner dikompilasi dengan lebih banyak overhead. biasanya saya menggunakantrue
karena kode lebih mudah dibaca (juga saya lebih suka menggunakansource
daripada.
).The
:
builtin ini juga berguna dengan Bash "nilai-nilai default assign" ekspansi shell, di mana ekspansi sering digunakan semata-mata untuk efek samping dan nilai diperluas dibuang:sumber
Saya bisa memikirkan dua tempat yang saya gunakan
:
di masa lalu.Itu adalah loop selamanya.
Masukkan fungsi rintisan, hanya untuk mendapatkan aliran kontrol tingkat atas yang benar.
Satu penggunaan yang saya lihat di masa lalu: Alih-alih garis
#!/bin/sh
(atau apa pun), Anda akan melihat:
garis. Beberapa kernel Real Unix yang lebih lama atau shell Real Unix akan menggunakan itu untuk berarti "Saya skrip shell, harus menjalankan saya". Seingat saya ini hanya ketika csh membuat terobosan sebagai shell interaktif umum.sumber
:
sangat aneh. Saya menemukan bahwa itu memang menyebabkan skrip dijalankansh
. di mana seperti ketika Anda memulai skrip tanpa shebang ... ia mencoba untuk menjalankan skrip dengan shell apa pun yang berjalan (jadi jika Anda menjalankannyabash
mencoba menjalankannya seolah-bash
olah Anda memilikicsh
maka mencoba menjalankannya sebagaicsh
).The
:
built-in sudah di Thompson shell - itu didokumentasikan untuk Unix V6 pada tahun 1975. Dalam Thompson shell,:
menunjukkan label untukgoto
perintah. Jika Anda tidak pernah mencoba menelepongoto
saluran yang diawali:
, saluran itu adalah komentar yang efektif.The Bourne shell , nenek moyang kerang Bourne / POSIX seperti yang kita tahu mereka, tidak pernah memiliki
goto
yang saya tahu, tapi tetap:
sebagai perintah no-op (itu sudah ada dalam Unix V7 ).sumber
Saya menggali referensi lama: "Lingkungan Pemrograman UNIX" (c) 1984 oleh Kernighan dan Pike.
Halaman 147 (Pemrograman Shell) mengatakan ini:
sumber
true
sekarang shell builtin juga pada banyak sistem.Saya ingat bahwa versi awal shell tidak memiliki sintaks komentar. Sebuah baris yang dimulai dengan
:
(yang mungkin akan menjadi executable aktual, mirip dengan/bin/true
) akan menjadi alternatif terbaik.Inilah halaman manual untuk cangkang Thompson kuno (tidak ada hubungan); tidak ada penyebutan sintaks komentar.
sumber
:
sebenarnya adalah indikator label untukgoto
perintah, di beberapa shell kuno (saya tidak tahu yang mana). Label: something
memang dapat digunakan sebagai komentar, jika tidak ada yang cocokgoto
. Latihan itu macet bahkan setelahgoto
menghilang.":" berguna untuk debugging.
Berjalan secara normal, fungsi debug tidak pernah dieksekusi sehingga ia hanya perlu melangkah di atas noop (variabel dan wildcard diperluas meskipun). Jika diperlukan debugging lebih dalam, hapus noop dari variabel dan fungsi debug dipanggil dengan argumen apa pun yang diperlukan.
Penggunaan praktis lainnya adalah sebagai blok komentar, yang merupakan fitur yang hilang dari sintaksis shell.
sumber