เอาต์พุตของคำสั่ง Bash ถูกเก็บในการลงทะเบียนหรือไม่? เช่นสิ่งที่คล้ายกับ$?การจับเอาท์พุทแทนที่จะออกจากสถานะ
ฉันสามารถกำหนดผลลัพธ์ให้กับตัวแปรด้วย:
output=$(command)แต่มันก็พิมพ์มากกว่า ...
เอาต์พุตของคำสั่ง Bash ถูกเก็บในการลงทะเบียนหรือไม่? เช่นสิ่งที่คล้ายกับ$?การจับเอาท์พุทแทนที่จะออกจากสถานะ
ฉันสามารถกำหนดผลลัพธ์ให้กับตัวแปรด้วย:
output=$(command)แต่มันก็พิมพ์มากกว่า ...
คำตอบ:
คุณสามารถใช้$(!!)
เพื่อคำนวณใหม่ (ไม่ใช้ซ้ำ) เอาต์พุตของคำสั่งสุดท้าย
ตัว!!มันเองรันคำสั่งสุดท้าย
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre$(your_cmd)โดยใช้ backticks: `your_cmd`ตามคู่มือ Gnu Bash พวกเขาเหมือนกันกับหน้าที่ ของหลักสูตรนี้ยังขึ้นอยู่กับคำเตือนที่ยกขึ้นโดย @memecs
                    git diff $(!!)ที่คำสั่งก่อนหน้าเป็นการfindเรียก
                    $()แทน backticks แต่คงไม่มีอะไรจะเสียเวลานอนมากกว่า github.com/koalaman/shellcheck/wiki/SC2006
                    $()ยังคงทำงานในทุบตีพวกเขาจะเลิกในความโปรดปรานของ
                    คำตอบคือไม่ Bash ไม่ได้จัดสรรผลลัพธ์ใด ๆ ให้กับพารามิเตอร์หรือบล็อกใด ๆ ในหน่วยความจำ นอกจากนี้คุณจะได้รับอนุญาตให้เข้าถึง Bash โดยการใช้งานอินเทอร์เฟซที่อนุญาต ข้อมูลส่วนตัวของ Bash ไม่สามารถเข้าถึงได้เว้นแต่ว่าคุณจะทำการแฮก
วิธีหนึ่งในการทำเช่นนั้นคือโดยใช้trap DEBUG:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUGตอนนี้ stdout ของคำสั่งที่ดำเนินการล่าสุดและ stderr จะพร้อมใช้งานใน /tmp/out.log
ข้อเสียเพียงอย่างเดียวคือมันจะรันคำสั่งสองครั้ง: หนึ่งครั้งเพื่อเปลี่ยนเส้นทางเอาต์พุตและข้อผิดพลาดไปยัง/tmp/out.logและอีกครั้งตามปกติ อาจมีวิธีป้องกันพฤติกรรมนี้เช่นกัน
rm -rf * && cd ..ไม่เพียงไดเรกทอรีปัจจุบัน แต่ยังผู้ปกครองหลักจะถูกลบ? วิธีการนี้ดูอันตรายมากสำหรับฉัน
                    trap '' DEBUG
                    หากคุณใช้ mac และไม่ต้องกังวลว่าจะเก็บเอาท์พุทของคุณไว้ในคลิปบอร์ดแทนที่จะเขียนลงในตัวแปรคุณสามารถใช้ pbcopy และ pbpaste เป็นวิธีแก้ปัญหา
ตัวอย่างเช่นแทนที่จะทำสิ่งนี้เพื่อค้นหาไฟล์และกระจายเนื้อหากับไฟล์อื่น:
$ find app -name 'one.php' 
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.phpคุณสามารถทำได้:
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.phpสตริง/var/bar/app/one.phpอยู่ในคลิปบอร์ดเมื่อคุณเรียกใช้คำสั่งแรก
โดยวิธีการที่PBในpbcopyและpbpasteยืนทำด้วยกระดาษแข็ง, ไวพจน์คลิปบอร์ด
$ find app -name 'one.php' | xclip          $ diff $(xclip -o) /var/bar/two.php
                    pbpasteร่วมกับการทดแทนคำสั่ง
                    ได้รับแรงบันดาลใจจากคำตอบของ anubhava ซึ่งฉันคิดว่าไม่เป็นที่ยอมรับเพราะมันรันแต่ละคำสั่งสองครั้ง
