Cara membersihkan output dari perintah 'script' linux

35

Saya menggunakan perintah 'script' linux http://www.linuxcommand.org/man_pages/script1.html untuk melacak beberapa sesi interaktif. File keluaran dari yang berisi karakter yang tidak dapat dicetak, termasuk penekanan tombol backspace saya.

Apakah ada cara untuk merapikan file output ini sehingga hanya berisi apa yang ditampilkan di layar?

Atau adakah cara lain untuk merekam sesi shell interaktif (input dan output)?

Andrew
sumber
"Atau adakah cara lain untuk merekam sesi shell interaktif (input dan output)?" Apakah Anda tahu asciinema.org ?
masterxilo

Jawaban:

34

Jika Anda ingin melihat file, maka Anda dapat mengirim output melalui col -bp; ini mengartikan karakter kontrol. Maka Anda bisa menyalurkan lebih sedikit, jika mau.

col -bp typescript | less -R

Pada beberapa sistem coltidak akan menerima argumen nama file, gunakan sintaks ini sebagai gantinya:

col -bp <typescript | less -R
Arcege
sumber
1
pada sistem saya, coltidak akan menerima nama file, jadi saya lakukan col -bp < typescript dan mendapatkan apa yang saya inginkan.
Andrew
Tidak bekerja untuk saya, mengacak beberapa output.
Alex
1
Pada sistem saya less -Rdengan sendirinya memberikan output yang lebih baik daripada pemipaan col -bpterlebih dahulu.
Brian Hawkins
@BrianHawkins Saya setuju. Menggunakan col -bp <typescript | less -Rtidak menampilkan konsol berwarna. Menggunakan less -R typescriptmemang menampilkan konsol berwarna!
Trevor Boyd Smith
ini hanya baik jika Anda ingin melihat skrip secara interaktif less.
Trevor Boyd Smith
18
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed

inilah beberapa interpretasi input string ke perl:

  • s/pattern//gberarti melakukan substitusi pada keseluruhan ( gopsi berarti melakukan semuanya alih-alih berhenti pada pengganti pertama) string input

inilah beberapa interpretasi dari pola regex:

  • \e cocok dengan karakter kontrol "pelarian" khusus (ASCII 0x1A)
  • (dan )merupakan awal dan akhir suatu grup
  • |berarti grup dapat mencocokkan salah satu pola N. dimana pola N berada
    • [^\[\]] atau
    • \[.*?[a-zA-Z] atau
    • \].*?\a
  • [^\[\]] cara
    • cocok dengan sekumpulan karakter NOT di mana karakter bukan berada [dan]
  • \[.*?[a-zA-Z] cara
    • cocokkan string yang dimulai dengan [kemudian lakukan non-serakah .*?sampai karakter alfa pertama
  • \].*?\a cara
    • cocokkan string yang dimulai dengan ]kemudian lakukan non-serakah .*?sampai Anda menekan karakter kontrol khusus yang disebut "karakter lansiran (bel)"
Peter Nore
sumber
1
Saya masih perlu mencari tahu bagaimana, tetapi ini benar-benar berfungsi;)
asdmin
@ asdmin - Pada dasarnya, ini menggemakan output dari typescriptke perlprogram yang menghilangkan karakter kontrol tertentu dari output, kemudian menyalurkan output ke colperintah unix , yang -bopsi menghapus artefak kunci "hapus" dalam transkrip. Kemudian pipa output ke file teks.
Peter Nore
Ini mengacak output di baris pertama naskah untuk saya tetapi merupakan jawaban terbaik.
Alex
Ini tampaknya bekerja dengan sangat baik dengan beberapa naskah naskah; itu tentu lebih mudah dibaca daripada output yang dihasilkan oleh jawaban yang diterima.
fakedad
jawaban legendaris!
Zack
2

Untuk sejumlah besar scriptoutput, saya akan meretas skrip perl secara iteratif. Kalau tidak, edit tangan dengan editor yang baik.

Tidak mungkin ada metode otomatis yang ada untuk menghapus karakter kontrol dari scriptoutput dengan cara yang mereproduksi apa yang ditampilkan di layar pada saat-saat penting tertentu (seperti ketika tuan rumah sedang menunggu karakter pertama dari beberapa input pengguna).

