Làm thế nào để tôi dẫn từng lệnh được đưa vào shell?


14

Tôi muốn chỉnh sửa .bashrc của mình để mọi lệnh được thực thi trên shell được chuyển sang một cái gì đó, ví dụ:

 $ sudo apt update
  _________________
< sudo apt update >
 -----------------
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||

Tôi đã quản lý một cái gì đó khá giống nhau, nhưng không hoàn toàn:

$ bash
$ exec > >(cowsay)
$ echo "Hello AU!"
$ exit
 _______
< Hello AU! >
 -------
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||

Nó không phải là kết quả mong muốn, vì nó chỉ xảy ra sau khi thoát khỏi shell hiện tại.

Nó chủ yếu cho mục đích vui chơi / học tập.


Sử dụng -ncờ để cowsayhữu ích; nó làm cho nó bảo tồn khoảng trắng
wjandrea

Câu trả lời:


12

Bạn có thể điều chỉnh phương pháp của mình một chút. Thay vì dẫn cowsaytrực tiếp, hãy đọc đầu ra cho đến khi ký tự phân cách, gửi đầu ra đó đến cowsay, sau đó in ký tự đó sau mỗi lệnh:

exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
PROMPT_COMMAND='printf "\0"'

Ở đây, tôi đang sử dụng ký tự ASCII NUL. Bạn có thể sử dụng một cái gì đó không có khả năng xuất hiện trong đầu ra lệnh.

Điều này sẽ in sau lời nhắc, vì vậy đầu ra sẽ xấu:

$ export LC_ALL=C
$ exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
$ PROMPT_COMMAND='printf "\0"'
$ ls
$
 ______________________________________
/ Desktop Documents Downloads Music    \
| Pictures Public Templates Videos
\ examples.desktop                     /
 --------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

$ echo foo
$
 ______
< foo  >
 ------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Lưu ý rằng điều này sẽ phá vỡ bất kỳ lệnh nào thử đầu ra phức tạp hoặc có giao diện người dùng văn bản (nghĩ rằng các trình soạn thảo dòng lệnh, máy nhắn tin, v.v.).

Giả sử bạn đã biết những gì exec > >(...), phần trong quá trình thay thế là:

  • while IFS= read -d '' -r line; do ... done: đây là một thành ngữ khá phổ biến để đọc dữ liệu được giới hạn bởi ký tự ASCII NUL:

    • IFS= đặt IFS thành chuỗi trống, vô hiệu hóa tách trường
    • -rngăn không cho readxử lý \trong đầu vào một cách đặc biệt ( \nví dụ, vì vậy , được đọc dưới dạng \nvà không được chuyển đổi thành ký tự dòng mới).
    • -d ''là cách readđể đọc cho đến khi ký tự NUL

    Vì vậy, toàn bộ các vòng lặp trên đầu vào trong các phần được phân định bằng NUL, trong khi bảo tồn nội dung của đầu vào càng nhiều càng tốt.

  • if [[ -n $line ]]; then ... fi; done - chỉ hành động nếu đầu vào đọc cho đến nay không trống.
  • echo; printf "%s\n" "$line" | cowsay;- in một dòng trống hàng đầu, sao cho đầu ra coway không xung đột với dấu nhắc, và sau đó gửi đầu vào đọc cho đến coway. printfđáng tin cậy và an toàn hơn echo.

1
Vì lời nhắc của tôi có ngắt dòng trong đó, đầu ra coway không xung đột với phần thứ hai của nó - cũng có thể đặt dấu nhắc thành thứ gì đó không gây xao lãng?
tráng miệng

16

Bạn có thể trapvà lạm dụng DEBUGtín hiệu của bash :

trap 'bash -c "$BASH_COMMAND" | cowsay' DEBUG

Chạy ví dụ

$ trap 'bash -c "$BASH_COMMAND" | cowsay' DEBUG
$ echo "AU is awesome!"
 __________________
< AU is awesome! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
AU is awesome!

Tuy nhiên, điều này vẫn sẽ thực hiện lệnh sau đó. Nhờ ilkkachu tôi đã tìm ra cách giải quyết:

$ shopt -s extdebug
$ trap 'bash -c "$BASH_COMMAND" | cowsay; false' DEBUG
$ echo "AU is awesome!"
 __________________
< AU is awesome! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.