Bisakah saya membuat semua perintah mendapat umpan balik jika berhasil atau tidak?

11

Kadang-kadang ketika saya menjalankan perintah itu tidak menampilkan output, jadi saya tidak yakin apakah mereka berhasil atau tidak. Apakah mungkin membuat semua perintah mendapat umpan balik jika sudah berjalan dengan benar atau tidak? Atau minimal untuk menampilkan id umpan balik yang telah mereka jalankan (benar atau tidak)

rajlego
sumber
6
Gagasan umum adalah: tidak ada umpan balik berarti berhasil.
Rinzwind
1
Ini tidak sepenuhnya benar. Misalnya, cryptsetupbisa secara default melewatkan beberapa pesan kesalahan. Ini adalah hal yang baik untuk memiliki $?di Anda PS1. Langkah selanjutnya adalah menambahkan waktu saat ini, untuk selalu mengetahui timing perintah;)
d33tah

Jawaban:

11

(Saya pikir karena Anda memposting di dalam Tanya Ubuntu, kami dapat menganggap Anda berbicara tentang shell default, yaitu, Bash .)

Ada jawaban yang sangat bagus dalam pertanyaan Stack Overflow Dalam skrip shell: gema perintah shell saat dijalankan (ini bukan hanya solusi spesifik Ubuntu).

Yang perlu Anda lakukan adalah menggunakan perintah set untuk mengaktifkan verbose atau xtrace.

set -o

akan memberikan daftar parameter yang saat ini beralih ke atas atau off .

set -v

atau versi longform:

set -o verbose

akan mengaktifkan verbose ON .

Saya pikir apa yang Anda inginkan sebenarnya xtrace. Ini tidak hanya akan menggemakan setiap perintah yang Anda jalankan, itu juga akan memperluas parameter dan memberi Anda lebih banyak umpan balik. Jadi jika saya melakukan sesuatu yang konyol seperti mengetik 'hai' di terminal, saya akan mendapatkan gema dari apa yang saya ketik serta laporan / jejak apa yang shell lakukan untuk menjalankan perintah 'hai' (lihat screenshot di bawah ini) ):

Masukkan deskripsi gambar di sini

Untuk mengaktifkan xtrace:

set -x

atau:

set -o xtrace

Untuk menonaktifkan parameter ini, Anda (kontra-intuitif) memanggil perintah yang sama kecuali dengan simbol plus + bukan tanda hubung atau simbol minus, jadi, misalnya:

set +v

akan berubah menjadi OFF , seperti halnya:

set +x

akan berubah xtrace OFF .


Panduan terperinci tentang opsi shell ada di Bab 33. Opsi, Panduan Script Bash Lanjutan .

Benjamin R
sumber
1
Tetapi bagaimana cara kerjanya ketika perintah sudah benar? apakah itu memberikan hasil? katakan untuk perintah whoami >/dev/null.
Pengguna Terdaftar
Ya, tentu saja, itu menggemakan apa yang Anda ketikkan plus parameter tambahan apa pun yang terlibat dalam perintah yang secara diam-diam dipanggil saat menjalankan perintah Anda. Jika maksud Anda, apakah itu mencetak "SUKSES", maka sayangnya, tidak, jawaban Avinash Raj akan melakukan itu.
Benjamin R
@PeterMortensen terima kasih atas suntingan halus yang bagus pada jawaban saya.
Benjamin R
13

Untuk memeriksa apakah beberapa perintah berhasil atau tidak, Anda dapat memeriksa status pengembalian , yang diberikan oleh $?, dari perintah sebelumnya dengan:

echo $?

Status pengembalian 0berarti perintah selesai dengan berhasil, sedangkan output non-nol ( kode kesalahan ) akan berarti beberapa masalah ditemui atau ada kesalahan dan kategori dapat diketahui dari kode kesalahan. Kode kesalahan Linux / C didefinisikan dalam /usr/include/asm-generic/errno-base.hdan /usr/include/asm-generic/errno.h.

