ฉันสามารถทำให้คำสั่งทั้งหมดมีข้อเสนอแนะได้หรือไม่หากพวกเขาทำงานได้หรือไม่


11

บางครั้งเมื่อฉันเรียกใช้คำสั่งมันไม่แสดงผลลัพธ์ดังนั้นฉันไม่แน่ใจว่าพวกเขาได้ทำงานหรือไม่ เป็นไปได้หรือไม่ที่จะทำให้คำสั่งทั้งหมดมีข้อเสนอแนะหากทำงานอย่างถูกต้องหรือไม่? หรืออย่างน้อยที่สุดเพื่อแสดงรหัสข้อเสนอแนะที่พวกเขาได้ทำงาน (อย่างถูกต้องหรือไม่)


6
แนวคิดทั่วไปคือ: ไม่มีข้อเสนอแนะหมายความว่ามันใช้งานได้
Rinzwind

1
สิ่งนี้ไม่เป็นความจริงอย่างแน่นอน ตัวอย่างเช่นcryptsetupโดยค่าเริ่มต้นสามารถข้ามบางข้อความผิดพลาด มันเป็นสิ่งที่ดีที่จะมีในของคุณ$? PS1ขั้นตอนต่อไปคือการเพิ่มเวลาปัจจุบันเป็นอย่างดีเพื่อจะรู้เสมอว่าการกำหนดเวลาคำสั่ง;)
d33tah

คำตอบ:


11

(ฉันคิดว่าเนื่องจากคุณกำลังโพสต์ในAsk Ubuntuเราสามารถสมมติว่าคุณกำลังพูดถึงเชลล์เริ่มต้นนั่นคือBash )

มีคำตอบที่ดีมากสำหรับคำถาม Stack Overflow ในเชลล์สคริปต์: คำสั่ง echo shell ขณะที่ถูกดำเนินการ (นี่ไม่ใช่แค่โซลูชันเฉพาะของ Ubuntu)

สิ่งที่คุณต้องทำคือใช้คำสั่งsetเพื่อเปิด verbose หรือ xtrace

set -o

จะให้รายการที่พารามิเตอร์ปัจจุบันจะเปลี่ยนไปในหรือออก

set -v

หรือรุ่น longform:

set -o verbose

จะเปิด verbose ON

ฉันคิดว่าสิ่งที่คุณต้องการจริงๆแล้วเป็น xtrace สิ่งนี้จะไม่เพียงสะท้อนทุกคำสั่งที่คุณเรียกใช้ แต่ยังจะขยายพารามิเตอร์และให้ข้อเสนอแนะเพิ่มเติม ดังนั้นถ้าฉันทำอะไรโง่ ๆ เหมือนพิมพ์ 'สวัสดี' ที่เทอร์มินัลฉันจะได้รับเสียงสะท้อนจากสิ่งที่ฉันพิมพ์รวมถึงรายงาน / การติดตามว่าเชลล์ทำอะไรเพื่อพยายามใช้คำสั่ง 'สวัสดี' (ดูภาพด้านล่าง ):

ป้อนคำอธิบายภาพที่นี่

วิธีเปิดใช้งาน xtrace:

set -x

หรือ:

set -o xtrace

ในการปิดการใช้งานพารามิเตอร์เหล่านี้คุณ (ตอบโต้โดยสัญชาตญาณ) เรียกคำสั่งเดียวกันยกเว้นด้วยเครื่องหมายบวก+แทนเครื่องหมายเส้นประหรือเครื่องหมายลบดังนั้นตัวอย่างเช่น:

set +v

จะปิด verbose OFFเช่นเดียวกัน:

set +x

จะเปิด xtrace OFF


แนะนำรายละเอียดเกี่ยวกับตัวเลือกเปลือกอยู่ในบทที่ตัวเลือก 33. ขั้นสูงทุบตี Scripting คู่มือ


1
แต่มันทำงานอย่างไรเมื่อคำสั่งถูกต้อง? มันให้ผลผลิตใด ๆ whoami >/dev/nullกล่าวว่าสำหรับคำสั่ง
ผู้ใช้ที่ลงทะเบียน

ใช่แน่นอนมันสะท้อนสิ่งที่คุณพิมพ์บวกกับพารามิเตอร์เพิ่มเติมใด ๆ ที่เกี่ยวข้องในคำสั่งที่ถูกเรียกอย่างเงียบ ๆ เมื่อเรียกใช้คำสั่งของคุณ ถ้าคุณหมายถึงมันพิมพ์ "ความสำเร็จ" แล้วน่าเศร้าไม่ใช่คำตอบของ Avinash Raj จะทำเช่นนั้น
Benjamin R

@ PeterMortensen ขอบคุณสำหรับการแก้ไขที่ละเอียดอ่อนในคำตอบของฉัน
Benjamin R

13

ในการตรวจสอบว่าคำสั่งบางคำสั่งทำงานได้สำเร็จหรือไม่คุณสามารถตรวจสอบสถานะการส่งคืนที่ได้รับจาก$?คำสั่งก่อนหน้าด้วย:

echo $?

