Là đầu ra của một lệnh Bash được lưu trữ trong bất kỳ thanh ghi nào? Ví dụ, một cái gì đó tương tự như $?
chụp đầu ra thay vì trạng thái thoát.
Tôi có thể gán đầu ra cho một biến với:
output=$(command)
nhưng đó là gõ nhiều hơn ...
Là đầu ra của một lệnh Bash được lưu trữ trong bất kỳ thanh ghi nào? Ví dụ, một cái gì đó tương tự như $?
chụp đầu ra thay vì trạng thái thoát.
Tôi có thể gán đầu ra cho một biến với:
output=$(command)
nhưng đó là gõ nhiều hơn ...
Câu trả lời:
Bạn có thể sử dụng $(!!)
để tính toán lại (không sử dụng lại) đầu ra của lệnh cuối cùng.
Chính !!
nó thực hiện lệnh cuối cùng.
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
$(your_cmd)
bằng cách sử dụng backticks: `your_cmd`
Theo hướng dẫn của Gnu Bash, chúng giống hệt nhau về mặt chức năng. Tất nhiên, điều này cũng phải chịu cảnh báo của @memecs
git diff $(!!)
lệnh trước đó là một lệnh find
.
$()
thay vì backticks. Nhưng có lẽ không có gì để mất ngủ hơn. github.com/koalaman/shellcheck/wiki/SC2006
$()
.
Câu trả lời là không. Bash không phân bổ bất kỳ đầu ra nào cho bất kỳ tham số hoặc bất kỳ khối nào trên bộ nhớ của nó. Ngoài ra, bạn chỉ được phép truy cập Bash bởi các hoạt động giao diện được phép của nó. Dữ liệu riêng tư của Bash không thể truy cập được trừ khi bạn hack nó.
Một cách để làm điều đó là bằng cách sử dụng trap DEBUG
:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG
Bây giờ thiết bị xuất chuẩn và lệnh stderr được thực thi gần đây nhất sẽ có sẵn trong /tmp/out.log
Nhược điểm duy nhất là nó sẽ thực thi một lệnh hai lần: một lần để chuyển hướng đầu ra và lỗi đến /tmp/out.log
và một lần bình thường. Có lẽ có một số cách để ngăn chặn hành vi này là tốt.
rm -rf * && cd ..
, không chỉ thư mục hiện tại, mà cả thư mục mẹ sẽ bị xóa ?? Cách tiếp cận này có vẻ rất nguy hiểm đối với tôi
trap '' DEBUG
Nếu bạn đang sử dụng mac và không ngại lưu trữ đầu ra của mình trong bảng tạm thay vì ghi vào một biến, bạn có thể sử dụng pbcopy và pbpaste như một cách giải quyết.
Ví dụ: thay vì làm điều này để tìm một tệp và tìm nội dung của nó với một tệp khác:
$ find app -name 'one.php'
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.php
Bạn có thể làm điều này:
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php
Chuỗi /var/bar/app/one.php
nằm trong clipboard khi bạn chạy lệnh đầu tiên.
Nhân tiện, pb trongpbcopy
và viết pbpaste
tắt của pasteboard, một từ đồng nghĩa với clipboard.
$ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
pbpaste
cùng với thay thế lệnh.
Lấy cảm hứng từ câu trả lời của anubhava, điều mà tôi nghĩ là không thực sự chấp nhận được vì nó chạy mỗi lệnh hai lần.
save_output() {
exec 1>&3
{ [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUG
Bằng cách này, đầu ra của lệnh cuối cùng nằm trong / tmp / last và lệnh không được gọi hai lần.
grep
hoặc git diff
dù sao đi nữa
Giống như konsolebox đã nói, bạn sẽ phải tự hack vào bash. Đây là một ví dụ khá hay về cách người ta có thể đạt được điều này. Kho lưu trữ stderred (thực sự có nghĩa là để tô màu thiết bị xuất chuẩn) đưa ra hướng dẫn về cách xây dựng nó.
Tôi đã thử: Xác định một số mô tả tệp mới bên trong .bashrc
như
exec 41>/tmp/my_console_log
(số là tùy ý) và sửa đổi cho stderred.c
phù hợp để nội dung cũng được ghi vào fd 41. Nó thuộc loại làm việc, nhưng chứa vô số NUL byte, formattings lạ và về cơ bản là dữ liệu nhị phân, không thể đọc được. Có lẽ ai đó hiểu rõ về C có thể thử nó.
Nếu vậy, tất cả mọi thứ cần thiết để có được dòng in cuối cùng là tail -n 1 [logfile]
.
Vâng, tại sao gõ thêm dòng mỗi lần đồng ý. Bạn có thể chuyển hướng được trả về đầu vào, nhưng đầu ra thành đầu vào (1> & 0) là không. Ngoài ra, bạn sẽ không muốn viết một hàm nhiều lần trong mỗi tệp cho cùng một tệp.
Nếu bạn không xuất các tệp ở bất cứ đâu và chỉ có ý định sử dụng nó cục bộ, bạn có thể thiết lập Terminal khai báo hàm. Bạn phải thêm chức năng trong ~/.bashrc
tập tin hoặc trong ~/.profile
tập tin. Trong trường hợp thứ hai, bạn cần kích hoạt Run command as login shell
từ Edit>Preferences>yourProfile>Command
.
Thực hiện một chức năng đơn giản, nói:
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<&-
}
Trong kịch bản chính:
#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 lưu biến ngay cả ngoài phạm vi trước đó:
#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++)); do echo ${arr[i]}; done
Một cái mà tôi đã sử dụng trong nhiều năm.
.bashrc
hoặc .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
Tôi có xu hướng thêm | cap
vào cuối tất cả các lệnh của tôi. Bằng cách này khi tôi thấy tôi muốn xử lý văn bản trên đầu ra của lệnh chạy chậm, tôi luôn có thể truy xuất nó res
.
cat -
ở cap () { cat - | tee /tmp/capture.out}
đây là gì? Có cap () { tee /tmp/capture.out }
phải tôi bị mất nấc không?
cat - | cat - | cat -
trước chỉ để làm cho nó thú vị hơn? Tôi sẽ sửa nó một khi tôi đã kiểm tra để đảm bảo rằng đó thực sự là một kẻ phá hoại
Không chắc chắn chính xác những gì bạn cần điều này cho, vì vậy câu trả lời này có thể không liên quan. Bạn luôn có thể lưu đầu ra của lệnh:netstat >> output.txt
nhưng tôi không nghĩ đó là thứ bạn đang tìm kiếm.
Có các tùy chọn lập trình mặc dù; bạn chỉ cần có một chương trình để đọc tệp văn bản ở trên sau khi lệnh đó được chạy và liên kết nó với một biến và trong Ruby, ngôn ngữ tôi chọn, bạn có thể tạo một biến ra khỏi đầu ra lệnh bằng cách sử dụng '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
Dán tệp này trong tệp .rb và chạy nó: ruby file.rb
và nó sẽ tạo ra một biến ra khỏi lệnh và cho phép bạn thao tác với nó.
Tôi có một ý tưởng rằng tôi không có thời gian để cố gắng thực hiện ngay lập tức.
Nhưng nếu bạn làm một cái gì đó như sau:
$ 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!
Có thể có vấn đề với bộ đệm IO. Ngoài ra các tập tin có thể nhận được quá lớn. Người ta sẽ phải đưa ra một giải pháp cho những vấn đề này.
Nếu bạn không muốn tính toán lại lệnh trước đó, bạn có thể tạo một macro quét bộ đệm đầu cuối hiện tại, cố gắng đoán đầu ra -supposed- của lệnh cuối cùng, sao chép nó vào bảng tạm và cuối cùng nhập nó vào thiết bị đầu cuối.
Nó có thể được sử dụng cho các lệnh đơn giản trả về một dòng đầu ra duy nhất (được thử nghiệm trên Ubuntu 18.04 với gnome-terminal
).
Cài đặt các công cụ sau: xdootool
, xclip
,ruby
Đi gnome-terminal
đến Preferences -> Shortcuts -> Select all
và đặt nó vào Ctrl+shift+a
.
Tạo tập lệnh ruby sau:
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
Trong cài đặt bàn phím, thêm phím tắt sau:
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 '
Phím tắt trên: