Como faço para escapar desse comando su + sed?

2
#!/bin/bash
wineuser=tom
su $wineuser -c "sed -i '$ialias ptgui "wine ~/.wine/drive_c/Program\ Files/PTGui/PTGui.exe\"' /usr/people/$wineuser/config/cshrc.csh"

A linha acutal inserida no cshrc.csh do tom deve se parecer com

alias ptgui 'wine ~/.wine/drive_c/Program\ Files/PTGui/PTGui.exe'

o comando sed '$ ialias ...' $ i está inserindo antes da última linha no arquivo, não é uma variável definida.

Dicas ou manuais explicando escapes de vários níveis também são bem-vindos.

    
por Party Time 20.05.2015 / 22:55

1 resposta

4

A teoria

As regras são:

  • dentro de uma string delimitada por ' , nada é interpretado e nada além de ' não tem um significado especial. Isso significa que apenas um ' precisa ser salvo, mas também significa que, para escapar, você precisa da construção '\'' . (O primeiro ' termina a cadeia, o seguinte \' adiciona um literal ' (o escape impede o início de uma nova cadeia) e o último ' inicia uma nova cadeia, uma vez que essas três cadeias não estão separadas por um delimitador (geralmente um espaço), eles serão vistos como uma única sequência contínua.

  • Dentro de uma string " , a expansão da variável ocorre e as fugas são interpretadas. Portanto, se você quiser um literal \ , precisará escapar dele. Além disso, se você quiser um literal $ , você também precisará escapar (senão ele será interpretado como expansão de variável).

Você pode escapar de seu comando de maneira diferente, combinando esses dois estilos de cotação como você deseja. Uma possível solução para sua pergunta específica está listada abaixo.

Além disso, tenha em mente que sed também interpreta \ como um caractere de escape, o que significa que você também precisa escapar desse caractere ao usá-lo literalmente dentro de um script sed .

Exemplo

Pessoalmente, acho mais fácil começar pela unidade de código mais interna e trabalhar meu caminho para fora, citando cada vez na unidade de código interna os caracteres especiais para o método de citação externo usado.

Por exemplo, se você quiser substituir a string It's a test por It's my test no arquivo /home/user/I have spaces in my name.txt e colocar o resultado no arquivo /home/user/NoSpaces.txt , você pode usar " em torno dele para facilitar assim:

sed "s/It's a test/It's my test/" "/home/user/I have spaces in my name.txt" >/home/user/NoSpaces.txt

Agora, se você quisesse armazenar isso dentro de uma variável, teria que adicionar outro nível de cotação.

  • Você poderia fazer isso usando ' (o que significa apenas ter que escapar de outros caracteres ' em sua string atual):

    myvar='sed "s/It'\''s a test/It'\''s my test/" "/home/user/I have spaces in my name.txt" >/home/user/NoSpaces.txt'
    
  • Você também pode usar usando " style quotes:

    myvar="sed \"s/It's a test/It's my test/\" \"/home/user/I have spaces in my name.txt\" >/home/user/NoSpaces.txt"
    

A regra geral é sempre seguir com a solução mais limpa para você.

Uma solução

Assim sendo, para o seu problema específico, você pode tentar isso:

cmd="sed -i '\$ialias ptgui '\''wine ~/.wine/drive_c/Program\\ Files/PTGui/PTGui.exe'\' /usr/people/$wineuser/config/cshrc.csh"
su "$wineuser" -c "$cmd"

Observe que sugiro usar o comando a ppend em vez de i nsert para sed , mas isso está fora do escopo da questão.

    
por 20.05.2015 / 23:18