Como reutilizo a última saída da linha de comando?

44

Gostaria de saber como reutilizar a última saída do console, por exemplo:

pv-3:method Xavier$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/Library/Python/2.6/site-packages
pv-3:method Xavier$ cd **LASTOUTPUT**
    
por methodofaction 10.03.2011 / 20:59

11 respostas

40

Assumindo o bash:

% python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.7/site-packages
% cd $(!!)
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
% pwd
/usr/lib/python2.7/site-packages
    
por 10.03.2011 / 21:05
13

Ainda não mencionado, use uma variável:

dir=$( python -c ... )
cd "$dir"
    
por 10.03.2011 / 21:50
8

Todas as outras soluções envolvem modificar seu fluxo de trabalho ou executar o comando duas vezes, o que pode não ser adequado se levar muito tempo para ser executado ou não for repetitivo (por exemplo, ele exclui um arquivo - executando novamente um resultado diferente) .

Então, aqui vai uma ideia mais complicada se você precisar:

.bashrc

exec > >(tee -a ~/$$.out)

PROMPT_COMMAND='LASTLINE=$(tail -n 1 ~/$$.out)'

trap 'rm ~/$$.out' EXIT

prompt do bash

$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.6/dist-packages
$ cd $LASTLINE
$ pwd
/usr/lib/python2.6/dist-packages

Isso tem alguns problemas, então é apenas um ponto de partida. Por exemplo, o arquivo de saída ( ~/<pid>.out ) pode ficar muito grande e preencher seu disco. Além disso, todo o seu shell pode parar de funcionar se tee morrer.

Ele pode ser modificado para capturar apenas a saída do comando anterior usando preexec e precmd hooks em zsh ou uma emulação deles no bash, mas isso é mais complicado de descrever aqui.

    
por 10.03.2011 / 21:23
8

Um rascunho de trabalho para um shell tradicional:

ttyid=$(readlink /proc/$$/fd/1)
\___/   \______/ \___/ |  |  |
  |         |      |   |  |  \- 0: stdin 
  |         |      |   |  |     1: stdout <- our interest
  |         |      |   |  |     2: stderr
  |         |      |   |  \- fd is, maybe, filedescriptor
  |         |      |   |
  |         |      |   \- $$ is the PID of the current process (shell,
  |         |      |      in our case)
  |         |      |
  |         |      \- you know, much runtime stuff is here
  |         |
  |         \- readlink extracts the symbolic link of /proc/$$/fd/1
  |            lrwx------ 1 stefan stefan 64 2011-03-18 09:11
  |            /proc/22159/fd/1 -> /dev/pts/4
  |
  \- /dev/tty3 for real shell, /dev/pts/3 for xterm

Agora podemos catar a tela para um arquivo. Precisa de sudo.

