Możesz uchronić się przed wpisywaniem $(your_cmd)za pomocą grawitacji: `your_cmd`Zgodnie z instrukcją Gnu Bash są one funkcjonalnie identyczne. Oczywiście jest to również przedmiotem ostrzeżenia podniesionego przez @memecs
W praktyce wynik poleceń jest deterministyczny, więc nie męczyłbym się z ponownym obliczeniem. Jest to z pewnością przydatne, gdy chcesz zrobić coś takiego, git diff $(!!)gdzie poprzednie polecenie było findwywołaniem.
@ user2065875, mimo że znaki odwrotne nadal działają w Bash, są one przestarzałe na rzecz $().
kurczyński
87
Odpowiedź brzmi nie. Bash nie przydziela żadnego wyjścia do żadnego parametru ani żadnego bloku w swojej pamięci. Ponadto możesz uzyskać dostęp do Bash tylko poprzez dozwolone operacje interfejsu. Prywatne dane Bash nie są dostępne, chyba że je zhakujesz.
Czy można mieć jakąś niestandardową funkcję „oprogramowania pośredniego” basha, która uruchamia się przed każdym poleceniem, a wszystko co robi, to zapisuje wynikowe dane wyjściowe do czegoś, co działa jak wewnętrzny schowek (powiedzmy BASH_CLIPBOARD)?
Pat Needham
@PatNeedham Not sure. Sprawdź ładowalne moduły. Sprawdź, czy potrafisz napisać.
Teraz stdout i stderr ostatnio wykonywanego polecenia będą dostępne w /tmp/out.log
Jedynym minusem jest to, że wykona polecenie dwukrotnie: raz, aby przekierować wyjście i błąd do /tmp/out.logi raz normalnie. Prawdopodobnie istnieje również sposób, aby temu zapobiec.
więc kiedy piszę rm -rf * && cd .., nie tylko bieżący katalog, ale także katalog nadrzędny zostanie usunięty? takie podejście wydaje mi się bardzo niebezpieczne
phil294
1
Jak teraz mogę cofnąć tę czynność?
Kartik Chauhan
5
@KartikChauhan: Po prostu zróbtrap '' DEBUG
anubhava
7
Jeśli korzystasz z komputera Mac i nie masz nic przeciwko przechowywaniu wyników w schowku zamiast zapisywania w zmiennej, możesz użyć pbcopy i pbpaste jako obejścia.
Na przykład, zamiast robić to, aby znaleźć plik i porównać jego zawartość z innym plikiem:
w systemie Linux $ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
si-mikey
ciekawe, nigdy nie myślałem o użyciu pbpasterazem z zastępowaniem poleceń.
Sridhar Sarnobat
Co jeśli zrobię pierwszą, a później zdam sobie sprawę, że była nieefektywna, jak zaoszczędzić czas obliczeniowy bez ponownego uruchamiania z drugą opcją?
NelsonGon
4
Zainspirowany odpowiedzią anubhavy, która moim zdaniem jest nie do zaakceptowania, ponieważ uruchamia każde polecenie dwukrotnie.
Jedną wadą, którą odkryłem, jest to, że żadne z twoich poleceń nie myśli, że działają już na tty, co oznacza, że potrzebujesz specjalnej uwagi, aby kody kolorów działały dla narzędzi takich jak greplub git diff+1
Marty Neal
2
Tak jak powiedział konsolebox, musiałbyś włamać się do samego basha. Oto całkiem dobry przykład, jak można to osiągnąć. Repozytorium stderred (w rzeczywistości przeznaczone do kolorowania standardowego wyjścia) zawiera instrukcje, jak je zbudować.
I spróbowaliśmy: definiowanie jakiegoś nowego deskryptora pliku wewnątrz .bashrcjak
exec 41>/tmp/my_console_log
(liczba jest dowolna) i stderred.codpowiednio zmodyfikuj , aby treść również została zapisana na fd 41. W pewnym sensie działała, ale zawiera mnóstwo bajtów NUL, dziwne formatowanie i jest w zasadzie danymi binarnymi, nieczytelnymi. Może ktoś, kto dobrze rozumie C, mógłby to wypróbować.
Jeśli tak, wszystko, co jest potrzebne do uzyskania ostatniej wydrukowanej linii, to tail -n 1 [logfile].
Tak, po co za każdym razem pisać dodatkowe wiersze. Możesz przekierować z powrotem na wejście, ale wyjście na wejście (1> & 0) nie działa. Nie będziesz też chciał wielokrotnie pisać funkcji w każdym pliku dla tego samego.
Jeśli nigdzie nie eksportujesz plików i zamierzasz używać ich tylko lokalnie, możesz ustawić w Terminalu deklarację funkcji. Musisz dodać funkcję w ~/.bashrcpliku lub w ~/.profilepliku. W drugim przypadku musisz włączyć Run command as login shellz Edit>Preferences>yourProfile>Command.
Utwórz prostą funkcję, powiedz:
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<&-}
Skrypt (dodaj do swojego .bashrclub .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 }
Stosowanie
$ find .-name 'filename'| cap
/path/to/filename
$ ret
/path/to/filename
Zwykle dodaję | capna końcu wszystkich moich poleceń. W ten sposób, gdy stwierdzę, że chcę przetworzyć tekst na wyjściu wolno działającego polecenia, zawsze mogę go pobrać res.
Jaki jest sens cat -w cap () { cat - | tee /tmp/capture.out}tutaj? Czy cap () { tee /tmp/capture.out }pojawiają się jakieś problemy, których mi brakuje?
Watson
1
@Watson dobra uwaga! Nie wiem, dlaczego mam taki nawyk. Czy powinienem dodać cat - | cat - | cat -wcześniej, żeby było ciekawiej? 😉 Naprawię to po przetestowaniu, aby upewnić się, że to naprawdę spandrel
Connor,
0
Nie jestem pewien, do czego to potrzebujesz, więc ta odpowiedź może nie być odpowiednia. Zawsze możesz zapisać wynik polecenia:, netstat >> output.txtale nie sądzę, że tego właśnie szukasz.
Istnieją oczywiście opcje programowania; możesz po prostu uzyskać program, który przeczyta powyższy plik tekstowy po uruchomieniu tego polecenia i skojarzy go ze zmienną, aw Ruby, moim wybranym języku, możesz utworzyć zmienną z wyjścia polecenia za pomocą `` lewych apostrofów '':
output =`ls`#(this is a comment) create variable out of commandif 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
Umieść to w pliku .rb i uruchom: ruby file.rba utworzy zmienną z polecenia i pozwoli na manipulowanie nią.
„Nie wiem dokładnie, czego potrzebują to dla” Well, można powiedzieć, (przez co rozumiem ja ) po prostu zabrakło skrypt długim czasie trwania, chcesz szukać wyjścia, i głupio zapomniał przekierować wyjście przed wykonaniem. Teraz chcę spróbować naprawić swoją głupotę bez ponownego uruchamiania skryptu.
jscs
0
Mam pomysł, którego nie mam czasu na natychmiastową realizację.
Ale co, jeśli zrobisz coś takiego:
$ 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!
Mogą wystąpić problemy z buforowaniem we / wy. Plik może również stać się zbyt duży. Trzeba byłoby znaleźć rozwiązanie tych problemów.
Jeśli nie chcesz ponownie obliczyć poprzedniego polecenia, możesz utworzyć makro, które skanuje bieżący bufor terminala, próbuje odgadnąć -supposed- wynik ostatniego polecenia, kopiuje je do schowka i na koniec wpisuje do terminala.
Może być używany do prostych poleceń, które zwracają pojedynczą linię wyjścia (testowane na Ubuntu 18.04 z gnome-terminal).
W gnome-terminalpodróży do Preferences -> Shortcuts -> Select alli ustawić go Ctrl+shift+a.
Utwórz następujący skrypt 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
W ustawieniach klawiatury dodaj następujący skrót klawiaturowy:
Odpowiedzi:
Możesz użyć
$(!!)
do przeliczenia (nie ponownego użycia) wyniku ostatniego polecenia.!!
Na własnych wykonuje ostatnie polecenie.źródło
$(your_cmd)
za pomocą grawitacji:`your_cmd`
Zgodnie z instrukcją Gnu Bash są one funkcjonalnie identyczne. Oczywiście jest to również przedmiotem ostrzeżenia podniesionego przez @memecsgit diff $(!!)
gdzie poprzednie polecenie byłofind
wywołaniem.$()
zamiast graweru. Ale prawdopodobnie nie ma nad czym stracić snu. github.com/koalaman/shellcheck/wiki/SC2006$()
.Odpowiedź brzmi nie. Bash nie przydziela żadnego wyjścia do żadnego parametru ani żadnego bloku w swojej pamięci. Ponadto możesz uzyskać dostęp do Bash tylko poprzez dozwolone operacje interfejsu. Prywatne dane Bash nie są dostępne, chyba że je zhakujesz.
źródło
Jednym ze sposobów jest użycie
trap DEBUG
:Teraz stdout i stderr ostatnio wykonywanego polecenia będą dostępne w
/tmp/out.log
Jedynym minusem jest to, że wykona polecenie dwukrotnie: raz, aby przekierować wyjście i błąd do
/tmp/out.log
i raz normalnie. Prawdopodobnie istnieje również sposób, aby temu zapobiec.źródło
rm -rf * && cd ..
, nie tylko bieżący katalog, ale także katalog nadrzędny zostanie usunięty? takie podejście wydaje mi się bardzo niebezpiecznetrap '' DEBUG
Jeśli korzystasz z komputera Mac i nie masz nic przeciwko przechowywaniu wyników w schowku zamiast zapisywania w zmiennej, możesz użyć pbcopy i pbpaste jako obejścia.
Na przykład, zamiast robić to, aby znaleźć plik i porównać jego zawartość z innym plikiem:
Możesz to zrobić:
Ciąg
/var/bar/app/one.php
znajduje się w schowku po uruchomieniu pierwszego polecenia.Nawiasem mówiąc, pb in
pbcopy
ipbpaste
oznacza pasteboard, synonim schowka.źródło
$ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
pbpaste
razem z zastępowaniem poleceń.Zainspirowany odpowiedzią anubhavy, która moim zdaniem jest nie do zaakceptowania, ponieważ uruchamia każde polecenie dwukrotnie.
W ten sposób wynik ostatniego polecenia znajduje się w / tmp / last, a polecenie nie jest wywoływane dwukrotnie.
źródło
grep
lubgit diff
+1Tak jak powiedział konsolebox, musiałbyś włamać się do samego basha. Oto całkiem dobry przykład, jak można to osiągnąć. Repozytorium stderred (w rzeczywistości przeznaczone do kolorowania standardowego wyjścia) zawiera instrukcje, jak je zbudować.
I spróbowaliśmy: definiowanie jakiegoś nowego deskryptora pliku wewnątrz
.bashrc
jak(liczba jest dowolna) i
stderred.c
odpowiednio zmodyfikuj , aby treść również została zapisana na fd 41. W pewnym sensie działała, ale zawiera mnóstwo bajtów NUL, dziwne formatowanie i jest w zasadzie danymi binarnymi, nieczytelnymi. Może ktoś, kto dobrze rozumie C, mógłby to wypróbować.Jeśli tak, wszystko, co jest potrzebne do uzyskania ostatniej wydrukowanej linii, to
tail -n 1 [logfile]
.źródło
Tak, po co za każdym razem pisać dodatkowe wiersze. Możesz przekierować z powrotem na wejście, ale wyjście na wejście (1> & 0) nie działa. Nie będziesz też chciał wielokrotnie pisać funkcji w każdym pliku dla tego samego.
Jeśli nigdzie nie eksportujesz plików i zamierzasz używać ich tylko lokalnie, możesz ustawić w Terminalu deklarację funkcji. Musisz dodać funkcję w
~/.bashrc
pliku lub w~/.profile
pliku. W drugim przypadku musisz włączyćRun command as login shell
zEdit>Preferences>yourProfile>Command
.Utwórz prostą funkcję, powiedz:
W głównym skrypcie:
Bash zapisuje zmienną nawet poza poprzednim zakresem:
źródło
Bardzo proste rozwiązanie
Takiego, którego używam od lat.
Skrypt (dodaj do swojego
.bashrc
lub.bash_profile
)Stosowanie
Zwykle dodaję
| cap
na końcu wszystkich moich poleceń. W ten sposób, gdy stwierdzę, że chcę przetworzyć tekst na wyjściu wolno działającego polecenia, zawsze mogę go pobraćres
.źródło
cat -
wcap () { cat - | tee /tmp/capture.out}
tutaj? Czycap () { tee /tmp/capture.out }
pojawiają się jakieś problemy, których mi brakuje?cat - | cat - | cat -
wcześniej, żeby było ciekawiej? 😉 Naprawię to po przetestowaniu, aby upewnić się, że to naprawdę spandrelNie jestem pewien, do czego to potrzebujesz, więc ta odpowiedź może nie być odpowiednia. Zawsze możesz zapisać wynik polecenia:,
netstat >> output.txt
ale nie sądzę, że tego właśnie szukasz.Istnieją oczywiście opcje programowania; możesz po prostu uzyskać program, który przeczyta powyższy plik tekstowy po uruchomieniu tego polecenia i skojarzy go ze zmienną, aw Ruby, moim wybranym języku, możesz utworzyć zmienną z wyjścia polecenia za pomocą `` lewych apostrofów '':
Umieść to w pliku .rb i uruchom:
ruby file.rb
a utworzy zmienną z polecenia i pozwoli na manipulowanie nią.źródło
Mam pomysł, którego nie mam czasu na natychmiastową realizację.
Ale co, jeśli zrobisz coś takiego:
Mogą wystąpić problemy z buforowaniem we / wy. Plik może również stać się zbyt duży. Trzeba byłoby znaleźć rozwiązanie tych problemów.
źródło
Myślę, że użycie polecenia skryptu może pomóc. Coś jak,
skrypt -c bash -qf fifo_pid
Używanie funkcji basha do ustawiania po przeanalizowaniu.
źródło
Jeśli nie chcesz ponownie obliczyć poprzedniego polecenia, możesz utworzyć makro, które skanuje bieżący bufor terminala, próbuje odgadnąć -supposed- wynik ostatniego polecenia, kopiuje je do schowka i na koniec wpisuje do terminala.
Może być używany do prostych poleceń, które zwracają pojedynczą linię wyjścia (testowane na Ubuntu 18.04 z
gnome-terminal
).Zainstalować następujące narzędzia:
xdootool
,xclip
,ruby
W
gnome-terminal
podróży doPreferences -> Shortcuts -> Select all
i ustawić goCtrl+shift+a
.Utwórz następujący skrypt ruby:
W ustawieniach klawiatury dodaj następujący skrót klawiaturowy:
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 '
Powyższy skrót:
źródło