Mengapa pesan kesalahan untuk dua titik dua sebagai perintah (: :) di bash memiliki tiga titik dua, tetapi satu titik dua tidak menghasilkan keluaran?

27

Jika saya mengetik

::

menjadi bash shell, saya mendapatkan:

-bash: ::: command not found

Tapi, hanya satu yang :tidak menghasilkan output. Kenapa ini?

NerdOfLinux
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Thomas Ward
Bagaimana ini terkait dengan Ubuntu?
NerdOfCode
@ NerdOfCode dengan cara yang sama? meta.askubuntu.com/q/17076/158442
muru

Jawaban:

40

The :shell built-in vs tidak ada::

Perintah : built-in shell ada (perhatikan perbedaan antara perintah eksternal dan built-in ) yang tidak melakukan apa-apa; itu hanya mengembalikan kesuksesan, seperti halnya trueperintah. The :built-in standar dan ditetapkan oleh standar POSIX , di mana itu juga dikenal sebagai "nol utilitas". Ini sering digunakan untuk pengujian atau untuk menjalankan loop tak terbatas seperti padawhile : ; do ...;done

bash-4.3$ type :
: is a shell builtin

Namun, ::- dua karakter titik dua bersama-sama - ditafsirkan sebagai satu "kata" pada shell, dan dianggap sebagai perintah yang dimasukkan pengguna. Shell akan melalui proses pengecekan built-in, lalu direktori mana pun dalam PATHvariabel untuk keberadaan perintah itu. Tetapi tidak ada :: perintah internal atau internal ::. Karena itu, itu menghasilkan kesalahan.

Nah, apa format khas untuk kesalahan?

<shell>: <command user typed>: error message

Jadi, apa yang Anda lihat bukan 3 titik dua tetapi apa yang Anda ketikkan disisipkan ke dalam format kesalahan standar.

Perhatikan juga, yang :dapat mengambil argumen baris perintah, yaitu sah untuk dilakukan:

: :

Dalam hal ini, shell akan menganggap itu sebagai dua "kata", salah satunya adalah perintah dan yang lainnya sebagai parameter posisi. Itu juga tidak akan menghasilkan kesalahan! (Lihat juga catatan historis (nanti dalam jawaban ini) tentang penggunaan :parameter dengan posisi).


Dalam cangkang selain bash

Perhatikan bahwa pemformatan dapat bervariasi di antara berbagai shell yang berbeda. Untuk bash,, kshdan mkshperilaku konsisten. Misalnya, /bin/shshell default Ubuntu (yang sebenarnya /bin/dash):

$ dash
$ ::
dash: 1: ::: not found

di mana 1 adalah nomor perintah (setara dengan nomor baris dalam naskah)

csh sebaliknya tidak menghasilkan pesan kesalahan sama sekali:

$ csh
% ::
%

Bahkan, jika Anda menjalankan strace -o csh.trace csh -c ::, jejak jejak dalam csh.tracefile mengungkapkan bahwa cshkeluar dengan status keluar 0 (tidak ada kesalahan). Tetapi tcshapakah menghasilkan kesalahan (tanpa mengeluarkan namanya):

$ tcsh
localhost:~> ::
::: Command not found.

Pesan kesalahan

Secara umum, item pertama dalam pesan kesalahan haruslah proses atau fungsi eksekusi (shell Anda mencoba untuk mengeksekusi ::, maka pesan kesalahan tersebut berasal dari shell). Misalnya, di sini proses pelaksanaannya adalah stat:

$ stat noexist
stat: cannot stat 'noexist': No such file or directory

Bahkan, POSIX mendefinisikan fungsi perror () , yang menurut dokumentasi mengambil argumen string, kemudian menampilkan pesan kesalahan setelah titik dua, dan kemudian baris baru. Mengutip:

Fungsi perror () akan memetakan nomor kesalahan yang diakses melalui simbol errno ke pesan kesalahan yang tergantung pada bahasa, yang harus ditulis ke aliran kesalahan standar sebagai berikut:

  • Pertama (jika s bukan pointer nol dan karakter yang ditunjuk oleh s bukan byte nol), string yang ditunjuk oleh s diikuti oleh titik dua dan <spasi>.

  • Kemudian string pesan kesalahan diikuti oleh <newline>.

Dan argumen string untuk secara perror()teknis bisa apa saja, tapi tentu saja untuk kejelasan itu biasanya nama fungsi atau argv[0].

Sebaliknya, GNU memiliki serangkaian fungsi dan variabel untuk penanganan kesalahan , yang dapat digunakan oleh seorang programmer fprintf()untuk melakukan stderrstreaming. Seperti yang ditunjukkan salah satu contoh pada halaman tertaut, sesuatu seperti ini dapat dilakukan:

  fprintf (stderr, "%s: Couldn't open file %s; %s\n",
           program_invocation_short_name, name, strerror (errno));

Catatan sejarah

Dalam shell Unix dan Thompson yang lama, :digunakan dengan gotopernyataan (yang menurut pengguna bernama Perderabo pada utas ini bukan sebuah shell bawaan ). Kutipan dari manual:

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 jalur berlabel.

Jadi Anda bisa melakukan sesuatu seperti ini untuk membuat skrip loop tak terbatas:

: repeat
echo "Hello World"
goto repeat
Sergiy Kolodyazhnyy
sumber
"3 kolom" salah ketik untuk "3 titik dua"
Barmar
1
DOS command.comdan Windows cmd.exememiliki situasi yang serupa tetapi berlawanan: :secara eksplisit merupakan label goto (bukan perintah) dan sering digunakan ulang sebagai karakter komentar (misalnya :: This is a comment).
grawity
54

Tanda titik dua terakhir hanya sebagian dari pesan "tidak ditemukan" default:

$ x
x: command not found
$ ::
::: command not found

Alasan satu titik tidak menghasilkan apa-apa adalah itu : adalah perintah yang valid - meskipun tidak melakukan apa-apa (kecuali kembali TRUE). Dari SHELL BUILTIN COMMANDSbagian man bash:

   : [arguments]
          No effect; the command does nothing beyond  expanding  arguments
          and  performing any specified redirections.  A zero exit code is
          returned.

Anda kadang-kadang akan melihatnya dalam konstruksi seperti

while :
do
  something
done

Lihat misalnya Apa tujuan yang dibangun usus besar?

Steeldriver
sumber
ya ini adalah komentar paling komprehensif .. jauh lebih fasih daripada saya .. jauh lebih baik dijelaskan: D
John Orion
8

Coba perintah lain yang tidak ada dan Anda akan melihat bahwa :melayani tujuan normal dalam bahasa Inggris:

$ ---
---: command not found
Olorin
sumber
6

Tanda titik dua yang ditambahkan adalah bagian dari pesan kesalahan itu sendiri. Jika salah satu jenis cd owitu menghasilkan bash: cd: ow: No such file or directory, yang menunjukkan bahwa kesalahan diletakkan di usus besar tambahan: No such file or directory

John Orion
sumber
6
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

yang ke-3 adalah pengatur jarak dari pemformatan

dalam bash a :adalah instruksi baris kosong

pengguna688056
sumber
4

Anda mendapatkan 3 titik dua karena format galat berisi titik dua:

bash: <command>: command not found
ravery
sumber