id=${ttyid//\/dev\/tty}
sudo cat /dev/vcs$id > screen.dump

Apropos screendump : o programa assim chamado não funciona mais para mim. Talvez apenas para kernels mais antigos. / dev / pts / N não funcionou para mim também. Talvez você tenha que usar algum MKDEV opcional em / dev - eu me lembro sombriamente de alguns /dev/cuaN , mas posso estar errado.

Gostaríamos de canalizar a saída em vez de usar screen.dump. Mas de alguma forma não funciona - às vezes aguarda ENTER.

A captura não é um arquivo de texto normal com alimentações de linha, mas com - por exemplo - 80x50 caracteres em uma sequência.

Para escolher as últimas 2 linhas, 1 para a saída do comando e uma para a linha solicitante, eu reverti-a, escolho 160 caracteres, revendo novamente e escolhendo 80.

rev vcs4.dat | sed 's/\(.\{160\}\).*//g' | rev | sed 's/\(.\{80\}\).*//g'

Se você já se perguntou por que há um programa rev .

Crítica:

  • Os primeiros comandos são inseridos, movendo assim a linha. Bem - apenas um exercício numérico para escolher a terceira ou última linha ou algo assim. Eu trabalhei principalmente em uma janela diferente.
  • Nem todo mundo tem uma tela de 80x50. Bem, sim, nós sabemos. Há $ COLUMNS e $ ROWS para o seu prazer.
  • A saída não está sempre na parte inferior. Uma casca nova e fresca pode estar nas fileiras superiores. Bem simples assim: Avalie qual shell está sendo executado. Qual prompt é usado. Faça alguma detecção de prompt e encontre a última linha com um prompt de shell. A linha antes (ou 2. antes) deve conter o diretório.

O primeiro diagrama é feito com explain.py

    
por 18.03.2011 / 09:48
7

Tente isto:

$ cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
$ pwd
/Library/Python/2.6/site-packages
    
por 10.03.2011 / 21:06
6

Então, aqui está uma resposta:

Se você estiver executando em X, selecione a saída desejada com o mouse para copiá-lo e clique com o botão do meio para colá-lo.

Se você estiver usando um console de texto, poderá fazer algo semelhante com gpm .

    
por 10.03.2011 / 21:41
1

(Não é uma resposta de trabalho, infelizmente, mas ainda é algo curioso. Alguém interessado poderia muito bem tentar completar a implementação do recurso que eu vou lhe falar.)

Em eshell dentro do Emacs, eles queriam ter esse recurso, mas ele não foi implementado de forma completa (o que, no entanto, é um refletido na documentação ).

Por exemplo:

~ $ pwd
~
~ $ /bin/echo $$
~
~ $ /bin/pwd
/home/imz
~ $ /bin/echo $$

~ $ 

Você vê, somente a saída de builtins pode ser capturada na variável $$ .

Mas, bem, alguma programação elisp (cf. eshell-mark-output implementation em "esh-mode.el"), e você poderia implementar uma função que "marca" a última saída e retorna como resultado da função; para que você possa usar essa função em um comando eshell que você está pedindo - as funções elisp podem ser usadas em comandos eshell com a sintaxe usual do elisp, ou seja, entre parênteses, assim:

~ $ /bin/echo (buffer-name)
*eshell*
~ $ /bin/echo (car '(a b c))
a
~ $ 
    
por 16.03.2011 / 21:43
0

Se você perceber que vai querer reutilizar a saída antes de pressionar Enter , poderá salvá-la em uma variável: adicione tmp=$( no início da linha e ) no fim. (Isso remove qualquer linha em branco no final da saída do comando e, de fato, remove qualquer nova linha final; isso raramente é importante.)

tmp=$(python -c …)
echo "$tmp"
cd "$tmp"

Se o seu shell é ksh ou zsh, aqui está uma função útil que você pode usar para tornar isso mais automático. (Não é de nenhuma ajuda no bash porque requer que o último comando em um pipeline seja executado no shell pai, que é apenas o caso em ksh (não pdksh) e zsh.)

keep () {
  local line IFS=$'\n'
  kept=
  while read -r line; do
    printf '%s\n' "$line"
    kept=$kept$line$IFS
  done
}
alias keep=k

Use da seguinte maneira:

python -c … |k
cd $kept
    
por 12.03.2011 / 01:45
0
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()" | tee $(readlink /proc/$$/fd/1))

(acumulando em resposta de 4485 )

Isso é muita digitação, então faça um alias:

alias tee2tty='tee $(readlink /proc/$$/fd/1)'

Em seguida, basta chamar cd $(python -c ... | tee2tty)

Isso, obviamente, exige que você já saiba o que deseja fazer com a saída, mas tem a vantagem de chamar o comando apenas uma vez.

    
por 18.03.2011 / 10:15
0
$ cd \'python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"\'

fará o truque.

Leia aqui para mais detalhes: Substituição de comandos .

    
por 11.03.2011 / 17:26
0

Existe uma solução melhor:

Basta imprimir !! após o comando executado e você obterá uma saída repetida.

Por exemplo

Original:

link

    
por 07.02.2015 / 18:54