สถานะการส่งคืน0หมายถึงคำสั่งที่ดำเนินการสำเร็จแล้วในขณะที่เอาต์พุตที่ไม่เป็นศูนย์ ( รหัสข้อผิดพลาด ) หมายถึงพบปัญหาบางอย่างหรือมีข้อผิดพลาดและสามารถทราบหมวดหมู่ได้จากรหัสข้อผิดพลาด รหัสข้อผิดพลาดลินุกซ์ / C ที่กำหนดไว้ในและ/usr/include/asm-generic/errno-base.h/usr/include/asm-generic/errno.h

นอกจากนี้ในทุบตี.bashrcกำหนดนามแฝงalertซึ่งสามารถใช้ในการแจ้งเตือนด้วยสถานะของความสำเร็จ คุณจะต้องแนบนามแฝงกับคำสั่งหรือคำสั่งผสมเช่นนี้:

some_command --some-switch; alert

คุณสามารถผนวกบรรทัดของรหัสต่อไปนี้ไปยัง~/.bashrcไฟล์ของคุณเพื่อแสดงสถานะการส่งคืนของคำสั่งสุดท้ายที่ดำเนินการ ..

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

(เปิดไฟล์~/.bashrcพร้อมตัวแก้ไขข้อความที่คุณเลือกและคัดลอกบรรทัดข้างต้นวางไว้ในไฟล์และบันทึกเรียกใช้อินสแตนซ์ใหม่ของเทอร์มินัลและคุณควรเปิดใช้งานหรือคุณสามารถกำหนดฟังก์ชันและใช้งานแทน มันมีPS1เหมือนเช่นภาพประกอบด้านล่าง.)

ตัวอย่างเล็ก ๆ น้อย ๆ :

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

เพิ่งเล่นกับPS1:) .. อีกนิด

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\$ '

(คุณสามารถปรับเปลี่ยนฟังก์ชั่นเพื่อทำให้แฟนซีมากขึ้นเช่น @gronostaj ทำในโพสต์ของเขา)


2
ฉันชอบคำตอบแบบขยายของคุณพร้อมตัวอย่าง ฉันค่อนข้างมั่นใจว่า OP ต้องการ xtrace แต่โดยส่วนตัวฉันจะพบว่าสิ่งนี้มีประโยชน์สำหรับการดีบักโปรแกรมบรรทัดคำสั่งของตัวเองและเข้าใจผู้อื่นได้ดีขึ้น
Benjamin R

1
ฉันขอแนะนำให้เว้นระยะห่างจากค่าส่งคืนเพื่อให้มันมีความยาวเท่ากันเสมอ
o0 '

+1 PS1สำหรับการแก้ไข นี่คือการใช้หนึ่งที่ฉันมีจำนวนสีแดงในกรณีของข้อผิดพลาดอะไรเป็นพิเศษถ้าคำสั่งสุดท้ายประสบความสำเร็จ:\[\033[01;41;37m\]${?#0}\[\033[00;01;36m\] \u@\h:\w\[\033[00m\]\$
คาร์ลอCampderrós

1
@rusty นั้นไม่จำเป็นต้องมี~/.bashrcไฟล์ต้นฉบับ หรือไม่
Avinash Raj

2
ใช่การแก้ไข PS1 นั้นมีประโยชน์และยืดหยุ่นมาก ฉันแสดงความสุข^_^ในความสำเร็จและสีแดงx_xกับสิ่งอื่น
Izkata

5

คุณสามารถเปลี่ยนพรอมต์คำสั่งของคุณเพื่อแสดงเครื่องหมายขีดสีเขียวเมื่อคำสั่งก่อนหน้าออกด้วย 0 และสีแดง X Arch Linux Wikiมีโค้ดที่ดีที่จะเพิ่มใน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'

(ผมได้ปิดการใช้งานรหัสข้อผิดพลาดที่เกิดขึ้นจริงเพราะผมไม่ชอบมันถ้าคุณต้องการที่จะดูรหัสที่แน่นอนเพียง แต่เอา#จากบรรทัดนี้#PS1="$White\$? ")

นี่คือลักษณะ:

ภาพหน้าจอ GUI Terminal

ภาพหน้าจอ tty


2

ใช่เป็นไปได้ที่จะได้รับคำติชมสำหรับทุกคำสั่งที่คุณดำเนินการบนเทอร์มินัลมันทำงานบนพื้นฐานของecho $?ผลตอบแทน 0 สำหรับความสำเร็จของคำสั่งและค่าอื่น ๆ ที่ไม่ใช่ 0 สำหรับความล้มเหลว

หากต้องการรับผลสำเร็จหรือความล้มเหลวให้เพิ่มบรรทัดด้านล่างลงใน~/.bashrcไฟล์

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

จากนั้น~/.bashrcไฟล์ต้นฉบับเพื่อให้มันใช้งานได้

source ~/.bashrc

คำอธิบาย:

สำหรับทุกคำสั่งที่คุณเรียกใช้บนเทอร์มินัล;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;รหัสนี้จะถูกผูกเข้ากับมันโดยอัตโนมัติ

ตัวอย่าง:

$ 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

ป้อนคำอธิบายรูปภาพที่นี่


1
bind 'RETURN: " && echo SUCCESS || echo FAILED \n"'จะทำเช่นเดียวกันคุณไม่จำเป็นต้องตรวจสอบ[[ $? == 0 ]]อย่างชัดเจน
souravc

อย่างไรก็ตามมาตรฐาน C / Linux และมาตรฐานไวยากรณ์ภาษาอังกฤษเป็น 'ความสำเร็จ' จะล้มเหลว
Benjamin R
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.