Misalnya layar mungkin kosong kecuali Andrew $, jika Anda kemudian mengetik rm /*dan menekan backspace dua belas kali (jauh lebih banyak dari yang diperlukan), apa yang ditampilkan pada layar pada akhirnya tergantung pada apa yang sedang berjalan, apa sttypengaturan Anda saat ini ( yang mungkin Anda ubah sebagian saat sesi berlangsung) dan mungkin beberapa faktor lain juga.

Di atas berlaku untuk metode otomatis menangkap input dan output secara terus menerus. Alternatif utama adalah mengambil "tangkapan layar" atau memotong dan menempelkan layar pada waktu yang tepat selama sesi (yang saya lakukan untuk panduan pengguna, catatan untuk log harian, dll).

RedGrittyBrick
sumber
2

Saya menggunakan cat filenameyang menghilangkan karakter kontrol :-)

Peeyush
sumber
imo ini adalah jawaban yang lebih baik, karena itu benar-benar menghilangkan semua karakter kontrol.
Nathanael Farley
di OSX, cat tidak menghapus karakter kontrol warna ...
Nick
9
Sebenarnya cat tidak menghapus karakter kontrol sama sekali, melainkan mengeluarkannya kata demi kata, dan terminal kemudian menafsirkannya. Itu mungkin bekerja untuk Anda jika naskah Anda relatif pendek ke buffer terminal Anda dan Anda bisa menyalin dan menempel dari terminal. Tidak begitu baik jika naskah Anda besar.
mc0e
1
Sepakat. Ini tidak menghapus apa pun. Ini hanya memungkinkan shell untuk menafsirkannya. Mereka masih ada.
Kentgrav
2

Jika yang Anda kejar adalah merekam perintah Anda (mis. Untuk kemudian mengubahnya menjadi skrip bash), maka peretasan yang masuk akal harus dijalankan script(1), kemudian di dalamnya jalankan

bash -x

Setelah itu grepfile output (biasanya "naskah") mencari baris yang dimulai dengan "+". Ekspresi reguler ^\+akan melakukan trik.

Yaron
sumber
2

Jika Anda ingin menulis output ke file:

col -bp < typescript >>newfile

gunakan perintah unix2dos untuk mengonversi file ke format Windows jika Anda mau

amara
sumber
1
Di Ubuntu 14.04, itu menyisakan banyak sampah di awal dan akhir baris. Cukup mudah dibaca, tetapi tidak terlalu bersih.
mc0e
2

col -bp memproses backspaces seperti yang diinginkan (AFAIK). Tapi itu mengubah urutan warna. Mungkin bagus untuk menghapus urutan warna terlebih dahulu, kemudian memproses backspaces, jika memungkinkan.

Ini adalah kebutuhan yang sangat umum, dan saya terkejut tidak ada lebih banyak solusi untuk itu. Sangat umum untuk skrip sesi, maka seseorang harus meninjau prosedur. Anda ingin memotong semua kesalahan pengetikan kecil, dan urutan pelarian warna untuk membuat skrip "bersih" dari prosedur untuk referensi di masa mendatang. Teks ASCII sederhana lebih disukai. Saya pikir inilah yang dimaksud dengan "dapat dibaca manusia", dan itu adalah hal yang sangat masuk akal untuk dilakukan.

Harun
sumber
1

Saya menemukan jawaban bahwa dewtall memberikan pertanyaan serupa di papan Unix agar lebih efektif dalam menghilangkan karakter kontrol dari output skrip jika Anda berada di lingkungan di mana Perl tersedia untuk Anda.

skrip dewtall:

#!/usr/bin/perl
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \r | # Remove extra carriage returns also
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
       1 while s/[^\b][\b]//g;  # remove all non-backspace followed by backspace
    print;
}

Untuk menghapus karakter kontrol:

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed
rynemcall
sumber
1

https://github.com/RadixSeven/typescript2txt ditulis untuk mengatasi masalah ini.

Sudah 4 tahun sejak saya terakhir diperbarui / menggunakannya, tapi saya tidak ingat melakukan sesuatu yang mewah yang seharusnya tidak berfungsi hari ini.

Eponim
sumber
0

Saya menemukan cara yang baik untuk melakukannya. Di sistem saya, jalur output panjang ditaburi dengan "^ M" (ruang kosong diikuti oleh carriage return). "^ M" dapat diganti dengan baik dengan karakter nol "^ @", yang tidak ditampilkan sama sekali saat Anda menyimpan file.

Saya menangkap waktu juga, jadi untuk memutar ulang file dengan sempurna, saya tidak bisa menghapus "^ M" sepenuhnya menggunakan perintah di bawah ini (karena scriptreplay menghitung byte):

tr '\r' '\0' | sed 's/ \x0//g'

Saya menjalankan perintah skrip saya seperti ini:

script -t -f session.log 2>timing

Jadi, apa yang saya lakukan setelah itu adalah:

cat session.log | tr '\r' '\0' > typescript 
scriptreplay -t timing | sed 's/ \x0//g'

Hasil edit pertama (sebelum replay) mempertahankan jumlah byte dalam file. Suntingan kedua (setelah replay) menghilangkan ruang putih di tempat acak. (Perhatikan bahwa secara default scriptreplay mencari file input bernama "naskah", itulah sebabnya saya tidak menyediakannya setelah "waktu".)

Khanan
sumber
-1

dos2unix pada output juga akan melakukan trik

albert
sumber
7
Bisakah Anda menjelaskan cara menggunakannya untuk menyelesaikan tugas?
Ben N
-1

Satu solusi lain adalah menggunakan stringsyang hanya mencetak karakter yang dapat dicetak dari file (atau dari input standar):

strings -n 1 filename

The -n 1pilihan menetapkan panjang minimum dari urutan harus dipertahankan untuk satu dan dengan demikian membuat karakter yang dapat dicetak memastikan bahkan tunggal dikelilingi oleh karakter non-printable yang diawetkan.

Satu kelemahan yang mungkin dari pendekatan ini adalah bahwa stringsmenambahkan jeda baris di antara rangkaian karakter yang dapat dicetak yang berdekatan. Misalnya file dengan konten

Foo<SOMECONTROLCHAR>Bar

(di mana <SOMECONTROLCHAR>karakter kontrol atau karakter tidak dapat dicetak lainnya) akan dikembalikan sebagai

Foo
Bar

Masalah lain yang muncul dalam komentar adalah bahwa beberapa urutan karakter kontrol terdiri dari kombinasi karakter yang dapat dicetak dan yang tidak dapat dicetak dan pendekatan ini hanya akan menghilangkan sebagian dari karakter tersebut.

Namun, stringsmelakukan pekerjaan yang baik untuk menghapus karakter kontrol seperti backspace yang disebutkan dalam pertanyaan.

justfortherec
sumber
stringstidak menghapus semua karakter yang tidak dapat dicetak. Ini mengidentifikasi dan mencetak urutan karakter yang dapat dicetak . Itu bukan hal yang sama.
CVn
@ MichaelKjörling, Anda benar, secara default stringshanya mencetak urutan panjang minimum 4. Saya telah memperbaiki jawaban saya dengan menambahkan -n 1opsi yang menetapkan panjang minimum menjadi 1. Terima kasih telah menunjukkan ini.
justfortherec
Jawabannya masih membuat klaim yang sama yang stringsmenghapus semua karakter yang tidak dapat dicetak, jadi masih salah dengan cara yang sama sebelum diedit. Jelas juga rusak karena "beberapa kode warna" (dan kode kontrol pada umumnya) sering terdiri dari karakter yang dapat dicetak dan yang tidak dapat dicetak. Misalnya, urutan kode kontrol untuk mengubah warna teks mungkin di ESC[01;52mmana ESCkarakter pelarian tunggal (nilai byte 27). Menggunakan stringsseperti yang Anda sarankan akan meninggalkan [01;52mdalam output, yang tidak ada artinya.
CVn
Poin bagus, @ MichaelKjörling. Terutama contoh dengan kode warna sangat disayangkan. Terima kasih telah membantu saya meningkatkan jawaban saya. Apakah hasil edit mengatasi masalah Anda dengan tepat? stringsmungkin tidak melakukan pekerjaan yang sama dengan beberapa jawaban lain tetapi IMHO itu adalah pendekatan yang valid untuk menyelesaikan masalah yang dijelaskan dalam pertanyaan.
justfortherec