Xóa các dòng nhắc cũ trong bash để tiết kiệm không gian cuộn


11

Chủ đề thiết bị đầu cuối của tôi đã từng như thế này,

thiết bị đầu cuối trước

Nhưng tôi nghĩ rằng nhắc nhở lãng phí rất nhiều không gian. Và sau đó tôi có một ý tưởng rằng tôi có thể xóa dấu nhắc mỗi khi tôi chạy lệnh. Tôi đã sử dụng bash, một trong những giải pháp là sử dụng preexec_invoke_execchức năng.

Tôi sử dụng lệnh sau để xóa các ký tự nhắc nhở cuối cùng:

echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"

Vì vậy, thiết bị đầu cuối rất sạch sẽ, như thế này,

nhập mô tả hình ảnh ở đây

Nhưng bây giờ vấn đề của tôi là, sẽ có vấn đề nếu tôi muốn sử dụng nhiều lệnh trong một dòng , giả sử, khi tôi sử dụng for i in ....

Đây là phiên bản đầy đủ của hàm trong .bashrc của tôi,

preexec () { echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"; echo -n "$1"; echo -ne "  \033[37;2m["; echo -n "$2"; echo -ne "]\033[0m\n"; }
preexec_invoke_exec () {
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`; 
    preexec "$this_command" "$this_pwd"
}
trap 'preexec_invoke_exec' DEBUG

Thủ thuật zsh Glyph Lefkowitz - tốt đẹp!

2
Dễ dàng bắt đầu với giải pháp zsh...
Gilles 'stop Somali vốn là xấu'

Tôi đã bỏ lỡ câu hỏi của bạn ở đó ...
David Hoelzer

@DavidHoelzer Vâng, nếu bạn làm for i in $(seq 1 10); do ls; donevới chức năng của anh ta, đầu ra của các lệnh lặp sẽ bị "nuốt" để nói. Vì vậy, OP muốn vệ sinh hành vi trong khi kích hoạt dấu nhắc đó. Lý do tại sao tôi ủng hộ điều này là sự quan tâm đến nhận thức về vỏ, tính khả dụng, phản hồi và tính di động. Liên kết mà tôi đã đưa ra trong nhận xét trước đây của mình dẫn đến bài đăng trên superuser - họ đã gặp rắc rối khi gán đoạn mã này, vì vậy đây là một nguyên mẫu mô phỏng chức năng zsh gốc (mà tôi nghĩ là thú vị), dưới dạng chức năng bẫy đây.

Câu trả lời:


3

Đầu tiên preexec_invoke_execphải được sửa đổi để ngăn chặn nhiều vụ hành quyết preexec. Ngoài ra, sửa đổi preexecđể tính đến số lượng dòng thực tế trong $PS1:

preexec () { 
    # delete old prompt; one "\e[1A\e[K" per line of $PS1
    for (( i=0, l=$(echo -e $PS1 | wc -l) ; i < l ; i++ ))
    do             
        echo -ne "\e[1A\e[K"
    done
    # replacement for prompt
    echo -ne "\e[31;1m$ \e[0m"
    echo -n "$1"
    echo -ne "  \e[37;2m["
    echo -n "$2"
    echo -e "]\e[0m"
}

preexec_invoke_exec () {
    [ -n "$DONTCLEANPROMPT" ] && return
    DONTCLEANPROMPT=x
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`
    preexec "$this_command" "$this_pwd"
}

trap 'preexec_invoke_exec' DEBUG

PROMPT_COMMAND='unset DONTCLEANPROMPT'

Để preexecđược chạy lại, DONTCLEANPROMPTphải được đặt hoặc đặt thành ''. Điều này được thực hiện với PROMPT_COMMAND, được chạy ngay trước khi dấu nhắc chính được ban hành. Do đó preexecsẽ được chạy một lần và chỉ một lần cho mỗi dòng lệnh.


Giải pháp của bạn giải quyết vấn đề với forvòng lặp! Cảm ơn bạn! Có một sự bất tiện hơn nữa. Điều gì xảy ra là nếu bạn thực hiện lslệnh và bạn có đầu ra, sau đó bạn thực hiện một lệnh khác ls, bạn sẽ thấy dòng cuối cùng của đầu ra trước đó bị xóa ... bạn có biết làm thế nào để giải quyết điều đó không?

1
Bạn có thể đang sử dụng một dấu nhắc chỉ với một dòng duy nhất. Thay đổi tiếng vang đầu tiên prexecđể in "\033[1A\033[K\033[31;1m$ \033[0m", đó chỉ là một \033[1A\033[K(di chuyển 1 dòng lên, xóa cho đến hết dòng) thay vì hai.
Adaephon

Hoàn hảo! Cảm ơn bạn rất nhiều cho giải pháp của bạn và dành thời gian để giải thích. Điều này giải quyết vấn đề của OP và gỡ lỗi giải pháp hơn nữa. Làm cho nó có thể sử dụng cho tất cả mọi người! Chúc mừng!
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.