opcionalmente executa vários comandos ao iniciar o tmux

7

Eu tenho um arquivo ~/.tmux/dev que se parece com isso:

selectp -t 0    # select the first pane
splitw -h -p 50 # split it into two halves

selectp -t 1    # select the new, second (1) pane
splitw -v -p 50 # split it into two halves

selectp -t 0    # go back to the first pane
send-keys 'vim .' Enter

Se eu executar o tmux source-file ~/.tmux/dev dentro de uma sessão do tmux, tudo funcionará bem.

Eu quero criar um script bash que abra o tmux e execute automaticamente esses comandos.

Eu tentei rodar

tmux new 'tmux source-file ~/.tmux/dev'

mas eu só vejo dois painéis; o painel com o vim está faltando.

Eu li Como faço para o tmux abrir um conjunto de painéis sem inseri-los manualmente? , mas antes de instalar uma ferramenta para gerenciar configurações do tmux, eu gostaria de destacar o que está acontecendo aqui.

Agradecemos antecipadamente por qualquer luz que você possa lançar sobre o assunto.

    
por scribu 31.03.2013 / 03:24

2 respostas

6

Isso é o que está acontecendo:

  1. tmux new 'tmux source-file ~/.tmux/dev'

    O comando new cria uma nova sessão com uma única janela que possui um único painel. O comando tmux source-file ~/.tmux/dev é executado nesse novo painel.

    • Então, você tem uma nova sessão N (onde N é algum número), com
    • uma única janela N:0 (ou o que tiver base-index definido como), com
    • um único painel N:0.0 (ou o que você tiver base-pane-index definido como)
    • executando o comando tmux source-file ~/.tmux/dev .
  2. O comando source-file é processado.

    1. Os painéis extras são adicionados.
    2. O painel 0 está (re) selecionado.
    3. O comando send-keys , em seguida, "tipos" vim . + Digite no painel 0.
      Esta entrada é ignorada porque este painel está apenas executando o cliente tmux que enviou o comando source-file .
  3. O cliente tmux sai, fechando assim o painel 0.

Portanto, o bit inesperado é que o painel 0 (ou seja, N:0.0 ) está executando (apenas) o comando source-file , que ignora o comando "digitado". Esse painel nunca executa um shell interativo que possa interpretar o comando "digitado".

Existem pelo menos algumas maneiras de corrigir isso:

  • Inicie o ~/.tmux/dev com new-window para que o painel 0 esteja executando o seu "comando padrão" (ou seja, provavelmente um shell interativo).

    Esse método tem a vantagem de não presumir que o painel atual está executando um shell interativo e também de não assumir que o painel atual é 0 (ou seja, o que acontece se você executar sua série original de comandos em um painel que é parte de uma janela já dividida?). Isso significa que você pode vincular com segurança source-file ~/.tmux/dev a uma chave que possa ser executada em qualquer contexto (desde que crie uma nova janela para todos os seus painéis). No shell, você pode executar tmux source-file ~/.tmux/dev (para criar uma nova janela na sessão atual) ou seu tmux new 'tmux source-file ~/.tmux/dev' original para criar uma nova sessão.

    Uma pequena desvantagem desse método é que quando você executa tmux new 'tmux source-file ~/.tmux/dev' , a janela inicial ainda executará o cliente que envia source-file e sai rapidamente. Isto significa que a sua "janela principal" (aquela com as divisões) será uma mais alta que a sua base-index e uma futura nova janela será colocada antes da "janela principal". Você poderia consertar isso usando algo assim:

    tmux new 'tmux move-window -t 99 \; source-file ~/.tmux/dev'
    

    Ele move a janela inicial (efêmera) para um índice alto, de modo que new-window em ~/.tmux/dev acabe em base-index .

  • Use (por exemplo) tmux new 'tmux source-file ~/.tmux/dev ; zsh -l' para que o painel acabe executando um shell interativo após o término do comando source-file .

    A parte feia disso é que você acaba “codificando” seu shell preferido nesse comando. Além disso, a entrada send-keys ( vim . + Enter) é tecnicamente enviada antes do início do shell; provavelmente está tudo bem, mas nem sempre é completamente confiável.

    Você pode evitar "codificar" seu shell consultando tmux para o default-command (ou, se não estiver definido, default-shell (ou, se não estiver definido, usando SHELL)) , mas isso pode ser mais trabalho do que você realmente quer fazer.

por 31.03.2013 / 10:03
0

Eu poderia contornar um problema semelhante dessa maneira:

#!/bin/bash

tmp=$(mktemp --tmpdir=/tmp/).tmux

cleanup () {
        rm -f "$tmp"
}
trap cleanup EXIT

dump_cmd () {
        local i=$1
        shift
        echo "tcpdump -i $i -s 1500 \"port 67 or port 68\" -e $@"
}

cat <<-EOT > "$tmp"
        new-window
        send-keys '$(dump_cmd eno1)' Enter
        splitw -v -p 50
        send-keys '$(dump_cmd enp12s0f2)' Enter
EOT

tmux new 'tmux move-window -t 99 \; source-file '"$tmp"

# EOF #

Este script inicia dois sniffers em duas interfaces em dois painéis.

P.S.

Pode-se usar simplesmente

        new-window '$(dump_cmd eno1)'
        splitw -v -p 50 '$(dump_cmd enp12s0f2)'

em vez dessas quatro linhas, mas ^C to tcpdump também matará esse painel. Isso pode não ser o que você quer.

    
por 05.09.2016 / 14:55

Tags