Saya ingin dapat menggunakan hasil dari perintah yang dieksekusi terakhir di perintah berikutnya. Sebagai contoh,
$ find . -name foo.txt
./home/user/some/directory/foo.txt
Sekarang katakanlah saya ingin dapat membuka file dalam editor, atau menghapusnya, atau melakukan sesuatu yang lain dengan itu, misalnya
mv <some-variable-that-contains-the-result> /some/new/location
Bagaimana saya bisa melakukannya? Mungkin menggunakan beberapa variabel bash?
Memperbarui:
Untuk memperjelas, saya tidak ingin menetapkan hal-hal secara manual. Apa yang saya kejar adalah sesuatu seperti variabel bash bawaan, misalnya
ls /tmp
cd $_
$_
memegang argumen terakhir dari perintah sebelumnya. Saya menginginkan sesuatu yang serupa, tetapi dengan output dari perintah terakhir.
Pembaruan terakhir:
Jawaban Seth telah bekerja dengan cukup baik. Beberapa hal yang perlu diingat:
- jangan lupa
touch /tmp/x
ketika mencoba solusi untuk pertama kalinya - hasilnya hanya akan disimpan jika kode keluar perintah terakhir berhasil
linux
bash
command-line
armandino
sumber
sumber
Jawaban:
Ini adalah solusi yang benar-benar gila, tetapi tampaknya sebagian besar berfungsi beberapa waktu. Selama pengujian, saya mencatat kadang-kadang tidak bekerja dengan baik ketika mendapatkan ^Cdi baris perintah, meskipun saya sedikit mengubah sedikit untuk berperilaku sedikit lebih baik.
Peretasan ini hanya peretasan mode interaktif, dan saya cukup yakin bahwa saya tidak akan merekomendasikannya kepada siapa pun. Perintah latar belakang cenderung menyebabkan perilaku yang bahkan lebih tidak terdefinisi daripada normal. Jawaban lainnya adalah cara yang lebih baik untuk mendapatkan hasil secara terprogram.
Yang sedang berkata, inilah "solusi":
Setel variabel lingkungan bash ini dan berikan perintah yang diinginkan.
$LAST
biasanya akan memiliki output yang Anda cari:sumber
PROMPT_COMMAND='last="$(cat /tmp/last)";lasterr="$(cat /tmp/lasterr)"; exec >/dev/tty; exec > >(tee /tmp/last); exec 2>/dev/tty; exec 2> >(tee /tmp/lasterr)'
yang menyediakan keduanya$last
dan$lasterr
.No such file or directory
2> >(tee /tmp/lasterr 1>&2)
karena output standartee
harus diarahkan kembali ke kesalahan standar.Saya tidak tahu ada variabel yang melakukan ini secara otomatis . Untuk melakukan sesuatu selain dari hanya menyalin hasil, Anda dapat menjalankan kembali apa pun yang baru saja Anda lakukan, misalnya
Dimana
!!
ekspansi sejarah berarti 'perintah sebelumnya'.Jika Anda berharap akan ada nama file tunggal dengan spasi atau karakter lain di dalamnya yang dapat mencegah penguraian argumen yang tepat, kutip hasilnya (
vim "$(!!)"
). Membiarkannya tanpa tanda kutip akan memungkinkan banyak file dibuka sekaligus selama tidak menyertakan spasi atau token penguraian shell lainnya.sumber
vim `!!`
date "+%N"
dan kemudianecho $(!!)
Bash adalah jenis bahasa yang jelek. Ya, Anda dapat menetapkan output ke variabel
Tapi lebih baik berharap yang tersulit kamu itufind
hanya mengembalikan satu hasil dan bahwa hasil itu tidak memiliki karakter "aneh" di dalamnya, seperti carriage return atau umpan baris, karena mereka akan diam-diam dimodifikasi ketika ditugaskan ke variabel Bash.Tapi lebih baik hati-hati mengutip variabel Anda dengan benar saat menggunakannya!
Lebih baik untuk bertindak pada file secara langsung, misalnya dengan
find
's-execdir
(konsultasikan manual).atau
sumber
echo "${MY_VAR}"
untuk melihat hal ini.Ada lebih dari satu cara untuk melakukan ini. Salah satu caranya adalah dengan menggunakan
v=$(command)
yang akan menugaskan output perintahv
. Sebagai contoh:Dan Anda dapat menggunakan backquote juga.
Dari Bash Beginners Guide ,
EDIT: Setelah diedit dalam pertanyaan, tampaknya ini bukan hal yang dicari OP. Sejauh yang saya tahu, tidak ada variabel khusus seperti
$_
untuk output dari perintah terakhir.sumber
Cukup mudah. Gunakan kutipan balik:
Dan kemudian Anda dapat menggunakannya kapan saja di masa depan
sumber
Disclamers:
Saat menjalankan shell interaktif di tmux, Anda dapat dengan mudah mengakses data yang saat ini ditampilkan di terminal. Mari kita lihat beberapa perintah menarik:
Ya, ini memberi kami banyak kemungkinan sekarang :) Sedangkan bagi saya, saya membuat alias sederhana:
alias L="tmux capture-pane; tmux showb -b 0 | tail -n 3 | head -n 1"
dan sekarang setiap kali saya perlu mengakses baris terakhir yang saya gunakan$(L)
untuk mendapatkannya.Ini tidak tergantung pada aliran output yang digunakan program (baik stdin atau stderr), metode pencetakan (ncurses, dll.) Dan kode keluar program - data hanya perlu ditampilkan.
sumber
Saya pikir Anda mungkin bisa meretas solusi yang melibatkan pengaturan shell Anda ke skrip yang berisi:
Kemudian jika Anda mengatur
$PROMPT_COMMAND
untuk mengeluarkan pembatas, Anda dapat menulis fungsi pembantu (mungkin disebut_
) yang memberi Anda potongan terakhir dari log itu, sehingga Anda dapat menggunakannya seperti:sumber
Anda dapat mengatur alias berikut di profil bash Anda:
Kemudian, dengan mengetikkan 's' setelah perintah arbitrer, Anda dapat menyimpan hasilnya ke variabel shell 'itu'.
Jadi contoh penggunaannya adalah:
sumber
grab
fungsi saya yang menyalin baris ke-n dari perintah terakhir ke clipboard gist.github.com/davidhq/f37ac87bc77f27c5027eSaya baru saja menyaring
bash
fungsi ini dari saran di sini:Kemudian, Anda cukup melakukan:
Update : seorang pengguna anonim disarankan untuk mengganti
echo
denganprintf '%s\n'
yang memiliki keuntungan bahwa itu tidak pilihan proses seperti-e
dalam teks meraih. Jadi, jika Anda mengharapkan atau mengalami kekhasan seperti itu, pertimbangkan saran ini. Pilihan lain adalah menggunakancat <<<$grab
.sumber
cat <<<$grab
pilihannya?man bash
: "Sini Strings: Varian dari dokumen di sini, formatnya adalah:<<<word
Kata tersebut diperluas dan dipasok ke perintah pada input standarnya." Jadi, nilai$grab
diumpankan kecat
stdin, dancat
masukkan saja kembali ke stdout.Dengan mengatakan "Saya ingin dapat menggunakan hasil dari perintah yang dieksekusi terakhir dalam perintah berikutnya", saya berasumsi - maksud Anda adalah hasil dari setiap perintah, bukan hanya menemukan.
Jika itu masalahnya - xargs adalah apa yang Anda cari.
find . -name foo.txt -print0 | xargs -0 -I{} mv {} /some/new/location/{}
ATAU jika Anda tertarik untuk melihat hasilnya terlebih dahulu:
find . -name foo.txt -print0
!! | xargs -0 -I{} mv {} /some/new/location/{}
Perintah ini berkaitan dengan banyak file dan berfungsi seperti jimat bahkan jika path dan / atau nama file mengandung spasi.
Perhatikan bagian mv {} / some / new / location / {} dari perintah. Perintah ini dibuat dan dieksekusi untuk setiap baris yang dicetak oleh perintah sebelumnya. Di sini baris yang dicetak oleh perintah sebelumnya diganti dengan {} .
Kutipan dari halaman manual xargs:
Untuk detail lebih lanjut lihat halaman manual:
man xargs
sumber
Tangkap output dengan backticks:
sumber
Saya biasanya melakukan apa yang disarankan orang lain di sini ... tanpa tugas:
Anda bisa menjadi pelamun jika Anda suka:
sumber
Jika yang Anda inginkan adalah menjalankan kembali perintah terakhir Anda dan mendapatkan output, variabel bash sederhana akan berfungsi:
Jadi, Anda dapat menjalankan perintah pada output dengan:
Ini akan menelurkan proses baru dan jalankan kembali perintah Anda, kemudian memberi Anda output. Kedengarannya seperti apa yang benar-benar Anda inginkan akan menjadi file bash history untuk output perintah Ini berarti Anda harus menangkap output yang dikirimkan bash ke terminal Anda. Anda bisa menulis sesuatu untuk menonton / dev atau / proc yang diperlukan, tapi itu berantakan. Anda juga bisa membuat "pipa khusus" antara istilah Anda dan bash dengan perintah tee di tengah yang mengarahkan ke file output Anda.
Namun keduanya merupakan solusi yang bersifat meretas. Saya pikir yang terbaik adalah terminator yang merupakan terminal yang lebih modern dengan output logging. Cukup periksa file log Anda untuk hasil dari perintah terakhir. Variabel bash mirip dengan di atas akan membuat ini lebih sederhana.
sumber
Inilah salah satu cara untuk melakukannya setelah Anda menjalankan perintah dan memutuskan bahwa Anda ingin menyimpan hasilnya dalam sebuah variabel:
Atau jika Anda tahu sebelumnya bahwa Anda ingin hasil dalam variabel, Anda dapat menggunakan backticks:
sumber
Sebagai alternatif dari jawaban yang ada: Gunakan
while
jika nama file Anda dapat berisi ruang kosong seperti ini:Seperti yang saya tulis, perbedaannya hanya relevan jika Anda harus mengharapkan kosong dalam nama file.
NB: satu-satunya hal bawaan bukan tentang output tetapi tentang status perintah terakhir.
sumber
Anda dapat menggunakan !!: 1. Contoh:
sumber
Saya memiliki kebutuhan yang sama, di mana saya ingin menggunakan output dari perintah terakhir ke yang berikutnya. Mirip seperti | (pipa). misalnya
untuk sesuatu seperti -
Solusi: Membuat pipa khusus ini. Sangat sederhana, menggunakan xargs -
Pada dasarnya bukan apa-apa dengan membuat tulisan tangan pendek untuk xargs, itu berfungsi seperti pesona, dan sangat berguna. Saya hanya menambahkan alias dalam file .bash_profile.
sumber
Ini dapat dilakukan dengan menggunakan keajaiban deskriptor file dan
lastpipe
opsi shell.Itu harus dilakukan dengan skrip - opsi "lastpipe" tidak akan berfungsi dalam mode interaktif.
Berikut skrip yang telah saya uji:
Yang saya lakukan di sini adalah:
mengatur opsi shell
shopt -s lastpipe
. Ini tidak akan berfungsi tanpa ini karena Anda akan kehilangan deskriptor file.memastikan stderr saya juga ditangkap
2>&1
piping output ke fungsi sehingga deskriptor file stdin dapat direferensikan.
pengaturan variabel dengan mendapatkan isi
/proc/self/fd/0
deskriptor file, yaitu stdin.Saya menggunakan ini untuk menangkap kesalahan dalam skrip jadi jika ada masalah dengan perintah saya bisa berhenti memproses skrip dan keluar segera.
Dengan cara ini saya dapat menambahkan di
2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msg
balik setiap perintah yang ingin saya periksa.Sekarang Anda dapat menikmati output Anda!
sumber
Ini bukan semata-mata solusi bash tetapi Anda bisa menggunakan piping dengan sed untuk mendapatkan baris terakhir dari perintah keluaran sebelumnya.
Pertama mari kita lihat apa yang ada di folder "a"
Kemudian, contoh Anda dengan ls dan cd akan berubah menjadi sed & piping menjadi sesuatu seperti ini:
Jadi, keajaiban yang sebenarnya terjadi dengan sed, Anda menyalurkan output apa pun dari perintah yang pernah ada ke sed dan mencetak baris terakhir yang dapat Anda gunakan sebagai parameter dengan kutu belakang. Atau Anda dapat menggabungkannya ke xargs juga. ("man xargs" di shell adalah teman Anda)
sumber
Shell tidak memiliki simbol khusus seperti perl yang menyimpan hasil gema dari perintah terakhir.
Belajar menggunakan simbol pipa dengan awk.
Pada contoh di atas Anda bisa melakukan:
sumber
adalah cara lain, meskipun kotor.
sumber
Saya ingat untuk mem-pipe output dari perintah saya ke file tertentu menjadi sedikit mengganggu, solusi saya adalah fungsi di saya
.bash_profile
yang menangkap output dalam file dan mengembalikan hasilnya ketika Anda membutuhkannya.Keuntungan dengan yang satu ini adalah Anda tidak perlu menjalankan ulang seluruh perintah (saat menggunakan
find
atau perintah jangka panjang lainnya yang bisa menjadi sangat penting)Cukup sederhana, rekatkan ini di
.bash_profile
:Naskah
Pemakaian
Pada titik ini, saya cenderung hanya menambahkan
| catch
ke akhir dari semua perintah saya, karena tidak ada biaya untuk melakukannya dan menghemat saya harus menjalankan kembali perintah yang membutuhkan waktu lama untuk menyelesaikannya.Juga, jika Anda ingin membuka output file dalam editor teks, Anda dapat melakukan ini:
sumber