Kabuk tırnak kaçmak nasıl?


65

Bash'ta kaçan karakterlerle ilgili sorun yaşıyorum. Farklı bir kullanıcı altında bir komut çalıştırırken tek ve çift tırnaktan kaçmak istiyorum. Diyelim ki bu sorunun amaçları için aşağıdakileri ekranda yankı yapmak istiyorum:

'single quote phrase' "double quote phrase"

Farklı bir kullanıcıya geçmem gerekirse, tüm özel karakterlerden nasıl kurtulabilirim:

sudo su USER -c "echo \"'single quote phrase' \"double quote phrase\"\""

Elbette bu doğru sonucu vermez.


"Elbette, bu doğru sonuçları vermez" için +1. bashBeni kızdırmanın yolunda.
Rolf

Yanıtlar:


88

Aşağıdaki dize değişmez sözdizimini kullanabilirsiniz:

> echo $'\'single quote phrase\' "double quote phrase"'
'single quote phrase' "double quote phrase"

itibaren man bash

$ 'String' formundaki kelimeler özel olarak değerlendirilir. Sözcük, ANSI C standardında belirtildiği şekilde ters eğik çizgi karakterleriyle değiştirilen dizeye genişler. Ters eğik çizgi kaçış dizileri, varsa, aşağıdaki gibi çözülür:

          \a     alert (bell)
          \b     backspace
          \e
          \E     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \"     double quote
          \nnn   the eight-bit character whose value is the octal value nnn (one to three digits)
          \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
          \cx    a control-x character

5
Aşırı yükleme. Çoğu durumda string değişmez sözdizimini kullanmanıza gerek kalmaz.
fpmurphy

Daha fazla detay burada stackoverflow.com/a/16605140/149221
mj41

12

Bir POSIX kabuğunda, dizginizde değişken, komut ya da tarih genişletme olmadığını ve yeni satır olmadığını varsayarak şu temel reçeteleri izleyin:

  1. Tek tırnaklı genel bir dize alıntı yapmak için aşağıdaki işlemleri gerçekleştirin:

    1. Tekli olmayan tırnaklı karakterlerden oluşan herhangi bir diziyi, eklenen baştaki ve sondaki tekli tırnak işaretleri ile aynı sırayla değiştirin: 'aaa' ==> ''aaa''

    2. Her önceden var olan tek alıntı karakterinde ters eğik çizgi ile kaçış : ' ==> \'
      Özellikle,''aaa'' ==> \''aaa'\'

  2. Çift tırnaklı genel bir dize alıntı yapmak için aşağıdaki işlemleri gerçekleştirin:

    1. Baştaki ve sondaki çift tırnak ekleyin: aaa ==> "aaa"

    2. Her iki teklif alıntı karakteri ve her bir ters eğik çizgi karakteri ile bir ters eğik çizgi ile kaçış: " ==> \", \ ==> \\

Birkaç örnek:

''aaa""bbb''ccc\\ddd''  ==>  \'\''aaa""bbb'\'\''ccc\\ddd'\'\'
                        ==>  "''aaa\"\"bbb''ccc\\\\ddd''"

Böylece, örneğin aşağıdakilerle genişletilebilir:

#!/bin/sh

echo \''aaa'\'' "bbb"'
echo "'aaa' \"bbb\""

sudo su enzotib -c 'echo \'\'\''aaa'\''\'\'\'' "bbb"'\'
sudo su enzotib -c 'echo "'\''aaa'\'' \"bbb\""'

sudo su enzotib -c "echo \\''aaa'\\'' \"bbb\"'"
sudo su enzotib -c "echo \"'aaa' \\\"bbb\\\"\""

10

Kabuktan kaçan tırnaklara basit bir örnek:

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

Daha önce bir ( ') açıp bitirerek \', bir tanesini açarak ( ), daha sonra bir başkasını ( ') açarak yapılır .

Alternatif:

$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc

Daha önce açılmış olan bir ( ') komutunu bitirmek , başka bir alıntıya ( "'") alıntı yapmak , sonra başka bir açmak ( ') ile yapılır.

İlgili: Tek alıntı dizeler içinde tek tırnak kaçış nasıl? stackoverflow SE şirketinde


1

Kabul edilen cevap basit (bir seviye) alıntı için işe yarar:

$ echo $'\'single quote phrase\' "double quote phrase"'
'single quote phrase' "double quote phrase"

Komutun işe sunulmasını sağlamak için iki kez alıntı yapmanız gerekir.
Bu komut tüm işi yapabilirdi:

#!/bin/bash

quote () { 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

read -r line <<-\_line_to_quote_
'single quote phrase' "double quote phrase"
_line_to_quote_

quote "$line"; echo
quote "echo $(quote "$line")"; echo

Almak için komut dosyasını yürütün:

$ script
''\''single quote phrase'\'' "double quote phrase"'
'echo '\'''\''\'\'''\''single quote phrase'\''\'\'''\'' "double quote phrase"'\'''

İlk satır basit yankı için çalışıyor:

$ echo ''\''single quote phrase'\'' "double quote phrase"'
'single quote phrase' "double quote phrase"

İkinci satır çift alıntı komutu için çalışacaktır:

sudo su USER -c 'echo '\'''\''\'\'''\''single quote phrase'\''\'\'''\'' "double quote phrase"'\'''

-3

echo 'Ben öğrenciyim' çalışmıyor. Ancak aşağıdaki işler:

echo $ 'Ben öğrenciyim' bash man sayfasından:

Önceden ters eğik çizgiden önce olsa bile, tek tırnaklar arasında tek bir teklif oluşmayabilir. .... $ 'string' formundaki kelimeler özel olarak değerlendirilir. Sözcük, ANSI C standardında belirtildiği şekilde ters eğik çizgi karakterleriyle değiştirilen dizeye genişler.


6
Bu mevcut cevaplara hiçbir şey eklemez.
jasonwryan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.