save_output() { 
   exec 1>&3 
   { [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
   exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUGวิธีนี้เอาต์พุตของคำสั่ง last อยู่ใน / tmp / last และคำสั่งไม่ถูกเรียกสองครั้ง
grepหรือgit diff+1 อย่างไรก็ตาม
                    อย่างที่ konsolebox บอกไว้คุณต้องแฮ็คไปทุบตีตัวเอง นี่เป็นตัวอย่างที่ดีเกี่ยวกับวิธีการที่อาจบรรลุเป้าหมายนี้ ที่เก็บ stderred (หมายถึงการระบายสี stdout) ให้คำแนะนำเกี่ยวกับวิธีการสร้าง
ฉันให้มันลอง: การกำหนดบางส่วนภายในไฟล์อธิบายใหม่.bashrcเช่น
exec 41>/tmp/my_console_log(หมายเลขคือพล) และปรับเปลี่ยนstderred.cตามความเหมาะสมเพื่อให้เนื้อหายังได้รับการเขียนเพื่อ fd 41. มันชนิดของการทำงาน แต่มีการโหลดของ NUL ไบต์, formattings แปลกและเป็นพื้นข้อมูลไบนารีไม่สามารถอ่านได้ บางทีคนที่มีความเข้าใจที่ดีของ C สามารถลองใช้งานได้
tail -n 1 [logfile]ถ้าเป็นเช่นนั้นทุกอย่างที่จำเป็นเพื่อให้ได้เส้นที่พิมพ์สุดท้ายคือ
ใช่ทำไมพิมพ์บรรทัดพิเศษทุกครั้งที่ตกลงกัน คุณสามารถเปลี่ยนเส้นทางกลับไปที่อินพุต แต่เอาต์พุตไปยังอินพุต (1> & 0) นั้นไม่เป็นเช่นนั้น นอกจากนี้คุณไม่ต้องการเขียนฟังก์ชั่นซ้ำแล้วซ้ำอีกในแต่ละไฟล์สำหรับไฟล์เดียวกัน
หากคุณไม่ได้ส่งออกไฟล์ที่ใดก็ได้และตั้งใจจะใช้งานแบบโลคัลเท่านั้นคุณสามารถตั้งค่าให้เทอร์มินัลตั้งค่าการประกาศฟังก์ชัน คุณต้องเพิ่มฟังก์ชั่นใน~/.bashrcไฟล์หรือใน~/.profileไฟล์ ในกรณีที่สองคุณต้องเปิดใช้งานจากRun command as login shellEdit>Preferences>yourProfile>Command
ทำให้ฟังก์ชั่นง่ายพูดว่า:
get_prev()
{
    # option 1: create an executable with the command(s) and run it
    echo $* > /tmp/exe
    bash /tmp/exe > /tmp/out
    # option 2: if your command is single command (no-pipe, no semi-colons), still it may not run correct in some exceptions
    #echo `$*` > /tmp/out
    # return the command(s) outputs line by line
    IFS=$(echo -en "\n\b")
    arr=()
    exec 3</tmp/out
    while read -u 3 -r line
    do
        arr+=($line)
        echo $line
    done
    exec 3<&-
}ในสคริปต์หลัก:
#run your command:
cmd="echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"
get_prev $cmd
#or simply
get_prev "echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"Bash บันทึกตัวแปรแม้อยู่นอกขอบเขตก่อนหน้า:
#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++)); do echo ${arr[i]}; doneหนึ่งที่ฉันใช้มานานหลายปี
.bashrcหรือ.bash_profile)# capture the output of a command so it can be retrieved with ret
cap () { tee /tmp/capture.out}
# return the output of the most recent command that was captured by cap
ret () { cat /tmp/capture.out }$ find . -name 'filename' | cap
/path/to/filename
$ ret
/path/to/filenameฉันมักจะเพิ่ม| capในตอนท้ายของคำสั่งทั้งหมดของฉัน ด้วยวิธีนี้เมื่อฉันพบว่าฉันต้องการที่จะทำการประมวลผลข้อความบนผลลัพธ์ของคำสั่งที่ทำงานช้าฉันสามารถดึงมันด้วยresเสมอ
cat -ในcap () { cat - | tee /tmp/capture.out}ที่นี่? ไม่cap () { tee /tmp/capture.out }ต้องเสียสะอึกใด ๆ ฉันหายไป?
                    cat - | cat - | cat -ก่อนเพื่อให้น่าสนใจยิ่งขึ้นหรือไม่ 😉ฉันจะแก้ไขมันเมื่อฉันทดสอบเพื่อให้แน่ใจว่ามันเป็น spandrel อย่างแท้จริง
                    ไม่แน่ใจว่าสิ่งที่คุณต้องการสำหรับสิ่งนี้ดังนั้นคำตอบนี้อาจไม่เกี่ยวข้อง คุณสามารถบันทึกผลลัพธ์ของคำสั่งได้ตลอดเวลา:netstat >> output.txtแต่ฉันไม่คิดว่านั่นคือสิ่งที่คุณกำลังมองหา
มีตัวเลือกการเขียนโปรแกรมแน่นอนว่า; คุณสามารถทำให้โปรแกรมอ่านไฟล์ข้อความด้านบนหลังจากคำสั่งนั้นรันและเชื่อมโยงกับตัวแปรและใน Ruby ซึ่งเป็นภาษาที่ฉันเลือกคุณสามารถสร้างตัวแปรจากเอาต์พุตคำสั่งโดยใช้ 'backticks':
output = `ls`                       #(this is a comment) create variable out of command
if output.include? "Downloads"      #if statement to see if command includes 'Downloads' folder
print "there appears to be a folder named downloads in this directory."
else
print "there is no directory called downloads in this file."
endติดสิ่งนี้ในไฟล์. rb และเรียกใช้: ruby file.rbและมันจะสร้างตัวแปรออกจากคำสั่งและอนุญาตให้คุณจัดการมัน
ฉันมีความคิดว่าฉันไม่มีเวลาลองดำเนินการทันที
แต่ถ้าคุณทำสิ่งต่อไปนี้:
$ MY_HISTORY_FILE = `get_temp_filename`
$ MY_HISTORY_FILE=$MY_HISTORY_FILE bash -i 2>&1 | tee $MY_HISTORY_FILE
$ some_command
$ cat $MY_HISTORY_FILE
$ # ^You'll want to filter that down in practice!อาจมีปัญหากับการบัฟเฟอร์ IO ไฟล์อาจมีขนาดใหญ่เกินไป จะต้องมีวิธีแก้ไขปัญหาเหล่านี้
ฉันคิดว่าการใช้คำสั่งสคริปต์อาจช่วยได้ สิ่งที่ต้องการ,
สคริปต์ -c bash -qf fifo_pid
การใช้คุณสมบัติทุบตีเพื่อตั้งค่าหลังจากการแยกวิเคราะห์
หากคุณไม่ต้องการคำนวณคำสั่งก่อนหน้านี้อีกครั้งคุณสามารถสร้างแมโครที่สแกนบัฟเฟอร์เทอร์มินัลปัจจุบันพยายามที่จะคาดเดาเอาต์พุตของคำสั่งสุดท้ายคัดลอกไปยังคลิปบอร์ดแล้วพิมพ์ลงในเทอร์มินัล
สามารถใช้สำหรับคำสั่งง่าย ๆ ที่คืนค่าเอาต์พุตบรรทัดเดียว (ทดสอบบน Ubuntu 18.04 ด้วยgnome-terminal)
ติดตั้งเครื่องมือดังต่อไปนี้: xdootool, xclip,ruby
ในgnome-terminalการเดินทางไปและตั้งค่าให้Preferences -> Shortcuts -> Select allCtrl+shift+a
สร้างสคริปต์ ruby ต่อไปนี้:
cat >${HOME}/parse.rb <<EOF
#!/usr/bin/ruby
stdin = STDIN.read
d = stdin.split(/\n/)
e = d.reverse
f = e.drop_while { |item| item == "" }
g = f.drop_while { |item| item.start_with? "${USER}@" }
h = g[0] 
print h
EOFในการตั้งค่าแป้นพิมพ์ให้เพิ่มแป้นพิมพ์ลัดต่อไปนี้:
bash  -c '/bin/sleep 0.3 ; xdotool key ctrl+shift+a ; xdotool key ctrl+shift+c ; ( (xclip -out  | ${HOME}/parse.rb ) > /tmp/clipboard ) ; (cat /tmp/clipboard | xclip -sel clip ) ; xdotool key ctrl+shift+v   '
ทางลัดด้านบน: