A expansão da cinta pode ser executada dentro do comando 'at'?

1

Em bash , a expansão de chaves é executada como uma operação shell antes de executar o comando. 1 Isso significa que o seguinte funcionará:
echo {1..10} >output | at -m now

A saída será 1 2 3 4 5 6 7 8 9 10 .

O que não funciona é uma tentativa de executar a expansão de chaves dentro do comando at , que avisa que os comandos serão executados por /bin/sh , que no meu caso está vinculado a dash , o que não parece suportar expansão de intervalo usando chaves.

$ at - now
warning: commands will be executed using /bin/sh
at> echo {1..10} >output
at> <EOT>

Isso executará o comando em dash (ou Bourne ou qualquer shell com o qual você tenha /bin/sh vinculado), resultando na saída {1..10} .

Como a expansão de cinta pode ser executada ao usar o comando at desta maneira?

Estou interessado em ver outras soluções para isso além da que publiquei como resposta, como poder executar comandos com bash no prompt at . Parece mais esforço do que o necessário para criar um script para cada comando de linha que é executado a partir do prompt at .

    
por iyrin 23.03.2015 / 08:20

2 respostas

3

Existem três outras opções diretas. Um é um pouco frágil e depende dos detalhes de implementação dos shells, outro usa aqui documentos para fornecer o script para bash inline e o outro apenas usa -c para passar uma única linha.

De forma mais confiável e portável, use um documento aqui :

$ at now
warning: commands will be executed using /bin/sh
at> bash <<'EOF'
at> echo {1..5} >/tmp/output
at> EOF
at> <EOT>
job 24 at Mon Mar 23 20:41:20 2015
$ cat /tmp/output
1 2 3 4 5

<<word declara um documento aqui fornecido como entrada padrão para bash e dura até word . Citando 'EOF' o documento não está sujeito a expansão pelo shell, então você pode escrever um $ no corpo sem dash comê-lo. Seu script pode incluir algo diferente de EOF (ou sua palavra de escolha) no início de uma linha.

Esta é realmente a abordagem que eu recomendaria - você pode escrever quase exatamente como se estivesse usando bash , com apenas uma linha extra no início e no final para mostrar que há algo acontecendo.

Se for realmente apenas uma linha, apenas use bash -c para passar um único comando para executar:

$ at now
warning: commands will be executed using /bin/sh
at> bash -c 'echo {1..3} >/tmp/output'
at> <EOT>
job 25 at Mon Mar 23 20:50:03 2015
$ cat /tmp/output
1 2 3

Isso pode ser um pouco incômodo quando você tem aspas para usar dentro do comando também.

Mais agressivamente: atd geralmente envia trabalhos para o shell como entrada padrão (mas não acredito que seja obrigatório). Os reservatórios geralmente lêem entrada padrão linha por linha (mas não precisam se comportar dessa maneira).

Se suas implementações se comportarem dessa maneira, você poderá executar um truque desagradável para executar seu trabalho em outro shell:

$ at now
warning: commands will be executed using /bin/sh
at> bash
at> echo {1..10} >/tmp/output
at> <EOT>
job 22 at Mon Mar 23 20:40:00 2015
$ cat /tmp/output
1 2 3 4 5 6 7 8 9 10

Isso funciona porque sh lê a primeira linha e executa bash , e bash consegue ler o restante da entrada padrão como seus comandos. Isso é muito frágil, mas é a versão menos intrusiva quando funciona.

dash em si é notavelmente mais complicado nesta área do que muitos shells, e preencher um buffer interno é mais importante para ele. Outros shells simplistas, como sh do BusyBox, tendem a ter o comportamento de buffer de linha.

Por fim, embora você nunca seja necessário para usar um arquivo de script separado, em muitos casos, na verdade, será a melhor opção do que tentar ser inteligente demais sobre as coisas. Quando seus trabalhos são de uso único ou programaticamente gerados, estas são opções razoáveis, mas qualquer outra hora sugando-o e usando um script independente provavelmente vale a pena em termos de manutenção.

Eu realmente não posso recomendar a exploração stdin da última opção, mas é um truque fofo.

    
por 23.03.2015 / 09:13
0

A única solução que encontrei até agora é escrever um script (vamos chamar de expandme.sh), que especifica o uso de bash como o interpretador.

#!/bin/bash
echo {1..10} >output

Em seguida, execute o script no prompt at :

$ at - now
warning: commands will be executed using /bin/sh
at> expandme.sh
at> <EOT>

Agora, o script nos tirará do dash / Bourne exile que nos colocou e executará a expansão antes de despejar a saída.

    
por 23.03.2015 / 08:20

Tags