Apa gunanya operator Null ":", titik dua?

13

Apa gunanya operator "null" dalam skrip BASH? Saya mengerti bahwa ini digunakan sebagai pengganti yang mengikuti ifperintah ketika Anda tidak memiliki sesuatu untuk dikatakan, tetapi perlu perintah untuk memungkinkan program berjalan dengan baik. Tapi apa gunanya keseluruhan untuk itu? Kapan Anda akan menggunakannya? Kapan masuk akal untuk menggunakannya?

Justin
sumber
1
Alasan Anda mengutip adalah alasan yang cukup penting. Mengapa Anda membutuhkan lebih banyak?
terdon

Jawaban:

16

Terkadang berguna untuk memungkinkan efek samping ekspansi parameter terjadi.

Misalnya, menetapkan nilai default

read -p "Enter your name: " name
: ${name:=John Doe}  # if the user entered an empty string
echo "$name"
glenn jackman
sumber
2
Bisakah Anda menjelaskan simbol demi simbol bagaimana cara kerja baris kedua?
Ruslan
Baca tentang ekspansi :perintah dan parameter di manual bash.
glenn jackman
4
Untuk menguraikan apa yang dirujuk oleh @glennjackman, baris kedua memanggil perintah null:, dan ${name:="John Doe"}akan diperluas, menyebabkan penugasan berlangsung karena dibaca sebagai argumen untuk:. Tanpa: shell akan mencoba menjalankan "John Doe" sebagai perintah, atau nilainya$name jika sudah disetel
imkendal
13

Anda juga dapat menggunakannya untuk loop tanpa akhir:

while : ; do 
   # ....
done
choroba
sumber
4
Tetapi mungkin while truelebih mudah dibaca, karena (a) ia menggunakan lebih sedikit tanda baca, dan (b) lebih mirip dengan bahasa yang diturunkan dari C.
wchargin
9

Anda dapat menggunakannya untuk membuat file tanpa menjalankan program ::

: > /path/to/file

Ini jauh lebih cepat daripada touch /path/to/file (karena tidak memerlukan menjalankan touchprogram) dan mungkin sedikit lebih portabel daripada sekadar

> /path/to/file

yang tampaknya bekerja pada banyak sistem. Demikian pula, dapat digunakan untuk memeriksa apakah Anda memiliki akses tulis ke file :

if { : >> /path/to/file;} 2> /dev/null
then
    echo "writeable"
else
    echo "write permission denied"
fi

Meskipun ini, juga, secara umum dapat dilakukan tanpa :. Peringatan:

  • Ini tidak memeriksa apakah file sudah ada. Jika tidak, ini akan membuat file jika memiliki izin untuk melakukannya.
  • Jika file tidak ada, dan skrip Anda tidak memiliki izin untuk membuatnya, ini akan melaporkan "izin menulis ditolak".

(Lihat pertanyaan terkait untuk alasan mengapa ini lebih dapat diandalkan daripada if [ -w /path/to/file ].)

G-Man Mengatakan 'Reinstate Monica'
sumber
5

Jauh di belakang, di Unix V6 dan Thompson Shell, :itu sebenarnya digunakan sebagai bagian dari gotopernyataan. Menurut manual , ini awalnya muncul di Unix versi 3:

Seluruh file perintah dicari untuk sebuah baris yang dimulai dengan: sebagai karakter non-kosong pertama, diikuti oleh satu atau lebih kosong, dan kemudian label. Jika garis seperti itu ditemukan, goto memposisikan ulang file perintah ke baris setelah label dan keluar. Ini menyebabkan shell untuk mentransfer ke baris berlabel.

Saat ini, dalam bash, itu digunakan sebagai operator no-op, mengembalikan kesuksesan. Memang, jika Anda melihat kode sumber , Anda akan melihat keduanya truedan :menggunakan fungsi yang sama int colon_builtin(),, di bawahnya. Tidak ada :perintah non-builtin, dan /bin/truesebenarnya adalah perintah yang cukup besar untuk apa yang dilakukannya.

:dapat digunakan di mana saja truedigunakan, misalnya dalam command_that_can_fail || true, meskipun itu mungkin membingungkan para non-ahli. Baca lebih lanjut di sini .

Sergiy Kolodyazhnyy
sumber
3

Anda dapat menggunakannya pada tes positif ifperintah ketika Anda hanya ingin melakukan sesuatu di sisi negatif. Sebagai contoh:

if [[ True == False ]]; then
    :
else
    echo "true <> flase"
fi

Tanpa : bash akan menghasilkan kesalahan sintaksis.

Ini adalah contoh yang terlalu disederhanakan. Secara umum Anda akan menggunakan teknik seperti itu dalam pengkodean pendahuluan ketika Anda belum menulis segmen kode itu dan hanya perlu sesuatu yang tidak menghasilkan kesalahan.

WinEunuuchs2Unix
sumber
Jawaban yang bagus, meskipun pada awalnya mungkin tidak terlihat, bahwa ini paling berguna dengan perintah aktual dalam kondisi pengujian, misalnya if pgrep firefox >/dev/null ; then : ; else echo "Firefox not running"; fiakan menunjukkan kesalahan hanya jika firefox tidak berjalan. Dengan kata lain, ketika Anda perlu melakukan sesuatu hanya ketika perintah memiliki kesalahan. Di satu sisi ini setara dengan pgrep firefox || echo "Firefox not running", meskipun lebih mudah dibaca dan memungkinkan lebih banyak perintah
Sergiy Kolodyazhnyy
0

Saya hanya menggunakannya dalam skrip dengan perintah SSH untuk menjaga skrip agar tidak keluar.

Dalam hal ini, saya ingin melihat apakah pengguna dapat terhubung ke satu set server. Jika koneksi OK, host jarak jauh akan bergema OK. Jika koneksi gagal, SSH akan merespons dengan kesalahan. Namun, saya ingin skrip saya keluar dengan 0 dan bukan nilai perintah SSH jika gagal. Jadi pada dasarnya saya menjebak kesalahan SSH dengan ORing ||dengan perintah nol :. Terlihat seperti ini:

#!/bin/bash
for i in $(cat servers.txt); do
    echo -n "$i "; 
    ssh user@${i} 'echo OK' || :; 
done

Dengan begitu saya mendapatkan output dari SSH tetapi bukan kode kesalahan:

....
swl06 ok
swl07 ok
swl08 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
swl09 ok
swl10 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
....
Michael J
sumber