Kadang-kadang saya perlu menulis teks dan kemudian menyalurkan teks itu ke perintah lain. Alur kerja saya yang biasa berjalan seperti ini:
vim
# I edit and save my file as file.txt
cat file.txt | pandoc -o file.pdf # pandoc is an example
rm file.txt
Saya menemukan ini rumit dan berusaha untuk belajar scripting bash Saya ingin membuat proses lebih sederhana dengan menulis perintah yang membuka editor dan ketika editor menutup pipa output editor ke stdout. Maka saya bisa menjalankan perintah sebagai quickedit | pandoc -o file.pdf
.
Saya tidak yakin bagaimana ini akan berhasil. Saya sudah menulis fungsi untuk mengotomatisasi ini dengan mengikuti alur kerja yang tepat di atas ditambah beberapa tambahan. Ini menghasilkan string acak untuk bertindak sebagai nama file dan meneruskannya ke vim ketika fungsi dipanggil. Ketika pengguna keluar vim dengan menyimpan file, fungsi mencetak file ke konsol dan kemudian menghapus file.
function quickedit {
filename="$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32)"
vim $filename
cat $filename
rm $filename
}
# The problem:
# => Vim: Warning: Output is not to a terminal
Masalah saya segera temui adalah ketika saya melakukan sesuatu seperti quickedit | command
vim itu sendiri tidak dapat digunakan sebagai editor karena semua output dibatasi ke pipa.
Saya bertanya-tanya apakah ada solusi untuk ini, sehingga saya bisa menyalurkan output dari quickedit
fungsi saya . Alternatif suboptimal adalah menjalankan editor terpisah, katakan teks luhur, tapi saya benar-benar ingin tinggal di terminal.
:w !pandoc -o file.pdf
? (Catatan: ruang antaraw
dan!
sangat penting.)mktemp
daripada menciptakannya kembali dengan cara yang tidak aman.Jawaban:
vipe
adalah program untuk mengedit saluran pipa:Anda mendapatkan editor dengan output lengkap
command1
, dan ketika Anda keluar, konten diteruskan kecommand2
melalui pipa.Dalam hal ini, tidak ada
command1
. Jadi, Anda bisa melakukan:Atau:
vipe
mengambilEDITOR
danVISUAL
variabel, sehingga Anda dapat menggunakannya untuk membuka Vim.Jika Anda belum menginstalnya,
vipe
tersedia dalammoreutils
paket;sudo apt-get install moreutils
, atau apa pun yang setara dengan flavour Anda.sumber
moreutils
tersedia di Homebrew.moreutils
tersedia untuk diinstal melalui pkg (8) .Anda dapat melakukan ini dari dalam Vim:
Atau bahkan menulis buffer ke dalam pipeline yang kompleks:
Dan kemudian Anda dapat keluar dari Vim tanpa menyimpan:
Namun, mengingat kasus penggunaan khusus Anda, mungkin ada solusi yang lebih baik dengan menggunakan
vi
sebagai editor baris perintah Anda. Dengan asumsi Anda menggunakanbash
:Ini mengatur ikatan kunci Anda
vi
. Sehingga Anda dapat mengedit perintah Anda tepat pada baris perintah dengan dasarvi
keybindings dengan menekan<Esc>
dan kemudian mengetikvi
perintah sepertix
,cw
, dll (Anda bisa mendapatkan kembali modus insert dengan menekani
.)Bahkan lebih baik, dan lebih relevan dengan pertanyaan ini, Anda dapat membuka Vim untuk membuat konten baris perintah Anda secara langsung. Cukup ketik
<Esc>v
dan Anda akan mendapatkan buffer Vim kosong. Ketika Anda menyimpan dan keluar, itu adalah perintah di baris perintah Anda dan langsung dijalankan. Ini jauh lebih fleksibel daripada mengedit pada baris perintah secara langsung karena Anda dapat menulis seluruh skrip mini jika Anda mau.Jadi, misalnya, jika Anda ingin menulis beberapa teks rumit dan langsung mengirimkannya ke pandoc, Anda cukup mengetik:
Kemudian edit buffer Vim hingga Anda memiliki sesuatu seperti:
Kemudian simpan dan keluar (dengan
:x
) dan semuanya akan dijalankan sebagai perintah shell.Ini juga akan tersedia dalam riwayat perintah shell Anda.
sumber
EDITOR
variabel lingkungan kevim
dan menekanCtrl-X
diikuti denganCtrl-E
saat mengedit baris perintah.Berjalan di saluran pipa
Mencoba:
Kuncinya adalah bahwa, untuk dapat menggunakan secara
vim
normal,vim
perlu stdout menjadi terminal. Kami melakukannya di sini dengan pengalihan>/dev/tty
.Untuk tujuan keamanan, saya meletakkan file sementara di direktori home pengguna. Untuk lebih lanjut tentang ini, lihat FAQ FAQ Pertanyaan 062 Greg . Ini menghilangkan kebutuhan untuk menggunakan nama file yang tidak jelas.
Contoh:
Ketika
vim
terbuka, saya mengetikThis function succeeded.
dan menyimpan file. Hasilnya di layar terlihat seperti:Meskipun output dari
quickedit
dialihkan ke saluran pipa,vim
masih berfungsi normal karena kami telah memberikan akses langsung ke/dev/tty
.Menjalankan program dari dalam vim
Seperti yang saya sebutkan di komentar, vim dapat mengirim file ke perintah. Dari dalam vim, misalnya, berikan perintah
:w !pandoc -o file.pdf
(Catatan: ruang antara w dan! Sangat penting).sumber
trap '...' exit
gagal tetapitrap '...' EXIT
tampaknya berfungsi. Saya tidak tahu banyak tentang menjebak, tetapi pendekatan umum saya untuk file sementara adalah menggunakanmktmp [--suffix=...]
. Juga,vim <outfile> -c '...' >/dev/tty
berjalan seperti biasa sampai file dimuat, kemudian jalankan rantai perintah yang diberikan, termasuk:wq
jika Anda ingin melewati fase pengeditan. Saya juga menggunakanset | grep -a EXIT
dan menemukansignals=(EXIT ... DEBUG)
.Pastikan bahwa
vim
ditetapkan sebagai editor default Anda (misalnyaexport EDITOR=vim
di.bash_profile
atau.bashrc
. Kemudian, pada prompt apa pun, Anda dapat mengetik Ctrl- Xdiikuti oleh Ctrl- E. Ini akan membuka baris perintah Anda saat ini di editor yang dikonfigurasi (misvim
.). Edit, simpan dan keluar, dan perintah akan dieksekusi seolah-olah Anda telah mengetiknya di baris perintah, termasuk pipa dan sejenisnya.sumber