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 / 410983
Accepted
Wildcard
Wildcard
Asked: 2017-12-15 21:58:06 +0800 CST2017-12-15 21:58:06 +0800 CST 2017-12-15 21:58:06 +0800 CST

Como o Bash lida com aspas na seção de substituição de string da expansão de parâmetros?

  • 772

Existe alguma lógica consistente nisso?

some-command "${somevariable//some pattern/'how does this get parsed?'}"

Postei algumas conclusões e testes brutos abaixo como uma "resposta", mas eles não são uma resposta completa de forma alguma. A página de manual do Bash parece silenciosa sobre o assunto.

bash quoting
  • 3 3 respostas
  • 2414 Views

3 respostas

  • Voted
  1. Best Answer
    ilkkachu
    2017-12-16T04:00:24+08:002017-12-16T04:00:24+08:00

    Conforme discutido nos comentários, isso parece ter mudado entre as versões do Bash. Eu acho que esta é a mudança relevante no bash-4.3-alpha( changelog ):

    zz. Ao usar a expansão de palavra de substituição de padrão, o bash agora executa a string de substituição por meio da remoção de aspas, pois permite que as aspas nessa string atuem como caracteres de escape. Isso não é compatível com versões anteriores, portanto, pode ser desativado definindo o modo de compatibilidade do bash como 4.2.

    E a descrição para shopt -s compat42( manual online ):

    compat42
    Se definido, o bash não processa a string de substituição na expansão da palavra de substituição de padrão usando a remoção de aspas.

    O exemplo de aspas simples:

    $ s=abc\'def; echo "'${s//\'/\'\\\'\'}'"
    'abc'\''def'
    
    $ shopt -s compat42
    $ s=abc\'def; echo "'${s//\'/\'\\\'\'}'"
    'abc\'\\'\'def'
    
    $ bash --version | head -1
    GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
    

    Solução alternativa: coloque a string de substituição em uma variável e não use aspas dentro da substituição:

    $ shopt -s compat42
    $ qq="'\''"; s=abc\'def; echo "'${s//\'/$qq}'";
    'abc'\''def'
    $ qq="'\''"; s=abc\'def; echo "'${s//\'/"$qq"}'";
    'abc"'\''"def'
    

    O engraçado é que, se a expansão não estiver entre aspas , as aspas serão removidas após a substituição, em todas as versões. Isso é s=abc; echo ${s/b/""}impressões ac. Isso obviamente não acontece com outras expansões, por exemplo, s='a""c' ; echo ${s%x}outputs a""c.

    • 7
  2. Wildcard
    2017-12-15T21:58:06+08:002017-12-15T21:58:06+08:00

    Regras gerais por engenharia reversa:

    • As cotações devem ser acopladas (concluídas)
    • As cotações são preservadas (incluídas na substituição real)
    • As barras invertidas são preservadas se vierem antes de uma letra arbitrária
    • As barras invertidas são preservadas se escaparem de uma aspa simples
    • Uma sequência de barra invertida é reduzida a uma barra invertida, mesmo entre aspas simples
    • Você não pode escapar de uma aspa simples dentro de aspas simples
    • A expansão de parâmetros funciona dentro de aspas simples da mesma forma que fora
    • Se um cifrão for escapado com uma barra invertida, o cifrão será preservado literalmente e a barra invertida será removida

    E uma conclusão:

    • Não há absolutamente nenhuma maneira de produzir a sequência literal '\''como uma substituição por meio da expansão de parâmetros.
    • No entanto, é muito fácil produzir a sequência literal "'\''"como uma substituição.

    Seguem alguns testes brutos.

    [vagrant@localhost ~]$ echo "$0"
    -bash
    [vagrant@localhost ~]$ echo "${0//a/x}"
    -bxsh
    [vagrant@localhost ~]$ echo "${0//a/some long string  with spaces}"
    -bsome long string  with spacessh
    [vagrant@localhost ~]$ echo "${0//a/"quoted string"}"
    -b"quoted string"sh
    [vagrant@localhost ~]$ echo "${0//a/"unfinished quote}"
    > wat
    > }"
    -b"unfinished quote}"
    wat
    sh
    [vagrant@localhost ~]$ echo "${0//a/\"escaped quote}"
    -b"escaped quotesh
    [vagrant@localhost ~]$ echo "${0//a/\\escaped escape}"
    -b\escaped escapesh
    [vagrant@localhost ~]$ echo "${0//a/\'escaped single quote}"
    -b\'escaped single quotesh
    [vagrant@localhost ~]$ echo "${0//a/''}"
    -b''sh
    [vagrant@localhost ~]$ echo "${0//a/''''}"
    -b''''sh
    [vagrant@localhost ~]$ echo "${0//a/'''}"
    > a'b}c"d
    -b'''}"
    a'bshcd
    [vagrant@localhost ~]$ echo "${0//a/'''}"
    > w'x}y"z
    -b'''}"
    w'xshyz
    [vagrant@localhost ~]$ echo "${0//a/'\'\\"a test'\'}"
    > ^C
    [vagrant@localhost ~]$ echo "${0//a/'\''\\"a test'\'}"
    -b'\''\"a test'\'sh
    [vagrant@localhost ~]$ echo "${0//a/'\''\\"a test'\$0'}"
    > ^C
    [vagrant@localhost ~]$ echo "${0//a/\\"a test'\$0'}"
    > w}x"y
    -b\"a test'$0'}"
    wshxy
    [vagrant@localhost ~]$ echo "${0//a/\\\"a test'\$0'}"
    -b\"a test'$0'sh
    [vagrant@localhost ~]$ echo "${0//a/\\\"a test'\\'$0'}"
    > ^C
    [vagrant@localhost ~]$ echo "${0//a/\\\"a test'\\$0'}"
    -b\"a test'\-bash'sh
    [vagrant@localhost ~]$ 
    
    • 1
  3. DocSalvager
    2020-07-21T00:58:47+08:002020-07-21T00:58:47+08:00

    Através da experimentação, descobri que a seguinte sintaxe funciona para converter aspas simples em aspas duplas no GNU bash, versão 5.0.11(1)-release (x86_64-pc-linux-gnu)...

    text="aaa'bbb'ccc"; echo "${text//$"'"/$'"'}"
    

    Resultado é...

    aaa"bbb"ccc
    

    Observe que o padrão de aspas simples deve ser colocado entre aspas duplas e a substituição de aspas duplas entre aspas simples.

    Existe uma loja relevante documentada como...

    extquote  
        If set, $'string' and $"string" quoting is performed within
        ${parameter} expansions  enclosed  in  double quotes.  This option
        is enabled by default.
    
    • 0

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

    Matriz JSON para bash variáveis ​​usando jq

    • 4 respostas
  • Marko Smith

    A data pode formatar a hora atual para o fuso horário GMT? [duplicado]

    • 2 respostas
  • Marko Smith

    bash + lê variáveis ​​e valores do arquivo pelo script bash

    • 4 respostas
  • Marko Smith

    Como posso copiar um diretório e renomeá-lo no mesmo comando?

    • 4 respostas
  • Marko Smith

    conexão ssh. Conexão X11 rejeitada devido a autenticação incorreta

    • 3 respostas
  • Marko Smith

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

    • 7 respostas
  • Marko Smith

    comando systemctl não funciona no RHEL 6

    • 3 respostas
  • Marko Smith

    rsync porta 22 e 873 uso

    • 2 respostas
  • Marko Smith

    snap /dev/loop em 100% de utilização -- sem espaço livre

    • 1 respostas
  • Marko Smith

    chave de impressão jq e valor para todos no subobjeto

    • 2 respostas
  • Martin Hope
    EHerman Matriz JSON para bash variáveis ​​usando jq 2017-12-31 14:50:58 +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
  • Martin Hope
    Drux A data pode formatar a hora atual para o fuso horário GMT? [duplicado] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC Como posso copiar um diretório e renomeá-lo no mesmo comando? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve Como as permissões de arquivo funcionam para o usuário "root"? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey Como baixar o pacote não instalá-lo com o comando apt-get? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao Por que os diretórios /home, /usr, /var, etc. têm o mesmo número de inode (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg — o comando list-keys gera uid [ desconhecido ] depois de importar a chave privada para uma instalação limpa 2017-11-26 18:26:02 +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