Juga di bash, .bashrcmendefinisikan alias alertyang dapat digunakan untuk memberi tahu dengan status penyelesaian. Anda harus melampirkan alias dengan perintah atau perintah kombo seperti ini:

some_command --some-switch; alert

Anda dapat menambahkan baris kode berikut ke ~/.bashrcfile Anda untuk menampilkan status pengembalian dari perintah terakhir yang dijalankan ..

# show the return code of last command executed
PS1='${debian_chroot:+($debian_chroot)}\u@\h(lst ret. $(echo $?) ):\w\$ '

(buka file ~/.bashrcdengan editor teks pilihan Anda, dan salin baris di atas, tempel di file dan simpan. Luncurkan instance baru dari terminal, dan Anda harus memilikinya dalam tindakan. Atau alih-alih Anda dapat mendefinisikan beberapa fungsi dan menggunakan dengan PS1seperti diilustrasikan di bawah ini.)

demo kecil:

hash@precise(lst ret. 0 ):~$ ls -sh someFileThatsNotThere
ls: cannot access someFileThatsNotThere: No such file or directory
hash@precise(lst ret. 2 ):~$ 
hash@precise(lst ret. 2 ):~$ aCommandThatsNot
aCommandThatsNot: command not found
hash@precise(lst ret. 127 ):~$ 
hash@precise(lst ret. 127 ):~$ echo "you should get a lst ret. 0, I believe the system has echo installed :)"
you should get a lst ret. 0, I believe the system has echo installed :)
hash@precise(lst ret. 0 ):~$
hash@precise(lst ret. 0 ):~$ sudo touch /tmp/someTestFile
[sudo] password for hash: 
hash@precise(lst ret. 1 ):~$
hash@precise(lst ret. 1 ):~$ chown $USER:$USER /tmp/someTestFile 
chown: changing ownership of `/tmp/someTestFile': Operation not permitted

Hanya bermain dengan PS1:) .. sedikit lagi,

function showRetStat {
## line1: initiliazing retStat with the return status of the previous command
retStat=$?
## line2: Left padding the return status with spaces. If you prefer the unpadded one, you can just replace
# $retStatFtd in the lines initializing noErrStr and errStr among other possible ways.
retStatFtd=$(sed -e :a -e 's/^.\{1,2\}$/ &/;ta' <<< $retStat)
## lines3&4: Setting the strings to display for a successful and unsuccessful run of previous command
# which we are going to display with the prompt string. Change the strings to display text of your
# choice like you may set noErrStr="yippie!" , errStr="oopsie!" in place of what they're now.
noErrStr="retStat "$retStatFtd" :: PASS ^_^"
errStr="retStat "$retStatFtd" :: FAIL x_x"
## line5: Applying the logic and display the proper string at the prompt. Space padded number i.e. retStatFtd, here,
# worked in the logic, originally I intended to use this for the display while retStat in the conditional
# check; you could make the function one statement less if you want to.
echo "$([ $retStatFtd = 0 ] && echo "$noErrStr" || echo "$errStr")"
}

## Combining the function showRetStat into the prompt string.
PS1='${debian_chroot:+($debian_chroot)}\u@\h($(showRetStat)):\w\$ '

(Anda dapat memodifikasi fungsi agar lebih mewah, seperti yang dilakukan @gronostaj di posnya.)

tepat
sumber
2
Saya sangat suka jawaban Anda yang diperluas dengan contoh. Saya cukup yakin untuk OP ingin xtrace tetapi secara pribadi saya akan menemukan ini berguna untuk debugging program baris perintah saya sendiri serta lebih memahami orang lain.
Benjamin R
1
Saya akan menyarankan kiri-padding nilai kembali, sehingga selalu panjang yang sama.
o0 '.
+1 untuk dimodifikasi PS1. Ini yang saya gunakan, dengan angka merah jika ada kesalahan, tidak ada tambahan jika perintah terakhir berhasil:\[\033[01;41;37m\]${?#0}\[\033[00;01;36m\] \u@\h:\w\[\033[00m\]\$
Carlos Campderrós
1
@rusty apakah itu tidak perlu sumber ~/.bashrcfile?
Avinash Raj
2
Ya, memodifikasi PS1 sangat membantu dan sangat fleksibel. Saya menunjukkan kebahagiaan ^_^pada kesuksesan, dan merah x_xpada hal lain.
Izkata
5

Anda dapat mengubah prompt perintah Anda untuk menampilkan tanda centang hijau ketika perintah sebelumnya keluar dengan 0 dan X merah sebaliknya. Arch Linux Wiki memiliki beberapa kode yang bagus untuk ditambahkan ke Anda bash.rc:

set_prompt () {
    Last_Command=$? # Must come first!
    Blue='\[\e[01;34m\]'
    White='\[\e[01;37m\]'
    Red='\[\e[01;31m\]'
    Green='\[\e[01;32m\]'
    Reset='\[\e[00m\]'
    FancyX='\342\234\227'
    Checkmark='\342\234\223'

    # Add a bright white exit status for the last command
    #PS1="$White\$? "
    # If it was successful, print a green check mark. Otherwise, print
    # a red X.
    if [[ $Last_Command == 0 ]]; then
        PS1+="$Green$Checkmark "
    else
        PS1+="$Red$FancyX "
    fi
    # If root, just print the host in red. Otherwise, print the current user
    # and host in green.
    if [[ $EUID == 0 ]]; then
        PS1+="$Red\\h "
    else
        PS1+="$Green\\u@\\h "
    fi
    # Print the working directory and prompt marker in blue, and reset
    # the text color to the default.
    PS1+="$Blue\\w \\\$$Reset "
}
PROMPT_COMMAND='set_prompt'

(Saya telah menonaktifkan kode kesalahan yang sebenarnya karena saya tidak seperti itu, jika Anda ingin melihat kode yang sebenarnya hanya menghapus #dari baris ini: #PS1="$White\$? ")

Begini tampilannya:

Tangkapan layar Terminal GUI

tangkapan layar tty

gronostaj
sumber
2

Ya , dimungkinkan untuk mendapatkan umpan balik untuk setiap perintah yang Anda jalankan di terminal. Ini bekerja atas dasar echo $?yang mengembalikan 0 untuk penyelesaian perintah yang berhasil dan nilai lain selain 0 untuk kegagalan.

Untuk mendapatkan umpan balik keberhasilan atau kegagalan, tambahkan baris di bawah ini ke ~/.bashrcfile.

bind 'RETURN: ";if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;\n"' 

Dan kemudian ~/.bashrcfile sumber untuk membuatnya berfungsi.

source ~/.bashrc

Penjelasan:

Untuk setiap perintah yang Anda jalankan di terminal, ;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;kode ini akan secara otomatis mengikatnya.

Contoh:

$ sudo apt-cache policy firefox;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;
firefox:
  Installed: 24.0+build1-0ubuntu1
  Candidate: 24.0+build1-0ubuntu1
  Version table:
 *** 24.0+build1-0ubuntu1 0
        500 http://ubuntu.inode.at/ubuntu/ saucy/main amd64 Packages
        100 /var/lib/dpkg/status
SUCCESS

$ suda apt-get update;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;
No command 'suda' found, did you mean:
 Command 'sudo' from package 'sudo-ldap' (universe)
 Command 'sudo' from package 'sudo' (main)
 suda: command not found
FAILURE

masukkan deskripsi gambar di sini

Avinash Raj
sumber
1
bind 'RETURN: " && echo SUCCESS || echo FAILED \n"'juga akan melakukan hal yang sama, Anda tidak perlu memeriksa [[ $? == 0 ]]secara eksplisit.
souravc
Namun, standar C / Linux dan mitra standar tata bahasa Inggris untuk 'Sukses' adalah KEGAGALAN.
Benjamin R