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 / 532811
Accepted
bit
bit
Asked: 2019-07-30 12:12:14 +0800 CST2019-07-30 12:12:14 +0800 CST 2019-07-30 12:12:14 +0800 CST

Como evitar a substituição de comandos na linha de comando?

  • 772

Acho que ao escrever texto como entrada para outro programa, quaisquer substituições de comando entre aspas duplas no texto pretendido são interpretadas e expandidas pelo shell

Os links na resposta aqui afirmam que aspas simples podem ser usadas para evitar a expansão de parâmetros ou a substituição de comandos. No entanto, estou descobrindo que colocar uma substituição de comando entre aspas simples também falha em impedir que o shell expanda a substituição de comando

Como você evita que o shell interprete as substituições de comando que são destinadas a texto em vez de um comando a ser executado?

Uma demonstração

$ echo "`wc -l *`"

tenta contar linhas em todos os arquivos no diretório atual

$ echo "'`wc -l *`'"

Mesmo resultado, ou seja, conta linhas em todos os arquivos no diretório atual

atualização A partir desta demonstração, percebi que o problema parece ser que estou citando as aspas simples. Acho que colocar aspas simples e `(backtick) entre aspas duplas preserva o significado literal de (ou seja, suprime) as aspas simples, mas não preserva o significado literal da backquote (ou seja, backtick) que introduz a substituição do comando.

No meu caso de uso, a entrada para outro comando precisa ser citada. Com este documento dizendo que:

Uma aspa simples não pode ocorrer entre aspas simples

Como você evita que uma substituição de comando entre aspas simples seja expandida quando a substituição de comando entre aspas simples está dentro de uma string entre aspas (duplas)? Deve haver uma maneira de fazer isso além de usar escapes de barra invertida

Situação atual

Em um programa que estou usando, a única maneira de dividir a descrição de uma tarefa em linhas separadas é colocar a descrição entre aspas duplas:

$ task add "first line doesn\'t say much
Second line says a lot but part of this line does not appear in the resulting description 'truncate -s0 !(temp_file | temp_dir)' truncates all files to 0 bytes as shown by: '`wc -l *`'"

A descrição resultante:

first line doesn\ -s0 !(temp_file | temp_dir)' truncates all files to 0 bytes as shown by: 0 file1 10 file2 0 directory1 0 directory2 502 file3 123 file4 162 file5 0 directory3

Como você pode ver

't say much
Second line says a lot but part of this line does not appear in the resulting description 'truncate

está faltando na descrição e o shell interpretou 'wc -l *'como uma substituição de comando, incluindo assim as contagens de linha de todos os arquivos no diretório atual como parte da descrição

O que está fazendo com que o shell remova a parte do argumento taskentre \(barra invertida) e -s, e como você evita que o shell interprete a substituição de comando entre aspas simples (ie '`wc -l *`')?

bash shell
  • 4 4 respostas
  • 3904 Views

4 respostas

  • Voted
  1. Stéphane Chazelas
    2019-07-30T13:38:11+08:002019-07-30T13:38:11+08:00

    Use citações fortes com aspas simples:

    printf '%s\n' '`wc -l *`'
    

    E se você também quiser incluir aspas simples nesse argumento passado para printf, precisará usar aspas diferentes para 'si mesmo, como:

    printf '%s\n' '`wc -l *` and a '"'"' character'
    

    Ou:

    printf '%s\n' '`wc -l *` and a '\'' character'
    

    Outras alternativas incluem escapar da `barra invertida entre aspas duplas:

    printf '%s\n' "\`wc -l *\` and a ' character"
    

    Ou ter `sido o resultado de alguma expansão:

    backtick='`'
    printf '%s\n' "${backtick}wc -l *${backtick} and a ' character"
    

    Observe também:

    cat << 'EOF'
    `wc -l *` and a ' character and a " character
    EOF
    

    para produzir texto arbitrário sem ter que se preocupar em citar (observe as aspas ao redor do primeiro EOF).

    Você também pode fazer:

    var=$(cat << 'EOF'
    echo '`wc -l *`'
    EOF
    )
    

    Que com ksh93ou mkshvocê pode otimizar para:

    var=$(<<'EOF'
    echo '`wc -l *`'
    EOF
    )
    

    (também funciona em zsh, mas ainda é executado catem um subshell) para $varconter literalmente echo '`wc -l *`'.

    No fishshell, você pode incorporar 'com :'...'\'

    printf '%s\n' '`wc -l *` and a \' character'
    

    mas de qualquer forma `não é especial lá, então:

    printf '%s\n' "`wc -l *` and a ' character"
    

    funcionaria também.

    Em rc, es ou zsh -o rcquotes, você pode inserir um 'dentro '...'com '':

    printf '%s\n' '`wc -l *` and a '' character'
    

    Consulte Como usar um caractere especial como um normal? para mais detalhes.

    • 11
  2. Best Answer
    ilkkachu
    2019-07-31T21:53:12+08:002019-07-31T21:53:12+08:00

    Aqui (quebras de linha adicionadas),

    $ task add "first line doesn\'t say much
    Second line says a lot but part of this line does not appear in the
    resulting description 'truncate -s0 !(temp_file | temp_dir)' truncates
    all files to 0 bytes as shown by: '`wc -l *`'"
    

    a string inteira está entre aspas duplas, então substituições de comandos e outras expansões serão executadas lá. Isso acontece no shell, antes de taskver essa string, e você precisará evitá-lo com barras invertidas ou colocando essa parte entre aspas simples.

    Por exemplo

    $ printf "%s\n" "...shown by: '\`wc -l *\`'"
    ...shown by: '`wc -l *`'
    

    Então,

    task add "...shown by: '\`wc -l *\`'"
    

    passaria a string ...shown by: '`wc -l *`'para task. Cabe a ele o que fazer com isso.

    Se você não quiser usar barras invertidas, aqui está a maneira de colocá-lo entre aspas simples:

    #               aaaaaaaaaaaaaaaaBBBBBBBBBBBaaa
    $ printf "%s\n" "...shown by: '"'`wc -l *`'"'"
    ...shown by: '`wc -l *`'
    

    (O a's marca as partes com aspas duplas, o B's as partes com aspas simples. Eles são apenas concatenados na linha de comando do shell. As aspas simples literais estão dentro das strings com aspas duplas.)


    Quanto às aspas simples e à barra invertida, você não precisa escapar uma aspa simples entre aspas duplas e, na verdade, a barra invertida permanecerá lá:

    $ printf "%s\n" "foo'bar"
    foo'bar
    $ printf "%s\n" "foo\'bar"
    foo\'bar
    

    Pelo que você mostra, parece que taskremove pelo menos a primeira string entre aspas simples do argumento (mais uma palavra depois disso, já que a parte removida foi 't say much ... 'truncate)

    O shell não fará isso, isso funciona bem:

    $ printf "%s\n" "a 'quoted string' to test"
    a 'quoted string' to test
    

    O que está fazendo com que o shell remova a parte do argumento taskentre \(barra invertida) e -s,

    É altamente provável que não seja o shell fazendo isso.

    e como você evita que o shell interprete a substituição de comando entre aspas simples acima (ie '`wc -l *`')?

    Não é aspas simples, é aspas duplas com aspas simples ao lado.

    • 4
  3. user138278
    2019-07-30T13:14:27+08:002019-07-30T13:14:27+08:00

    Você pode escapar dos acentos graves usando uma barra invertida, conforme mostrado abaixo:

    echo "\`wc -l *\`"
    
    • 1
  4. Keiji
    2019-07-31T04:14:48+08:002019-07-31T04:14:48+08:00

    Para escapar de qualquer sequência de caracteres arbitrária para que nenhum caractere especial seja processado e nenhuma substituição seja feita:

    1. Substitua cada 'por'\''
    2. Coloque a string resultante entre aspas simples.

    Por exemplo:

    `wc -l 'my file.txt'`
    

    Torna-se

    '`wc -l '\''my file.txt'\''`'
    

    Observe se a string começa ou termina com ', você termina com ''o início/fim, que não faz nada e pode ser removido, mas é válido deixá-la lá (por exemplo, para manter uma função de escape de string simples).

    • 0

relate perguntas

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

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

  • Como salvar um caminho com ~ em uma variável?

  • 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