A saída de um comando Bash é armazenada em qualquer registro? Por exemplo, algo semelhante a $?
capturar a saída em vez do status de saída.
Eu poderia atribuir a saída a uma variável com:
output=$(command)
mas isso é mais digitação ...
A saída de um comando Bash é armazenada em qualquer registro? Por exemplo, algo semelhante a $?
capturar a saída em vez do status de saída.
Eu poderia atribuir a saída a uma variável com:
output=$(command)
mas isso é mais digitação ...
Respostas:
Você pode usar $(!!)
para recalcular (não reutilizar) a saída do último comando.
Por !!
si só, executa o último comando.
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
$(your_cmd)
usando backticks: `your_cmd`
De acordo com o manual do Gnu Bash, eles são funcionalmente idênticos. Claro que isso também está sujeito à advertência levantada por @memecs
git diff $(!!)
onde o comando anterior foi uma find
invocação.
$()
vez de reticulares. Mas provavelmente nada para perder o sono. github.com/koalaman/shellcheck/wiki/SC2006
$()
.
A resposta é não. O Bash não aloca nenhuma saída para nenhum parâmetro ou bloco em sua memória. Além disso, você só pode acessar o Bash por suas operações de interface permitidas. Os dados privados do Bash não estão acessíveis, a menos que você os hackie.
Uma maneira de fazer isso é usando trap DEBUG
:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG
Agora, o comando stdout e stderr do comando executado mais recentemente estará disponível em /tmp/out.log
A única desvantagem é que ele executará um comando duas vezes: uma vez para redirecionar a saída e o erro /tmp/out.log
e uma vez normalmente. Provavelmente, há alguma maneira de evitar esse comportamento também.
rm -rf * && cd ..
, não apenas o diretório atual, mas também o diretório pai será apagado? esta abordagem parece altamente perigoso para mim
trap '' DEBUG
Se você estiver no Mac e não se importa de armazenar sua saída na área de transferência, em vez de gravar em uma variável, use pbcopy e pbpaste como uma solução alternativa.
Por exemplo, em vez de fazer isso para encontrar um arquivo e diferenciar seu conteúdo com outro arquivo:
$ find app -name 'one.php'
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.php
Você poderia fazer isso:
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php
A cadeia /var/bar/app/one.php
está na área de transferência quando você executa o primeiro comando.
By the way, pb in pbcopy
e pbpaste
stand para área de transferência, um sinônimo de área de transferência.
$ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
pbpaste
junto com a substituição de comandos.
Inspirado pela resposta de anubhava, que eu acho que não é realmente aceitável, pois executa cada comando duas vezes.
save_output() {
exec 1>&3
{ [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUG
Dessa forma, a saída do último comando está em / tmp / last e o comando não é chamado duas vezes.
grep
ou git diff
um qualquer maneira embora
Como o konsolebox disse, você teria que invadir o próprio bash. Aqui está um bom exemplo de como alguém pode conseguir isso. O repositório stderred (realmente destinado a colorir stdout) fornece instruções sobre como construí-lo.
Eu tentei: Definindo um novo descritor de arquivo dentro .bashrc
como
exec 41>/tmp/my_console_log
(número é arbitrário) e modificar stderred.c
de acordo para que o conteúdo também é gravado fd 41. tipo de funcionou, mas contém um monte de NUL bytes, formattings estranhos e é, basicamente, dados binários, não legível. Talvez alguém com um bom entendimento de C possa tentar isso.
Nesse caso, tudo o que é necessário para obter a última linha impressa é tail -n 1 [logfile]
.
Sim, por que digitar linhas extras sempre que acordado. Você pode redirecionar o retorno para a entrada, mas a saída para a entrada (1> & 0) não é necessária. Além disso, você não deseja escrever uma função repetidamente em cada arquivo para o mesmo.
Se você não estiver exportando os arquivos para qualquer lugar e pretender usá-lo apenas localmente, poderá fazer com que o Terminal configure a declaração de função. Você precisa adicionar a função no ~/.bashrc
arquivo ou no ~/.profile
arquivo. No segundo caso, você precisa ativar a Run command as login shell
partir de Edit>Preferences>yourProfile>Command
.
Faça uma função simples, diga:
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<&-
}
No script principal:
#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'"
O Bash salva a variável mesmo fora do escopo anterior:
#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++)); do echo ${arr[i]}; done
Um que eu uso há anos.
.bashrc
ou .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
Costumo adicionar | cap
ao final de todos os meus comandos. Dessa forma, quando eu descobrir que quero fazer o processamento de texto na saída de um comando de execução lenta, sempre posso recuperá-lo res
.
cat -
nos cap () { cat - | tee /tmp/capture.out}
aqui? Existe cap () { tee /tmp/capture.out }
algum soluço que eu sinto falta?
cat - | cat - | cat -
antes apenas para torná-lo mais interessante? 😉 Vou consertar uma vez que testei para garantir que seja realmente um spandrel
Não sei exatamente para que você está precisando disso, portanto, essa resposta pode não ser relevante. Você sempre pode salvar a saída de um comando:, netstat >> output.txt
mas acho que não é isso que você está procurando.
É claro que existem opções de programação; você pode simplesmente obter um programa para ler o arquivo de texto acima após a execução desse comando e associá-lo a uma variável. No Ruby, minha linguagem preferida, você pode criar uma variável sem saída de comando usando '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
Coloque isso em um arquivo .rb e execute-o: ruby file.rb
e ele criará uma variável fora do comando e permitirá que você a manipule.
Eu tenho uma ideia que não tenho tempo para tentar implementar imediatamente.
Mas e se você fizer algo como o seguinte:
$ 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!
Pode haver problemas com o buffer de E / S. Além disso, o arquivo pode ficar muito grande. Seria necessário encontrar uma solução para esses problemas.
Eu acho que usar o comando script pode ajudar. Algo como,
script -c bash -qf fifo_pid
Usando os recursos do bash para definir após a análise.
Se você não quiser recalcular o comando anterior, poderá criar uma macro que varre o buffer do terminal atual, tente adivinhar a saída do último comando - suposta -, copie-a para a área de transferência e, finalmente, digite-a no terminal.
Pode ser usado para comandos simples que retornam uma única linha de saída (testada no Ubuntu 18.04 com gnome-terminal
).
Instalar as seguintes ferramentas: xdootool
, xclip
,ruby
Em gnome-terminal
ir para Preferences -> Shortcuts -> Select all
e configurá-lo para Ctrl+shift+a
.
Crie o seguinte script 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
Nas configurações do teclado, adicione o seguinte atalho de teclado:
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 '
O atalho acima: