2014-08-29 25 views
9

Tôi dường như đang chạy vào một vấn đề cụ thể đối với ksh88 đang thay đổi dấu nháy đơn thành dấu ngoặc kép, nhưng chỉ trong một số trường hợp liên quan đến heredocs và lệnh thay thế.ksh88 thay đổi dấu nháy đơn thành dấu ngoặc kép trong heredocs?

Dưới đây là một ví dụ:

#!/bin/ksh 

# This example works correctly 
echo "Example 1:" 
cat <<EOF 
The 'quick' brown fox "jumped" over the lazy dog. 
EOF 
echo 


# This example is broken 
echo "Example 2:" 
var=$(cat <<EOF 
The 'quick' brown fox "jumped" over the lazy dog. 
EOF) 
echo "${var}" 
echo 


# This example works correctly 
echo "Example 3:" 
var=`cat <<EOF 
The 'quick' brown fox "jumped" over the lazy dog. 
EOF` 
echo "${var}" 
echo 

Và đây là kết quả (lưu ý cách Ví dụ 2 là khác nhau):

Example 1: 
The 'quick' brown fox "jumped" over the lazy dog. 

Example 2: 
The "quick" brown fox "jumped" over the lazy dog. 

Example 3: 
The 'quick' brown fox "jumped" over the lazy dog. 

Các ' để " thay dường như xảy ra trước lệnh chạy. Trong bối cảnh thực tế, heredoc đang chuyển SQL sang Oracle. Bằng cách thay đổi ' thành ", các chuỗi đang được chuyển đổi thành số nhận dạng, do đó phá vỡ SQL. Điều này cũng có thể được quan sát bằng cách kích hoạt xtrace trong khi thực thi mã trên.

Làm cách nào để ngăn chặn việc chuyển đổi ' sang " trong đoạn mã ở trên mà không sử dụng dấu gạch chéo ngược?


Chỉnh sửa: Cốt truyện dày hơn. Thay thế biến thế chỉ lệnh $(...) bằng ký hiệu backtick không thay thế dấu nháy đơn bằng dấu ngoặc kép. Vì vậy, (tùy chọn) câu hỏi hai: tại sao?

+3

Hành vi được mô tả giống như một lỗi. Thay đổi back-ticks thành '$ (…)' không nên thay đổi nội dung của đầu ra. Bạn không thể nâng cấp lên ['ksh93'] (http://www.kornshell.com/)? –

+0

@JonathanLeffler - Nếu nó là một lỗi, có vẻ khá nguy hiểm có chủ ý. Đối với chuyển đổi sang ksh93, đó không nhất thiết là một tùy chọn. Tập lệnh thực tế cần chạy trên nhiều máy chủ AIX và Solaris của các phiên bản khác nhau. Một số có ksh93, nhưng hầu hết chỉ có ksh88. –

+0

@ AdrianFrühwirth - 'echo $ {var}' và 'echo" $ {var} "' tạo ra kết quả tương tự trong tất cả các trường hợp trên. Nếu bạn kích hoạt xtrace '#!/Bin/ksh -x', bạn có thể thấy giá trị' var' ngay cả trước khi nó được hiển thị. –

Trả lời

5

Đây là ghi chú của tôi khi tôi phát hiện ra lỗi này cách đây vài năm.

kịch bản thử nghiệm:

#!/bin/ksh 
cat <<EOF 
    $PWD "$PWD" '$PWD' 
EOF 
echo `cat <<EOF 
    $PWD "$PWD" '$PWD' 
EOF 
` 
echo $(cat <<EOF 
    $PWD "$PWD" '$PWD' 
EOF 
) 

Output cho vỏ khác nhau:

  • Linux KSH Version M 1993/12/28 q
  • Linux Bash 3.00.15 (1)

(Chú ý: hoạt động như dự kiến)

/home/jrw32982 "/home/jrw32982" '/home/jrw32982' 
/home/jrw32982 "/home/jrw32982" '/home/jrw32982' 
/home/jrw32982 "/home/jrw32982" '/home/jrw32982' 
  • AIX Version M-11/16/tầng 88
  • Solaris Version M-11/16/88i

(LƯU Ý: các dấu nháy đơn được thay thế bằng dấu ngoặc kép và biến không được thay thế)

/home/jrw32982 "/home/jrw32982" '/home/jrw32982' 
/home/jrw32982 "/home/jrw32982" '/home/jrw32982' 
/home/jrw32982 "/home/jrw32982" "$PWD" 

làm việc xung quanh:

  1. Tính đơn trích dẫn chuỗi bên ngoài từ đây-file

    abc=xyz 
    STR="'$abc'" 
    x=$(cat <<EOF 
        $abc "$abc" $STR 
    EOF 
    ) 
    
  2. Sử dụng ở đây-file trong một chức năng thay vì trực tiếp

    fn() { 
        cat <<EOF 
        $abc "$abc" '$abc' 
    EOF 
    } 
    abc=xyz 
    x=$(fn) 
    
Các vấn đề liên quan