Você pode evitar digitar $(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
Na prática, a saída dos comandos é determinística, então eu não agonizaria com a recalculação. Certamente é útil quando você deseja fazer algo como git diff $(!!)onde o comando anterior foi uma findinvocação.
@ user2065875 embora os backticks ainda funcionem no Bash, eles foram preteridos em favor de $().
kurczynski 28/02
87
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.
É possível ter alguma função customizada do 'middleware' do bash que é executada antes de cada comando, onde tudo o que faz é salvar a saída resultante em algo que atue como uma área de transferência interna (por exemplo, BASH_CLIPBOARD)?
Pat Needham
@PatNeedham Não tenho certeza. Verifique os módulos carregáveis. Veja se você pode escrever um.
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.loge uma vez normalmente. Provavelmente, há alguma maneira de evitar esse comportamento também.
Então, quando eu digitar 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
phil294
1
Agora, como desfazer esta ação?
Kartik Chauhan
5
@KartikChauhan: Just dotrap '' DEBUG
anubhava
7
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:
Uma desvantagem que eu encontrei para isso é que nenhum de seus comandos acho que eles estão rodando em um tty mais, o que significa que precisam de atenção especial para obter os códigos de cores a trabalhar para utilitários como grepou git diffum qualquer maneira embora
Marty Neal
2
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 .bashrccomo
exec 41>/tmp/my_console_log
(número é arbitrário) e modificar stderred.cde 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 ~/.bashrcarquivo ou no ~/.profilearquivo. No segundo caso, você precisa ativar a Run command as login shellpartir 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<&-}
# 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 }
Uso
$ find .-name 'filename'| cap
/path/to/filename
$ ret
/path/to/filename
Costumo adicionar | capao 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.
Qual é o ponto de cat -nos cap () { cat - | tee /tmp/capture.out}aqui? Existe cap () { tee /tmp/capture.out }algum soluço que eu sinto falta?
Watson
1
@Watson bom ponto! Não sei por que tenho isso lá, provavelmente hábito. Devo adicionar cat - | cat - | cat -antes apenas para torná-lo mais interessante? 😉 Vou consertar uma vez que testei para garantir que seja realmente um spandrel
Connor
0
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.txtmas 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 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
Coloque isso em um arquivo .rb e execute-o: ruby file.rbe ele criará uma variável fora do comando e permitirá que você a manipule.
"Não tenho certeza exatamente do que você está precisando disso" Bem, digamos que (com isso quero dizer que eu ) apenas executei um script de longa duração, deseje pesquisar a saída e estupidamente esqueci de redirecionar a saída antes de executar. Agora, quero tentar remediar minha estupidez sem executar novamente o script.
JSCs
0
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.
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-terminalir para Preferences -> Shortcuts -> Select alle 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:
Respostas:
Você pode usar
$(!!)
para recalcular (não reutilizar) a saída do último comando.Por
!!
si só, executa o último comando.fonte
$(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 @memecsgit diff $(!!)
onde o comando anterior foi umafind
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.
fonte
Uma maneira de fazer isso é usando
trap 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.fonte
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 mimtrap '' 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:
Você poderia fazer isso:
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
epbpaste
stand para área de transferência, um sinônimo de área de transferência.fonte
$ 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.
Dessa forma, a saída do último comando está em / tmp / last e o comando não é chamado duas vezes.
fonte
grep
ougit diff
um qualquer maneira emboraComo 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(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]
.fonte
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 aRun command as login shell
partir deEdit>Preferences>yourProfile>Command
.Faça uma função simples, diga:
No script principal:
O Bash salva a variável mesmo fora do escopo anterior:
fonte
Solução Muito Simples
Um que eu uso há anos.
Script (adicione ao seu
.bashrc
ou.bash_profile
)Uso
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á-lores
.fonte
cat -
noscap () { cat - | tee /tmp/capture.out}
aqui? Existecap () { 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 spandrelNã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':
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.fonte
Eu tenho uma ideia que não tenho tempo para tentar implementar imediatamente.
Mas e se você fizer algo como o seguinte:
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.
fonte
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.
fonte
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 paraPreferences -> Shortcuts -> Select all
e configurá-lo paraCtrl+shift+a
.Crie o seguinte script ruby:
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:
fonte