AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 793230
Accepted
merlin2011
merlin2011
Asked: 2025-04-02 13:51:06 +0800 CST2025-04-02 13:51:06 +0800 CST 2025-04-02 13:51:06 +0800 CST

É possível definir um bash heredoc com um delimitador de várias palavras que expanda variáveis?

  • 772

Considere o seguinte script:

#!/bin/bash

foo=Hello
bar=Word
cat <<EOF
No quotes single word delimiter expands
$foo
$bar

EOF

cat <<'EOF'
Single-quoted single word delimiter does not expand.
$foo
$bar

EOF

cat <<"EOF"
Double-quoted single word delimiter does not expand.
$foo
$bar

EOF

cat <<EOF\ SOME\ MORE
Unquoted multi-word word delimiter does not expand.
Can we get it to expand?
$foo
$bar

EOF SOME MORE

No último caso, estou usando um delimitador multipalavra, sem aspas, mas a saída é a seguinte:

Unquoted multi-word word delimiter does not expand.
Can we get it to expand?
$foo
$bar

Existe uma maneira de fazer o bash expandir variáveis ​​ao usar um delimitador heredoc de várias palavras?

bash
  • 2 2 respostas
  • 655 Views

2 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2025-04-02T16:50:19+08:002025-04-02T16:50:19+08:00

    Quando o delimitador ou qualquer parte dele é citado (por qualquer operador de citação, incluindo '...', "...", \, $'...', $"..."), nenhuma expansão é feita no documento aqui.

    O delimitador é um token único na sintaxe do shell, então qualquer caractere como espaço, tabulação (e outros caracteres de byte único classificados como espaços em branco no local), ;, <, |só pode ser usado em delimitadores se estiver entre aspas, pois eles delimitam tokens na sintaxe do idioma, o que significa que não haverá expansão no documento here, ou como parte de um "token" de shell que inclui espaços como $(foo bar), $[foo bar], $(( foo bar )), ${--foo bar}, etc. Ou você pode usar outros caracteres de espaço multibyte, como UTF-8 codificado U+00A0 NO-BREAK SPACE ou U+2003 EM SPACE

    bash-5.2$ cat << $(foo bar)
    > $(( 1 + 1 ))
    > $(foo bar)
    2
    

    Curiosamente, o espaço parece não ser considerado como citado em:

    bash-5.2$ cat << $(' ')
    > $(( 1 + 1 ))
    > $( )
    2
    

    Usando um espaço em branco multibyte:

    bash-5.2$ cat << FOO BAR
    > $(uname)
    > FOO BAR
    Linux
    

    O  entre FOOe BARacima é um caractere U+2003, não um espaço ASCII U+0020, codificado em UTF-8 como bytes 0xe2 0x80 0x83.

    Esteja ciente de que se esse script for executado em um local onde qualquer um desses três bytes for a codificação de um caractere classificado como espaço em branco , isso falhará, pois o bash o tratará como um separador, como espaço ou tabulação (um dos motivos pelos quais geralmente é recomendado colocar entre aspas caracteres não ASCII no bash).

    Na prática, porém, o único caractere não ASCII que sei que alguns sistemas (como alguns BSDs) consideram como em branco e que tem uma codificação de byte único é U+00A0, e só consegui encontrar o conjunto de caracteres NeXT onde esse caractere é codificado como 0x80 (pelo menos de acordo com a GNU libc ), mas nunca me deparei com um local usando esse charmap.

    (você também pode argumentar que usar espaços em branco não-ASCII em um script é uma maneira certa de confundir leitores e mantenedores do script)

    • 11
  2. muru
    2025-04-02T16:26:31+08:002025-04-02T16:26:31+08:00

    O manual do Bash, na seção Here Documents :

    O formato dos documentos aqui é:

    [n]<<[-]word
            here-document
    delimiter
    

    Nenhuma expansão de parâmetro e variável, substituição de comando, expansão aritmética ou expansão de nome de arquivo é realizada em word. Se qualquer parte de wordestiver entre aspas, o delimiteré o resultado da remoção de aspas em word, e as linhas no here-document não são expandidas. [...]

    E aspas incluem "o caractere de escape, aspas simples e aspas duplas". Então não parece que isso seja possível. As únicas expansões não mencionadas acima são as expansões de histórico e alias, e usar qualquer uma delas ainda exigiria aspas para uma palavra que inclua espaços ou outros metacaracteres. Conforme observado nos comentários, também há expansão de chaves e expansão de til, mas nenhuma delas ajuda aqui.

    • 9

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve