É possível fazer eco em um arquivo, mas usar recuo na fonte do script de shell? [duplicado]

6

Se eu tiver algumas instruções aninhadas e recuadas que fazem eco de uma cadeia de várias linhas em um arquivo, os recuos do shell original (no meu caso bash) serão transportados para o arquivo de destino.

Para evitar isso, eu removo os recuos da saída ecoada, mas isso perde a formatação de código recuada na minha origem, por exemplo,

#! /bin/bash

function configure_default_vhost() {

    case "$2" in
        [--production])
              echo "<VirtualHost *:80>
# These lines are "breaking" out of the preffered indenting
redirect 404 /
ErrorDocument 404
</VirtualHost>
" > /etc/apache/sites-availabe/000-default.conf
    esac
}

Estou com o objetivo de conseguir algo o mais próximo possível disso:

#! /bin/bash

function configure_default_vhost() {

    case "$2" in
        [--production])
              echo "<VirtualHost *:80>
                    # These lines are aligned with the preffered indenting
                    redirect 404 /
                    ErrorDocument 404
                    </VirtualHost>
                    " > /etc/apache/sites-availabe/000-default.conf
    esac
}

(Nota: esta questão foi listada como uma possível duplicação de uma questão relacionada a HEREDOC. Não tenho certeza de onde o lugar correto para responder a isso é por isso vou colocar aqui por agora sei que se não) Minha pergunta é sobre recuar blocos de código, e heredoc é apenas uma das muitas maneiras de conseguir isso e, na verdade, o HEREDOC não era a solução que eu escolhi.

    
por the_velour_fog 24.04.2015 / 16:05

3 respostas

2

Usando echo com a opção -e (ative a interpretação das saídas de barra invertida):

#!/bin/bash

function configure_default_vhost() {
    conf_file="/etc/apache/sites-availabe/000-default.conf"
    case "$2" in
        [--production])
            # The ">" overwrites; the ">>" appends. 
            {
                echo -e "<VirtualHost *:80>"
                echo -e "\tredirect 404 /"
                echo -e "\tErrorDocument 404"
                echo -e "</VirtualHost>"
            } > "$conf_file"
    esac
}
    
por 24.04.2015 / 16:22
11

Você pode usar um "aqui-documento" com o modificador - . Pode ser recuado por caracteres de tabulação. Você deve alternar de echo para cat .

cat <<-EOF > /etc/apache/sites-availabe/000-default.conf
        <VirtualHost *:80>
        redirect 404 /
        ErrorDocument 404     
        </VirtualHost>
EOF

Ou, para manter as guias no resultado, você pode pré-processar o documento AHERE, digamos sed e indentar com 4 espaços:

sed 's/^    //' <<EOF
....{
....(------)func () {
....(------)return
....(------)}
....}
EOF

Eu usei . em vez de um espaço e (------) em vez de uma guia para mostrar como formatar o script.

    
por 24.04.2015 / 16:09
8

Algumas abordagens:

  • printf '%s\n' > "$conf_file" \
      '<VirtualHost *:80>' \
      '  redirect 404 /' \
      '  ErrorDocument 404' \
      '</VirtualHost>'
    

    Se você quiser que as seqüências de escape sejam expandidas, substitua %s por %b :

    printf '%b\n' > "$conf_file" \
      '<VirtualHost *:80>' \
      '\tredirect 404 /' \
      '\tErrorDocument 404' \
      '</VirtualHost>'
    
  • @ abordagem cat <<- EOF da choroba , mas o recuo deve ser feito apenas com caracteres TAB e eles ' re tudo removido.

  • ...
      indent='
      '; cut -b "${#indent}-" << EOF > "$conf_file"
      <VirtualHost *:80>
        redirect 404 /
        ErrorDocument 404     
      </VirtualHost>
    EOF
    

    (o truque é ter $indent mantendo o número de caracteres de recuo para aparar (cuidado desta vez, recuo tem que ser feito com caracteres de espaço, não abas)).

  • ...
      cut -d'|' -f2- << EOF > "$conf_file"
      |echo "<VirtualHost *:80>
      |  redirect 404 /
      |  ErrorDocument 404     
      |</VirtualHost>
    EOF
    

    As sequências de escape não serão expandidas, mas as variáveis e as substituições de comando serão. Citar EOF para evitar isso ( cut... << 'EOF' , por exemplo).

  • Você também pode cortar o recuo com base no da primeira linha:

    show() {
      expand | awk 'NR == 1 {match($0, /^ */); l = RLENGTH + 1}
                    {print substr($0, l)}'
    }
    ...
      show << EOF > "$conf_file"
        <VirtualHost *:80>
          redirect 404 /
          ErrorDocument 404     
        </VirtualHost>
    EOF
    
por 24.04.2015 / 16:19