Saya mencoba membuat skrip dengan echo
memasukkan konten ke dalam file, alih-alih membukanya dengan editor
echo -e "#!/bin/bash \n /usr/bin/command args" > .scripts/command
The Output :
bash:! / bin / bash: acara tidak ditemukan
Saya telah mengisolasi perilaku aneh ini ke ledakan .
$ echo !
!
$ echo "!"
bash: !: event not found
$ echo \#!
#!
$ echo \#!/bin/bash
bash: !/bin/bash: event not found
- Kenapa bang menyebabkan ini?
- Apa "peristiwa" yang dirujuk oleh bash ini?
- Bagaimana cara saya mengatasi masalah ini dan mencetak "#! / Bin / bash" ke layar atau file saya?
command-line
bash
echo
Stefan
sumber
sumber
$''
. Misalnyaecho $'1!\n2!\n3!\n'
mencetak setiap angka diikuti dengan bang dan baris baru.echo '0123'"$var"'456'
perhatikan dua pasang tanda kutip tunggal dan sepasang tanda kutip ganda.Seperti yang dikatakan Richm , bash sedang mencoba melakukan pertandingan sejarah . Cara lain untuk menghindarinya adalah dengan melarikan diri dari ledakan dengan
\
:Meskipun berhati-hatilah bahwa di dalam tanda kutip ganda,
\
itu tidak dihapus:sumber
"\!"
sebenarnya diperluas menjadi\!
, tidak!
, seharusnya untuk kepatuhan POSIX.!
dalam tanda kutip ganda tanpa perilaku sulap? Ini gila ...!
memulai substitusi sejarah ("acara" adalah garis dalam sejarah perintah); misalnya!ls
memperluas ke baris perintah terakhir yang berisils
, dan!?foo
memperluas ke baris perintah terakhir yang berisifoo
. Anda juga dapat mengekstrak kata-kata spesifik (mis.!!:1
Merujuk pada kata pertama dari perintah sebelumnya) dan lebih banyak lagi; lihat manual untuk detailnya.Fitur ini diciptakan untuk dengan cepat mengingat perintah sebelumnya di masa ketika edisi baris perintah adalah primitif. Dengan shell modern (setidaknya bash dan zsh) dan copy-and-paste, ekspansi sejarah tidak berguna seperti dulu - ini masih membantu, tetapi Anda bisa bertahan tanpa itu.
Anda dapat mengubah karakter mana yang memicu substitusi riwayat dengan menetapkan
histchars
variabel; jika Anda jarang menggunakan substitusi histori, Anda dapat mengatur mishistchars='¡^'
sehingga¡
memicu ekspansi histori alih-alih!
. Anda bahkan dapat mematikan fitur sama sekaliset +o histexpand
.sumber
Untuk dapat menonaktifkan ekspansi riwayat pada baris perintah tertentu, Anda dapat menggunakan
space
sebagai karakter ke-3 dari$histchars
:Kemudian, jika Anda memasukkan perintah Anda dengan spasi terkemuka, ekspansi sejarah tidak akan dilakukan.
Namun perlu dicatat bahwa spasi utama juga digunakan ketika
$HISTCONTROL
berisiignorespace
sebagai cara untuk memberitahubash
agar tidak merekam baris perintah dalam sejarah.Jika Anda menginginkan kedua fitur tersebut secara independen, Anda harus memilih karakter lain sebagai karakter ketiga
$histchars
. Anda ingin satu yang tidak mempengaruhi cara perintah Anda ditafsirkan. Beberapa pilihan:\
):\echo foo
berfungsi tetapi memiliki efek samping menonaktifkan alias atau kata kunci.jika Anda tidak keberatan mengetik dua tombol, Anda dapat memilih karakter yang biasanya tidak muncul di posisi pertama (
%
,@
,?
, memilih sendiri) dan membuat sebuah alias kosong untuk itu:Lalu masukkan karakter itu, spasi dan perintah Anda:
(Anda tidak akan dapat merekam perintah di mana substitusi riwayat telah dinonaktifkan. Juga catat bahwa karakter ke-3 default
$histchars
adalah#
agar ekspansi riwayat tidak dilakukan dalam komentar. Jika Anda mengubahnya, dan Anda memasukkan komentar di cepat, Anda harus menyadari fakta bahwa! Urutan dapat diperluas di sana).sumber
Solusi yang diusulkan tidak berfungsi, misalnya, contoh berikut:
Dalam hal ini bang dapat dicetak menggunakan kode ASCII oktalnya:
sumber
!
adalah di antara tanda kutip ganda, di mana sebagai jawaban lain menunjukkan itu mempertahankan makna ekspansi sejarahnya. Anda bisa menggunakanbash -c 'echo '\''hello World!'\'
ataubash -c "echo 'hello World"\!"'"
.Sejak Bash 4.3, sekarang Anda dapat menggunakan tanda kutip ganda untuk mengutip karakter ekspansi sejarah:
sumber
!
diikuti oleh"
yang tidak lagi istimewa.echo "foo!"
tidak apaecho "foo!bar"
-apa