Apa yang dilakukan dengan mengetik tanda seru di Bash?

20

Bash menggunakan tanda seru untuk ekspansi sejarah, seperti yang dijelaskan dalam jawaban untuk pertanyaan ini (misalnya sudo !!menjalankan baris perintah sebelumnya dengan sudo). Namun, saya tidak dapat menemukan tempat yang menjelaskan apa yang menjalankan perintah berikut (yaitu tanda seru tunggal):

!

Tampaknya tidak mencetak apa pun dan keluar dengan 1, tetapi saya tidak yakin mengapa ia melakukan itu. Saya telah melihat online dan di halaman manual Bash, tetapi tidak dapat menemukan apa pun, terlepas dari kenyataan bahwa itu adalah "kata yang dilindungi" - tetapi begitu juga }, dan menjalankan ini:

}

mencetak kesalahan:

bash: syntax error near unexpected token `}'
Josh
sumber
1
Tidak ada. !menunjukkan "awal" dari ekspresi ekspansi sejarah.
jordanm

Jawaban:

47

Satu-satunya !di awal perintah meniadakan status keluar dari perintah atau pipa : jika perintah keluar 0, itu akan berubah menjadi 1(kegagalan), dan jika keluar non-nol itu akan mengubahnya menjadi 0keluar (berhasil).

Penggunaan ini didokumentasikan dalam manual Bash:

Jika kata yang dipesan '!' mendahului pipa, status keluar adalah negasi logis dari status keluar seperti yang dijelaskan di atas.

Sebuah !tanpa perintah berikut meniadakan perintah kosong, yang tidak apa-apa dan kembali benar (setara dengan para :perintah ). Dengan demikian itu membalikkan yang benar ke yang salah dan keluar dengan status 1, tetapi tidak menghasilkan kesalahan.


Ada juga kegunaan lain dari !dalam testdan [[perintah, di mana mereka meniadakan tes kondisional. Ini tidak terkait dengan apa yang Anda lihat. Baik dalam pertanyaan Anda dan kasus-kasus itu tidak terkait dengan ekspansi sejarah dan !dipisahkan dari istilah lain.

Michael Homer
sumber
5
+1 untuk jawaban pertama yang menjelaskan apa yang sebenarnya dijalankan dan mengapa itu menjelaskan kode kembali.
Jeff Schaller
11

Anda dapat menemukan satu tanda seru yang didokumentasikan di bagian manual bash 3.2.2 Pipa

Jika kata yang dipesan '!' mendahului pipa, status keluar adalah negasi logis dari status keluar seperti yang dijelaskan di atas.

$ ! true; echo $?
1
$ ! false; echo $?
0

Juga bagian 3.2.4.2 Konstruksi Bersyarat

! ekspresi

Benar jika ekspresi salah.


Juga bagian 4.1 Bourne Shell Builtins

! expr

Benar jika expr salah.


Juga harus dicatat bahwa !akan memulai penggantian sejarah kecuali diikuti oleh: spasi, tab, akhir baris, '=' atau '(' (ketika opsi cangkang extglob diaktifkan menggunakan shopt builtin).

Jesse_b
sumber
0

Karena !digunakan dalam perbandingan dan artinya TIDAK .

Sebagai contoh:

a=3
b=2

[ $a -eq $b ] && echo "Equal"
[ ! $a -eq $b ] && echo "Not equal"
# of cause last comparison is possible to write as:
[ $a -eq $b ] || echo "Not equal"

[ $a -eq $b ]
echo $?
1
[ ! $a -eq $b ]
echo $?
0
Yurij Goncharuk
sumber
1
Itulah makna !sebagai argumen pada testperintah (termasuk versi built-in bash), bukan arti !ketika digunakan dalam posisi perintah.
Gilles 'SO- berhenti menjadi jahat'
1
Perlu ! [...]mencocokkan pertanyaan dalam kasus ini.
Michael Homer
Setuju dengan @Gilles dan @Michael Homer. Saya tahu bahwa []adalah test. Saya sedikit terburu-buru.
Yurij Goncharuk
-2

! built-in command, membalikkan arti pipa.

Penggunaan lainnya:

#! built-in command, memanggil interpreter bernama untuk menjalankan skrip.

! penunjuk acara, menandai kata baris perintah sebagai pengganti sejarah

!= operator ketidaksetaraan

$! variabel shell, mengembalikan nomor proses dari perintah latar belakang terakhir.

Bharat
sumber
Hanya dengan menambahkan, seseorang dapat menggunakan! $ Untuk menggunakan kata terakhir dari perintah sebelumnya seperti ls -l /tmp cd !$ ini : Ini akan membawa Anda ke direktori / tmp.
Hopping Bunny
-3

! diikuti oleh sebuah string mengeksekusi perintah sebelumnya yang terbaru (masih dalam buffer perintah) yang dimulai dengan string yang diberikan. Mungkin shell hanya menemukan bahwa tidak ada perintah sebelumnya dimulai dengan <null>.

pdelmonte
sumber
3
Anda perhatikan bahwa tidak ada string yang diberikan dalam pertanyaan ...?
Jeff Schaller