Como dizer ao vira-lata para não esperar o retorno de um programa de anexos?

9

Eu uso esta linha para imagens no meu mailcap:

image/*; eog %s &;

mas o mutt exclui imediatamente o arquivo temporário e o eog não pode carregá-lo.
Quando removo, o &mutt aguarda que o eog seja fechado até que ele escape da linha de comando.

Profpatsch
fonte

Respostas:

9

Aqui está o que eu uso:

.mailcap:

application/*; mkdir -p /tmp/mutt \; cp %s /tmp/mutt \; xdg-open /tmp/mutt/$(basename %s) &

.mutt / muttrc:

folder-hook . `rm -f /tmp/mutt/*`

Sempre que é feita uma tentativa de abrir um anexo, ele é copiado em um diretório temporário dedicado e a cópia é aberta.
Sempre que você inicia mutt, as cópias restantes são limpas.

Você pode ou não precisar &no final, dependendo do comando usado. (Algumas versões xdg-openestão bloqueando, enquanto outras não.)

Escusado será dizer que você pode usar isso com qualquer comando. xdg-opené apenas um manipulador de uma paragem conveniente.


fonte
Essa é uma maneira geral legal de substituir o mailcap! Obrigado!
Profpatsch 17/01
Eu precisava do &xdg-open depois. Não pode machucar tê-lo lá em qualquer caso, certo?
Profpatsch
Talvez você pudesse fazer uma pergunta: Como substituir mailcapcom xdg-open? e copie essa resposta. Tenho certeza que existem algumas pessoas com essa pergunta.
Profpatsch 17/01
2
Isso não seria problemático se você tivesse vários aplicativos abertos por alterar pastas de mutt, eliminaria qualquer coisa na sua pasta / tmp / mutt /. Desde poder xdg-aberto ou não pode bloquear Estou apenas usando o aplicativo (firefox) text/html; t=$(mktemp /tmp/XXXXXXXXXX) \; cp %s "$t" \; /bin/sh -c "firefox $t \; rm $t \;" &
Derek Schrock
Eu sei que essa é uma pergunta antiga, mas eu a encontrei agora porque estou experimentando a configuração do Mutt. Minha solução foi usar o Neomutt's shutdown-hook; isso apenas esvazia o diretório tmp quando o mutt é desligado.
Thriveth
3

Você pode usar um comando wrapper que:

  1. renomeia o arquivo
  2. executa o visualizador em segundo plano
  3. limpa quando o espectador retorna em vez de deixá- muttlo.

Algo como:

#! /bin/sh -

TMPDIR=$(
  mutt -D 2> /dev/null |
    awk -F\" '
      $1 == "tmpdir=" {
        gsub("~", ENVIRON["HOME"], $2)
        print $2
        exit
      }'
)
[ -n "$TMPDIR" ] || exit
export TMPDIR

nargs=$#
nfiles=0
for i do
  case $i in
    ("$TMPDIR"/?*)
      new_file=$(mktemp -ut "XXXXX${i##*/}") &&
        mv -- "$i" "$new_file" &&
        nfiles=$(($nfiles + 1)) &&
        set -- "$new_file" "$@" "$new_file" &&
        continue
  esac
  set -- "$@" "$i"
done

run_command() (
  shift "$(($nargs + $nfiles))"
  exec "$@"
)

(
  run_command "$@"
  while [ "$nfiles" -gt 0 ]; do
    set -- "$@" "$1"
    shift
    nfiles=$(($nfiles - 1))
  done
  shift "$((2*$nargs))"
  rm -f -- "$@"
) &

E colocar algo como:

image/*; muttv eog %s;

Onde muttvestá esse script acima.

O exemplo acima não assume como os nomes dos arquivos aparecem na lista de argumentos ou que caractere eles contêm ... Por isso, perguntamos primeiro o muttque tmpdiré (então usamos isso para determinar quais são os arquivos vista ).

Na maioria dos casos, isso seria um exagero e, como aponta Gilles, pode não funcionar se tmpdir for especificado como relativo à sua pasta da caixa de correio.

Um mais simples seria:

#! /bin/sh -
nargs=$#
eval "file=\${$nargs}"
newfile=$(dirname -- "$file")/new-$(basename -- "$file")
while [ "$nargs" -gt 1 ]; do
  set -- "$@" "$1"
  shift
  nargs=$(($nargs - 1))
done
shift
mv -- "$file" "$newfile" || exit
(
  "$@" "$newfile"
  rm -f -- "$newfile"
) &

Substitua mvpor cpse você não quiser tocar no arquivo original fornecido por mutt.

Stéphane Chazelas
fonte
Puxa, você acabou de escrever isso do zero? Levei 15 minutos para entender o que você está fazendo e, mesmo agora, não tenho certeza de como algumas partes funcionam exatamente.
Profpatsch
Falha no meu .muttrcporque tmpdir="=tmp". Por que não pegar o diretório no nome do arquivo?
Gilles 'SO- stop be evil'
@ Gilles, bom argumento sobre o "+", "=" ... O ponto principal era obter o tmpdir do mutt, para que saibamos qual dos argumentos é o nome do arquivo. A coisa toda é um pouco exagerado, embora de qualquer maneira como em 99% dos casos o nome do arquivo vai ocorrer apenas uma vez e ser o último argumento, e nós podemos apenas renomeá-lo paranew-$original
Stéphane Chazelas
Outro ponto é que esse script de entrada nem sempre é chamado em nome de mutt; pode ser chamado em circunstâncias em que o arquivo não é temporário e não deve ser excluído. (Costumo ligar seepara a linha de comando, não espero que ele remova o arquivo, mesmo que esteja dentro /tmp!) Solução: crie um link físico.
Gilles 'SO- stop be evil'
@Gilles, pensei no hardlink, mas, para o mutt, ele não funciona, porque, depois de executar o comando, o mutt trunca o arquivo antes de desvinculá-lo. (abra com O_TRUNC e feche, verifiquei).
Stéphane Chazelas