เอาต์พุตของคำสั่ง 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 shell
Edit>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 all
Ctrl+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 '
ทางลัดด้านบน: