Làm thế nào để thoát dấu ngoặc kép trong vỏ?


65

Tôi gặp rắc rối với việc thoát khỏi các nhân vật trong bash. Tôi muốn thoát dấu ngoặc đơn và dấu ngoặc kép trong khi chạy lệnh dưới một người dùng khác. Đối với mục đích của câu hỏi này, giả sử tôi muốn lặp lại những điều sau trên màn hình:

'single quote phrase' "double quote phrase"

Làm cách nào tôi có thể thoát khỏi tất cả các ký tự đặc biệt, nếu tôi cũng cần chuyển sang một người dùng khác:

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

Tất nhiên, điều này không tạo ra kết quả đúng.


+1 cho "Tất nhiên, điều này không tạo ra kết quả đúng". bashcũng đang trên đường làm tôi phát điên
Rolf

Câu trả lời:


88

Bạn có thể sử dụng cú pháp chuỗi ký tự sau:

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

Từ man bash

Các từ có dạng $ 'chuỗi' được xử lý đặc biệt. Từ này mở rộng thành chuỗi, với các ký tự thoát dấu gạch chéo ngược được thay thế theo quy định của tiêu chuẩn ANSI C. Các chuỗi thoát dấu gạch chéo ngược, nếu có, được giải mã như sau:

          \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
Quá mức cần thiết. Trong hầu hết các trường hợp, bạn không cần sử dụng cú pháp chuỗi ký tự.
fpmurphy

Thêm chi tiết tại đây stackoverflow.com/a/16605140/149221
mj41

12

Trong trình bao POSIX, giả sử trong chuỗi của bạn không có biến, lệnh hoặc mở rộng lịch sử và không có dòng mới, hãy làm theo các quy định cơ bản sau:

  1. Để trích dẫn một chuỗi chung với các trích dẫn đơn, hãy thực hiện các hành động sau:

    1. Thay thế bất kỳ chuỗi ký tự không trích dẫn nào có cùng trình tự với các trích dẫn đơn hàng đầu và dấu phụ được thêm vào: 'aaa' ==> ''aaa''

    2. Thoát với dấu gạch chéo ngược mỗi ký tự trích dẫn có sẵn từ trước : ' ==> \'
      Đặc biệt,''aaa'' ==> \''aaa'\'

  2. Để trích dẫn một chuỗi chung có dấu ngoặc kép, hãy thực hiện các hành động sau:

    1. Thêm dấu ngoặc kép hàng đầu và dấu: aaa ==> "aaa"

    2. Thoát với dấu gạch chéo ngược mỗi ký tự trích dẫn kép và mỗi ký tự dấu gạch chéo ngược: " ==> \", \ ==> \\

Một vài ví dụ:

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

để ví dụ của bạn có thể được mở rộng với các mục sau:

#!/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

Ví dụ đơn giản về thoát dấu ngoặc kép trong shell:

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

Nó được thực hiện bằng cách hoàn thành đã mở một ( '), đặt thoát một ( \'), sau đó mở một ( ') khác.

Cách khác:

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

Nó được thực hiện bằng cách hoàn thành đã mở một ( '), đặt trích dẫn trong một trích dẫn khác ( "'"), sau đó mở một ( ') khác.

Liên quan: Làm thế nào để thoát dấu ngoặc đơn trong chuỗi trích dẫn đơn? tại stackoverflow SE


1

Câu trả lời được chấp nhận hoạt động cho trích dẫn đơn giản (một cấp):

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

Để có được lệnh được trình bày để làm việc, bạn cần trích dẫn hai lần.
Kịch bản này có thể làm tất cả công việc:

#!/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

Thực thi tập lệnh để có được:

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

Dòng đầu tiên hoạt động cho tiếng vang đơn giản:

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

Dòng thứ hai sẽ hoạt động cho lệnh trích dẫn kép:

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

-3

echo 'Tôi \' ma sinh viên 'không hoạt động. Nhưng các công việc sau đây:

echo $ 'I \' ma student 'Từ trang man của bash:

Một trích dẫn có thể không xảy ra giữa các trích dẫn đơn, ngay cả khi trước dấu gạch chéo ngược. .... Các từ có dạng $ 'chuỗi' được xử lý đặc biệt. Từ này mở rộng thành chuỗi, với các ký tự thoát dấu gạch chéo ngược được thay thế theo quy định của tiêu chuẩn ANSI C.


6
Điều này không thêm gì vào các câu trả lời hiện có.
jasonwryan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.