Bash komutunun çıktısı herhangi bir kayıtta saklanıyor mu? Örneğin,$?
çıkış durumu yerine çıktıyı yakalamaya .
Ben çıktı ile bir değişken atayabilirsiniz:
output=$(command)
ama bu daha çok yazıyor ...
Bash komutunun çıktısı herhangi bir kayıtta saklanıyor mu? Örneğin,$?
çıkış durumu yerine çıktıyı yakalamaya .
Ben çıktı ile bir değişken atayabilirsiniz:
output=$(command)
ama bu daha çok yazıyor ...
Yanıtlar:
Sen kullanabilirsiniz $(!!)
için yeniden hesaplamak (değil yeniden kullanım) son komutun çıktısı.
!!
Kendi yürütür son komut.
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
$(your_cmd)
uçları kullanarak kendinizi yazmaktan kurtarabilirsiniz : `your_cmd`
Gnu Bash kılavuzuna göre fonksiyonel olarak aynıdırlar. Tabii ki bu da memecs tarafından yapılan uyarıya tabidir
git diff $(!!)
Önceki komutun bir find
çağırma olduğu gibi bir şey yapmak istediğinizde kesinlikle yararlıdır .
$()
backticks yerine kullanmak için iyi nedenler var . Ama muhtemelen uykuyu kaybedecek bir şey yok. github.com/koalaman/shellcheck/wiki/SC2006
$()
.
Cevap hayır. Bash, belleğindeki herhangi bir parametreye veya bloğa herhangi bir çıkış tahsis etmez. Ayrıca, Bash'e yalnızca izin verilen arabirim işlemleriyle erişebilirsiniz. Bash'un özel verilerine, onu hacklemedikçe erişilemez.
Bunu yapmanın bir yolu trap DEBUG
:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG
Şimdi en son yürütülen komutun stdout ve stderr'i /tmp/out.log
Tek dezavantajı, komutun iki kez yürütülmesidir: bir kez çıktı ve hatayı /tmp/out.log
normal bir şekilde ve bir kez yönlendirmek için . Muhtemelen bu davranışı önlemenin bir yolu vardır.
rm -rf * && cd ..
, sadece geçerli dizini değil, aynı zamanda üst dir silinecek ?? Bu yaklaşım benim için çok tehlikeli görünüyor
trap '' DEBUG
Mac kullanıyorsanız ve çıktınızı bir değişkene yazmak yerine panoya depolamak sakıncası yoksa, geçici çözüm olarak pbcopy ve pbpaste kullanabilirsiniz.
Örneğin, bir dosyayı bulmak ve içeriğini başka bir dosyayla dağıtmak için bunu yapmak yerine:
$ find app -name 'one.php'
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.php
Bunu yapabilirsin:
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php
/var/bar/app/one.php
İlk komutu çalıştırdığınızda dize panodadır.
Bu arada, pb içinde pbcopy
ve pbpaste
standı çalışma alanındaki panoya ile eşanlamlı için.
$ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
pbpaste
komut ikamesi ile birlikte kullanmayı hiç düşünmemiştim .
Anubhava'nın cevabından esinlenerek, her komutu iki kez çalıştırdığı için aslında kabul edilemez olduğunu düşünüyorum.
save_output() {
exec 1>&3
{ [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUG
Bu şekilde son komutun çıktısı / tmp / last olur ve komut iki kez çağrılmaz.
grep
da git diff
yine de yardımcı programlar veya +1 için çalışan renk kodları almak için özel dikkat göstermeniz gerektiği anlamına geliyor
Konsolebox'ın dediği gibi, bash'ın kendisini hacklemelisiniz. Buraya bunun nasıl başarabileceğine dair oldukça iyi bir örnek. Stderred deposu (aslında stdout'u renklendirme amaçlı), nasıl oluşturulacağı hakkında talimatlar verir.
Denedim: İçinde yeni bir dosya tanımlayıcı .bashrc
gibi
exec 41>/tmp/my_console_log
(sayı isteğe bağlıdır) ve stderred.c
içeriği fd 41'e yazacak şekilde değiştirin. çalıştı, ancak bir sürü NUL bayt, garip biçimlendirmeler içeriyor ve temelde ikili veriler, okunabilir değil. Belki de C'yi iyi anlayan biri bunu deneyebilir.
Eğer öyleyse, son yazdırılan çizgiyi elde etmek için gereken her şey tail -n 1 [logfile]
.
Evet, neden her seferinde ekstra satırlar yazıyorsunuz? Girdiye geri yönlendirebilirsiniz, ancak girişe (1> & 0) çıkış hayır olur. Ayrıca, her dosyaya tekrar tekrar bir işlev yazmak istemezsiniz.
Dosyaları hiçbir yere dışa aktarmıyorsanız ve yalnızca yerel olarak kullanmak istiyorsanız, Terminal'in işlev bildirimini ayarlamasını sağlayabilirsiniz. İşlevi ~/.bashrc
dosyaya veya dosyaya eklemeniz gerekir ~/.profile
. İkinci durumda, etkinleştirmeniz gerekir Run command as login shell
dan Edit>Preferences>yourProfile>Command
.
Basit bir işlev yapın, söyleyin:
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<&-
}
Ana komut dosyasında:
#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, değişkeni önceki kapsamın dışında bile kaydeder:
#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++)); do echo ${arr[i]}; done
Yıllarca kullandığım.
.bashrc
ya .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
Tüm komutlarımın sonuna ekleme eğilimindeyim . Bu şekilde bulduğumda metin işleme yapmak için yavaş çalışan bir komutun çıktısını her zaman alabilirim res
.
cat -
içinde cap () { cat - | tee /tmp/capture.out}
burada? cap () { tee /tmp/capture.out }
Kaçırdığım bir hıçkırık var mı ?
cat - | cat - | cat -
Daha ilginç hale getirmek için önceden eklemem gerekir mi? 😉 Gerçekten bir spandrel olduğundan emin olmak için test ettikten sonra düzeltirim
Bunun için tam olarak neye ihtiyaç duyduğunuzdan emin değilim, bu nedenle bu cevap alakalı olmayabilir. Bir komutun çıktısını her zaman kaydedebilirsiniz:netstat >> output.txt
ancak aradığınız şeyin bu olduğunu sanmıyorum.
Tabii ki programlama seçenekleri var; bu komut çalıştırıldıktan sonra yukarıdaki metin dosyasını okuyabilmeniz ve bir değişkenle ilişkilendirebilmeniz için bir program elde edebilirsiniz ve benim tercih ettiğim dil olan Ruby'de 'backticks'i kullanarak komut çıktısından bir değişken oluşturabilirsiniz:
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
Bunu bir .rb dosyasına yapıştırın ve çalıştırın: ruby file.rb
ve komuttan bir değişken oluşturur ve onu değiştirmenize izin verir.
Hemen uygulamaya çalışacak vaktim olmadığına dair bir fikrim var.
Peki ya aşağıdaki gibi bir şey yaparsanız:
$ 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!
ES arabelleklemesi ile ilgili sorunlar olabilir. Ayrıca dosya çok büyük olabilir. Kişi bu sorunlara bir çözüm bulmalıdır.
Önceki komutu yeniden hesaplamak istemiyorsanız, geçerli terminal arabelleğini tarayan bir makro oluşturabilir, son komutun -supposed- çıktısını tahmin etmeye çalışır, panoya kopyalar ve son olarak da terminale yazar.
Tek bir çıktı satırı döndüren basit komutlar için kullanılabilir (Ubuntu 18.04 ile test edilmiştir gnome-terminal
).
Aşağıdaki araçları yükleyin: xdootool
, xclip
,ruby
Adresine gnome-terminal
gidin Preferences -> Shortcuts -> Select all
ve ayarlayın Ctrl+shift+a
.
Aşağıdaki yakut komut dosyasını oluşturun:
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
Klavye ayarlarına aşağıdaki klavye kısayolunu ekleyin:
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 '
Yukarıdaki kısayol: