Làm cách nào để cấu hình bash để in trạng thái thoát cho mỗi lệnh?


12

Mỗi lệnh chạy trong bash trả về với một mã thoát.

Bất cứ khi nào tôi gõ một lệnh trên bash prompt, tôi muốn nó hiển thị trạng thái thoát, tức là echo $?

ví dụ: nếu tôi chạy echo "hello";trên dấu nhắc bash, đầu ra sẽ là:

linux@linux$ hello
linux@linux$ 0

Điều gì về việc đăng câu hỏi của bạn trên unix.stackexchange.com ?

Cảm ơn @Frank. Nhưng nó cũng không phải là một nơi tốt để đặt câu hỏi này?
ravidixit

Tôi đã thử in itas một phần của biến PS1, nhưng không hoạt động vì lý do tôi chưa hiểu.
ravidixit

Câu trả lời:


13

Mã thoát khỏi lệnh thực thi cuối cùng được lưu trữ trong $?biến môi trường. Vì vậy, bạn chỉ có thể thêm biến này vào dấu nhắc lệnh mặc định và bạn sẽ luôn có mã thoát được in ở đó. Dấu nhắc được lưu trữ trong $PS1biến môi trường. Nó ban đầu được đặt trong /etc/bash.bashrckịch bản và sau đó trong $HOME/.bashrc.

Vì vậy, chỉnh sửa dòng trong $HOME/.bashrc( /etc/bash.bashrcsẽ là toàn hệ thống) từ giá trị mặc định của nó:

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

đến đây (ví dụ):

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w[$?] \$ '

Vì vậy, lời nhắc mặc định đã thay đổi thành:

user@host:/path/to/dir[0] $

Số 0 trong ngoặc là mã thoát của bạn, xem:

user@host:~[0] $ ls
user@host:~[0] $ ls /root/
ls: cannot open directory /root/: Permission denied
user@host:~[2] $ ^C
user@host:~[130] $

Để biết ý nghĩa, hãy xem http://www.tldp.org/LDP/abs/html/exitcodes.html


Tôi đã thử làm nó nhưng với bash trong tay, nó không hoạt động. nó luôn hiển thị [0] cho máy tôi đang làm việc.
ravidixit

Bạn có chắc chắn rằng bạn chạy bash? Bạn có thể sao chép đầu ra của readlink /proc/$$/exexin vui lòng? 0 có nghĩa là không có lỗi, có bạn đã thử một cái gì đó cho một lỗi: ^Choặc falsehoặc asdasdasd?
hỗn loạn

1
@chaos Tôi có PS1 của mình PS1=$(printf "%s\\\\u@\h:%s%s\w[$?]$%s " "$yellow" "$end" "$blue" "$end"), nhưng nó chỉ hiển thị 0mọi lúc. Bất cứ ý tưởng tại sao?
Tối đa

1
Sẽ thật tuyệt, nếu trạng thái thoát sẽ chỉ được hiển thị, nếu nó không bằng 0
rubo77

1
@max Đó là vì bạn $?đã được mở rộng 0khi cài đặt PS1. Làm echo $PS1và bạn sẽ thấy. Bạn phải sử dụng dấu ngoặc đơn, hoặc thoát nó như thế nào \$?.
wvducky

7

Một cách khác mà tôi đã chọn từ Arch Wiki là sử dụng trap:

EC() { echo -e '\e[1;33m'code $?'\e[m\n'; }
trap EC ERR

Hiệu ứng:

$ ( exit 1 )
code 1

$ some-non-existent-command
some-non-existent-command: command not found
code 127

$

2
Điều đó không hoàn toàn đáp ứng yêu cầu của OP, vì anh ấy muốn in trạng thái thoát ngay cả khi nó bằng không - nhưng đó chính xác là những gì tôi đang tìm kiếm.
Keith Thompson

2

Đây là một ví dụ đơn giản:

PS1='$? > '

Nếu sử dụng dấu ngoặc kép, thì bạn phải thêm dấu gạch chéo ngược để thoát $:

PS1="\$? > "

Đầu ra:

0 > echo 'ok'
ok
0 > bogus
bogus: command not found
127 > 

Một cách thậm chí tốt hơn là chỉ in mã thoát khi nó khác không.

PS1='${?#0}> '    # single quote example
PS1="\${?#0}> "   # double quote example (requires extra backslash)

Đầu ra mẫu:

> echo 'ok'
ok
> bogus
bogus: command not found
127> 

Giải thích: ${var#pattern}là một mở rộng tham số bash có nghĩa là loại bỏ mẫu phù hợp ngắn nhất khỏi mặt trước của $ var. Vì vậy, trong trường hợp này, chúng tôi sẽ xóa 0từ phía trước $?, điều này sẽ cắt ngắn một cách hiệu quả mã thoát 0.

Nếu sử dụng dấu ngoặc kép, $?sẽ được thay thế khi PS1được đặt, thay vì được đánh giá mỗi lần. Làm echo $PS1để xác nhận rằng bạn không có giá trị mã hóa cứng PS1.


Cảm ơn bạn từ tháng 1 năm 2018. Tôi muốn lời nhắc bình thường với mã thoát ngay từ đầu nếu nó khác không - điều này giúp ích rất nhiều.
SDsole
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.