ต้องใช้อักขระใดบ้างเมื่อใช้ Bash


206

มีรายการที่ครอบคลุมของตัวละครที่ต้องหลบหนีใน Bash หรือไม่? สามารถตรวจสอบได้ด้วยsedหรือไม่

โดยเฉพาะอย่างยิ่งฉันกำลังตรวจสอบว่า%จำเป็นต้องหลบหนีหรือไม่ ฉันเหนื่อย

echo "h%h" | sed 's/%/i/g'

%และทำงานได้ดีโดยไม่ต้องหลบหนี มันหมายความว่า%ไม่จำเป็นต้องหลบหนี? นี่เป็นวิธีที่ดีในการตรวจสอบความจำเป็นหรือไม่?

และอื่น ๆ โดยทั่วไป: พวกเขาเป็นตัวละครเดียวที่จะหลบหนีในshellและbash?


4
โดยทั่วไปถ้าคุณสนใจคุณก็ทำผิด การจัดการข้อมูลไม่ควรเกี่ยวข้องกับการเรียกใช้ผ่านการแยกวิเคราะห์และกระบวนการประเมินผลที่ใช้สำหรับรหัสทำให้หนี moot นี่เป็นแนวขนานที่ใกล้เคียงที่สุดกับแนวทางปฏิบัติที่ดีที่สุดสำหรับ SQL โดยที่สิ่งที่ถูกต้องคือการใช้ตัวแปรผูกและสิ่งที่ผิดคือพยายามที่จะ "ฆ่าเชื้อ" ข้อมูลที่ถูกฉีดผ่านการแทนที่สตริง
Charles Duffy

เกี่ยวข้องกับstackoverflow.com/questions/2854655/…
skywinder

8
@CharlesDuffy ใช่ แต่บางครั้งสิ่งที่เอ็นจินการเตรียมการกำลังทำกับแบ็กเอนด์ก็แค่หลบหนีสิ่งต่างๆ ดังนั้น "ทำผิด" เพราะพวกเขาหนีความคิดเห็นที่ผู้ใช้ส่งก่อนแสดงในเบราว์เซอร์? ไม่พวกมันป้องกัน XSS การไม่สนใจเลยทำผิดไป
คู่ปรับ Shot

@ParthianShot หากเอ็นจินของคำสั่งที่เตรียมไว้ไม่ได้ทำให้ข้อมูลหลุดออกจากรหัสอย่างสมบูรณ์คนที่เขียนมันควรจะถูกยิง ใช่ฉันรู้ว่ามีการใช้โพรโทคอล wire ของ MySQL ในลักษณะนั้น คำสั่งของฉันยืนอยู่
Charles Duffy

@CharlesDuffy และจุดของฉัน - ที่บางครั้งตัวเลือกของคุณคือการทำให้บางอย่างทำงานอย่างปลอดภัยโดยใช้ toolchain ที่จะทำให้ประจบประแจงพิถีพิถันหรือจมแปดครั้งเวลาและความพยายามในการทำให้มันสวย - ยังคงยืน
คู่ปรับ Shot

คำตอบ:


282

มีสองกฎง่ายและปลอดภัยซึ่งทำงานไม่เพียง แต่ในมีแต่ยังshbash

1. ใส่สตริงทั้งหมดในเครื่องหมายคำพูดเดี่ยว

สิ่งนี้ใช้ได้กับทุกตัวอักษรยกเว้นการอ้างถึงเพียงคำเดียว หากต้องการหลีกเลี่ยงอัญประกาศเดี่ยวให้ปิดข้อความที่อยู่ข้างหน้าใส่เครื่องหมายคำพูดเดี่ยวแล้วเปิดข้อความใหม่อีกครั้ง

'I'\''m a s@fe $tring which ends in newline
'

คำสั่ง sed: sed -e "s/'/'\\\\''/g; 1s/^/'/; \$s/\$/'/"

2. หลบหนีถ่านทุกตัวด้วยแบ็กสแลช

ใช้ได้กับทุกตัวละครยกเว้นขึ้นบรรทัดใหม่ สำหรับอักขระขึ้นบรรทัดใหม่ให้ใช้เครื่องหมายคำพูดเดี่ยวหรือคู่ จะต้องจัดการสตริงที่ว่างเปล่า - แทนที่ด้วย""

\I\'\m\ \a\ \s\@\f\e\ \$\t\r\i\n\g\ \w\h\i\c\h\ \e\n\d\s\ \i\n\ \n\e\w\l\i\n\e"
"

คำสั่ง sed -e 's/./\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/'sed:

2b เวอร์ชันที่อ่านง่ายขึ้นของ 2

มีชุดอักขระที่ปลอดภัยง่าย ๆ เช่น[a-zA-Z0-9,._+:@%/-]ที่สามารถไม่ใช้ Escape เพื่อให้สามารถอ่านได้มากขึ้น

I\'m\ a\ s@fe\ \$tring\ which\ ends\ in\ newline"
"

คำสั่ง LC_ALL=C sed -e 's/[^a-zA-Z0-9,._+@%/-]/\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/'sed:


โปรดทราบว่าในโปรแกรม sed หนึ่งไม่สามารถทราบได้ว่าบรรทัดสุดท้ายของการป้อนข้อมูลลงท้ายด้วยไบต์ขึ้นบรรทัดใหม่ (ยกเว้นเมื่อมันว่างเปล่า) นั่นเป็นเหตุผลที่คำสั่ง sed ทั้งสองข้างถือว่ามันไม่ได้ คุณสามารถเพิ่มบรรทัดใหม่ที่เสนอราคาด้วยตนเอง

โปรดสังเกตว่าตัวแปรเชลล์ถูกกำหนดไว้สำหรับข้อความใน POSIX Sense เท่านั้น ไม่ได้กำหนดการประมวลผลข้อมูลไบนารี สำหรับการนำไปปฏิบัติที่สำคัญไบนารีจะทำงานด้วยข้อยกเว้นของ NUL ไบต์ (เนื่องจากตัวแปรถูกนำไปใช้กับสตริง C และตั้งใจจะใช้เป็นสตริง C คืออาร์กิวเมนต์ของโปรแกรม) แต่คุณควรสลับไปที่โลแคล "ไบนารี" เช่น latin1 .


(คุณสามารถตรวจสอบกฎได้โดยง่ายโดยอ่านข้อมูลจำเพาะ POSIX shสำหรับทุบตีตรวจสอบคู่มืออ้างอิงที่เชื่อมโยงโดย @AustinPhillips)


หมายเหตุ: การเปลี่ยนแปลงที่ดีใน # 1 สามารถเห็นผึ้งที่นี่: github.com/scop/bash-completion/blob/... มันไม่จำเป็นต้องทำงานแต่ไม่จำเป็นต้องมีsed bash
jwd

4
หมายเหตุสำหรับคนอื่น ๆ (เช่นฉัน!) ผู้ที่ดิ้นรนเพื่อให้การทำงานเหล่านี้ .... ดูเหมือนว่ารสชาติของ sed ที่คุณได้รับบน OSX ไม่ได้รันคำสั่ง sed เหล่านี้อย่างถูกต้อง พวกเขาทำงานได้ดีบน Linux แม้ว่า!
dalelane

@dalelane: ไม่สามารถทดสอบได้ที่นี่ โปรดแก้ไขเมื่อคุณมีรุ่นที่ใช้ได้ทั้งสองอย่าง
Jo So

ดูเหมือนว่าคุณพลาดไปแล้วสตริงควรเริ่มต้นด้วย '-' (ลบ) หรือใช้กับชื่อไฟล์เท่านั้น - ในกรณีหลังจำเป็นต้องมี './' ด้านหน้า
slashmais

ฉันไม่แน่ใจว่าคุณหมายถึงอะไร ด้วยคำสั่ง sed เหล่านั้นสตริงอินพุตจะถูกนำมาจาก stdin
โจดังนั้น

59

รูปแบบที่สามารถนำกลับมาใช้ใหม่เป็นอินพุตของเชลล์

มีคำสั่งรูปแบบพิเศษ printf ( %q) ที่สร้างขึ้นสำหรับคำขอประเภทนี้:

รูปแบบ printf [-v var] [อาร์กิวเมนต์]

 %q     causes printf to output the corresponding argument
        in a format that can be reused as shell input.

ตัวอย่างบางส่วน:

read foo
Hello world
printf "%q\n" "$foo"
Hello\ world

printf "%q\n" $'Hello world!\n'
$'Hello world!\n'

สามารถใช้ผ่านตัวแปรได้เช่นกัน:

printf -v var "%q" "$foo
"
echo "$var"
$'Hello world\n'

ตรวจสอบอย่างรวดเร็วด้วยทั้งหมด (128) ascii ไบต์:

โปรดทราบว่าต้องหลีกเลี่ยงไบต์ทั้งหมดจาก 128 ถึง 255

for i in {0..127} ;do
    printf -v var \\%o $i
    printf -v var $var
    printf -v res "%q" "$var"
    esc=E
    [ "$var" = "$res" ] && esc=-
    printf "%02X %s %-7s\n" $i $esc "$res"
done |
    column

สิ่งนี้ต้องแสดงผลดังนี้:

00 E ''         1A E $'\032'    34 - 4          4E - N          68 - h      
01 E $'\001'    1B E $'\E'      35 - 5          4F - O          69 - i      
02 E $'\002'    1C E $'\034'    36 - 6          50 - P          6A - j      
03 E $'\003'    1D E $'\035'    37 - 7          51 - Q          6B - k      
04 E $'\004'    1E E $'\036'    38 - 8          52 - R          6C - l      
05 E $'\005'    1F E $'\037'    39 - 9          53 - S          6D - m      
06 E $'\006'    20 E \          3A - :          54 - T          6E - n      
07 E $'\a'      21 E \!         3B E \;         55 - U          6F - o      
08 E $'\b'      22 E \"         3C E \<         56 - V          70 - p      
09 E $'\t'      23 E \#         3D - =          57 - W          71 - q      
0A E $'\n'      24 E \$         3E E \>         58 - X          72 - r      
0B E $'\v'      25 - %          3F E \?         59 - Y          73 - s      
0C E $'\f'      26 E \&         40 - @          5A - Z          74 - t      
0D E $'\r'      27 E \'         41 - A          5B E \[         75 - u      
0E E $'\016'    28 E \(         42 - B          5C E \\         76 - v      
0F E $'\017'    29 E \)         43 - C          5D E \]         77 - w      
10 E $'\020'    2A E \*         44 - D          5E E \^         78 - x      
11 E $'\021'    2B - +          45 - E          5F - _          79 - y      
12 E $'\022'    2C E \,         46 - F          60 E \`         7A - z      
13 E $'\023'    2D - -          47 - G          61 - a          7B E \{     
14 E $'\024'    2E - .          48 - H          62 - b          7C E \|     
15 E $'\025'    2F - /          49 - I          63 - c          7D E \}     
16 E $'\026'    30 - 0          4A - J          64 - d          7E E \~     
17 E $'\027'    31 - 1          4B - K          65 - e          7F E $'\177'
18 E $'\030'    32 - 2          4C - L          66 - f      
19 E $'\031'    33 - 3          4D - M          67 - g      

โดยที่ฟิลด์แรกคือค่าเลขฐานสิบหกของไบต์ตัวที่สองจะประกอบด้วยEหากจำเป็นต้องใช้อักขระและช่องที่สามแสดงการแสดงอักขระที่หลบหนี

ทำไม,?

คุณจะได้เห็นตัวละครบางตัวที่ไม่ได้มักจะต้องมีการหลบหนีเช่น,, และ}{

ดังนั้นไม่เสมอไปแต่บางครั้ง :

echo test 1, 2, 3 and 4,5.
test 1, 2, 3 and 4,5.

หรือ

echo test { 1, 2, 3 }
test { 1, 2, 3 }

แต่การดูแล:

echo test{1,2,3}
test1 test2 test3

echo test\ {1,2,3}
test 1 test 2 test 3

echo test\ {\ 1,\ 2,\ 3\ }
test  1 test  2 test  3

echo test\ {\ 1\,\ 2,\ 3\ }
test  1, 2 test  3 

นี่เป็นปัญหาที่การเรียก pritnf ผ่าน bash / sh สตริงนั้นจะต้องเป็นเชลล์ที่หลบหนีสำหรับ bash / sh
ThorSummoner

1
@ThorSummoner ไม่ใช่ถ้าคุณส่งสตริงเป็นอาร์กิวเมนต์ตามตัวอักษรไปยังเชลล์จากภาษาอื่น (ซึ่งคุณคงทราบวิธีการอ้างอิงแล้ว) ในหลาม: จะทำให้คุณเป็นรุ่นที่ถูกต้องเปลือกยกของsubprocess.Popen(['bash', '-c', 'printf "%q\0" "$@"', '_', arbitrary_string], stdin=subprocess.PIPE, stdout=subprocess.PIPE).communicate() arbitrary_string
Charles Duffy

1
FYI ทุบตี%qถูกทำลายเป็นเวลานาน - หากใจของฉันรับใช้ฉันได้ดีข้อผิดพลาดได้รับการแก้ไข (แต่อาจยังถูกทำลาย) ในปี 2013 หลังจากถูกทำลายเป็นเวลา 10 ปี ดังนั้นอย่าพึ่งพามัน
โจดังนั้น

@CharlesDuffy แน่นอนเมื่อคุณอยู่ใน Python land shlex.quote()(> = 3.3, pipes.quote()- ที่ไม่มีเอกสาร - สำหรับเวอร์ชันเก่า) จะทำงานและสร้างเวอร์ชั่นที่มนุษย์อ่านได้มากขึ้น (เพิ่มคำพูดและการหลบหนีตามความจำเป็น) ของสตริงส่วนใหญ่ โดยไม่จำเป็นต้องวางไข่เปลือกหอย
Thomas Perl

1
,ขอขอบคุณที่เพิ่มบันทึกพิเศษเกี่ยวกับ ฉันประหลาดใจที่รู้ว่า Bash ในตัวprintf -- %q ','ให้\,แต่/usr/bin/printf -- %q ','ให้,(ไม่รอด) เหมือนกันสำหรับตัวอักษรอื่น ๆ : {, |, ,} ~
kevinarpe

34

ในการบันทึกคนอื่นไม่ให้ RTFM ... เป็นbash :

ล้อมรอบตัวอักษรในคำพูดสองรักษามูลค่าที่แท้จริงของตัวละครทุกตัวที่อยู่ในคำพูดที่มีข้อยกเว้นของ$, `, และเมื่อการขยายตัวประวัติถูกเปิดใช้งาน\!

... ดังนั้นหากคุณหลบหนีสิ่งเหล่านั้น (และคำพูดของตัวเองแน่นอน) คุณอาจจะไม่เป็นไร

หากคุณใช้ความระมัดระวังในการอนุรักษ์มากขึ้นเมื่อมีข้อสงสัยให้หลีกเลี่ยงวิธีนี้คุณควรหลีกเลี่ยงการใช้ตัวอักษรที่มีความหมายพิเศษแทนโดยหลีกเลี่ยงการใช้อักขระตัวระบุ (เช่นตัวอักษร ASCII ตัวเลขหรือ '_') มันไม่น่าเป็นไปได้ที่สิ่งเหล่านี้จะเคยมี (เช่นในเปลือก POSIX-ish แปลก ๆ ) มีความหมายพิเศษและจำเป็นต้องหลบหนี


1
นี่คือคู่มือที่ยกมาด้านบน: gnu.org/software/bash/manual/html_node/Double-Quotes.html
code_monk

นี่เป็นคำตอบที่สั้นหวานและถูกต้องที่สุด (+1 สำหรับสิ่งนั้น) แต่อาจจะดีกว่าถ้าใช้เครื่องหมายคำพูดเดี่ยว - ดูคำตอบที่ยาวกว่าของฉัน
โจดังนั้น

26

โดยใช้print '%q' เทคนิคเราสามารถเรียกใช้ลูปเพื่อค้นหาว่าอักขระใดเป็นพิเศษ:

#!/bin/bash
special=$'`!@#$%^&*()-_+={}|[]\\;\':",.<>?/ '
for ((i=0; i < ${#special}; i++)); do
    char="${special:i:1}"
    printf -v q_char '%q' "$char"
    if [[ "$char" != "$q_char" ]]; then
        printf 'Yes - character %s needs to be escaped\n' "$char"
    else
        printf 'No - character %s does not need to be escaped\n' "$char"
    fi
done | sort

มันให้ผลลัพธ์นี้:

No, character % does not need to be escaped
No, character + does not need to be escaped
No, character - does not need to be escaped
No, character . does not need to be escaped
No, character / does not need to be escaped
No, character : does not need to be escaped
No, character = does not need to be escaped
No, character @ does not need to be escaped
No, character _ does not need to be escaped
Yes, character   needs to be escaped
Yes, character ! needs to be escaped
Yes, character " needs to be escaped
Yes, character # needs to be escaped
Yes, character $ needs to be escaped
Yes, character & needs to be escaped
Yes, character ' needs to be escaped
Yes, character ( needs to be escaped
Yes, character ) needs to be escaped
Yes, character * needs to be escaped
Yes, character , needs to be escaped
Yes, character ; needs to be escaped
Yes, character < needs to be escaped
Yes, character > needs to be escaped
Yes, character ? needs to be escaped
Yes, character [ needs to be escaped
Yes, character \ needs to be escaped
Yes, character ] needs to be escaped
Yes, character ^ needs to be escaped
Yes, character ` needs to be escaped
Yes, character { needs to be escaped
Yes, character | needs to be escaped
Yes, character } needs to be escaped

ผลลัพธ์บางอย่างเช่น,ดูน่าสงสัยเล็กน้อย น่าสนใจที่จะรับ @ CharlesDuffy อินพุตนี้


2
คุณอาจอ่านคำตอบเพื่อ,ดูข้อสงสัยเล็กน้อยในย่อหน้าสุดท้ายของคำตอบของฉัน
F. Hauri

2
โปรดจำไว้ว่า%qไม่ทราบว่าคุณกำลังวางแผนที่จะใช้อักขระภายในเชลล์ดังนั้นมันจะหนีอักขระทั้งหมดที่สามารถมีความหมายพิเศษในบริบทเชลล์ที่เป็นไปได้ ,ตัวเธอเองไม่มีความหมายพิเศษสำหรับตัวเธอ แต่อย่างที่ @ F.Hauri ได้ชี้ให้เห็นในการตอบกลับของเขามันมีความหมายพิเศษใน{...}การขยายรั้ง: gnu.org/savannah-checkouts/gnu/bash/manual/ ......นี่มันเหมือน! ซึ่งต้องใช้การขยายในสถานการณ์เฉพาะเท่านั้นไม่ใช่โดยทั่วไป: echo Hello World!ทำงานได้ดี แต่echo test!testจะล้มเหลว
Mecki

18

อักขระที่ต้องหลบหนีจะแตกต่างกันใน Bourne หรือ POSIX เชลล์กว่า Bash โดยทั่วไป (มาก) Bash เป็นเกมซูเปอร์เซ็ตของกระสุนเหล่านั้นดังนั้นสิ่งใดก็ตามที่คุณหลบหนีเข้ามาshellควรถูกหลบหนีใน Bash

กฎทั่วไปที่ดีจะเป็น "หากมีข้อสงสัยให้หลีกเลี่ยง" \nแต่หนีออกมาตัวละครบางตัวช่วยให้พวกเขามีความหมายพิเศษเช่น เหล่านี้มีการระบุไว้ในman bashหน้าภายใต้และQuotingecho

นอกจากนั้นให้หลีกตัวละครที่ไม่ใช่ตัวอักษรและตัวเลขให้ปลอดภัย ฉันไม่รู้รายชื่อที่ชัดเจนเพียงรายการเดียว

หน้ารายชื่อพวกเขาทั้งหมดที่ไหนสักแห่ง แต่ไม่ได้อยู่ในที่เดียว เรียนรู้ภาษานั่นคือวิธีที่จะทำให้แน่ใจ

!หนึ่งที่ได้จับฉันออก นี่เป็นอักขระพิเศษ (การขยายประวัติ) ใน Bash (และ csh) แต่ไม่ใช่ใน Korn เชลล์ แม้กระทั่งecho "Hello world!"ให้ปัญหา การใช้เครื่องหมายคำพูดเดี่ยวตามปกติจะลบความหมายพิเศษออก


1
ฉันชอบกฎทั่วไปที่ดีเป็นพิเศษคือคำแนะนำ"หากมีข้อสงสัยให้หลีกเลี่ยง" ยังคงมีข้อสงสัยว่าการตรวจสอบด้วยsedนั้นดีพอที่จะดูหรือไม่ว่าจะต้องมีการหลบหนี ขอบคุณสำหรับคำตอบ!
fedorqui 'ดังนั้นหยุดการทำร้าย'

2
@fedorqui: sedไม่จำเป็นต้องตรวจสอบด้วยคุณสามารถตรวจสอบได้เกือบทุกอย่าง sedไม่ใช่ปัญหาbashคือ ภายในเครื่องหมายคำพูดเดี่ยวไม่มีอักขระพิเศษ (ยกเว้นเครื่องหมายคำพูดเดี่ยว) คุณจะไม่สามารถหลบหนีแม้แต่อักขระได้ sedคำสั่งมักจะควรจะอยู่ในราคาเดียวเพราะ metacharacters RE มีการทับซ้อนมากเกินไปกับ metacharacters เปลือกเพื่อความปลอดภัย ข้อยกเว้นคือการฝังตัวแปรเชลล์ซึ่งจะต้องทำอย่างระมัดระวัง
cdarke

5
echoตรวจสอบกับ หากคุณได้สิ่งที่คุณใส่ออกมาก็ไม่จำเป็นต้องหลบหนี :)
Mark Reed

6

ฉันเข้าใจว่าคุณกำลังพูดถึง bash strings มีสตริงประเภทต่างๆที่มีชุดข้อกำหนดที่แตกต่างกันสำหรับการหลบหนี เช่น. สตริงเครื่องหมายคำพูดเดี่ยวจะแตกต่างจากสตริงที่มีเครื่องหมายคำพูดคู่

การอ้างอิงที่ดีที่สุดคือส่วนการอ้างอิงของคู่มือทุบตี

มันอธิบายถึงตัวละครที่ต้องการหลบหนี โปรดทราบว่าตัวละครบางตัวอาจต้องหลบหนีขึ้นอยู่กับตัวเลือกที่เปิดใช้งานเช่นการขยายประวัติ


3
ดังนั้นจึงยืนยันว่าการหลบหนีเป็นป่าที่ไม่มีทางออกที่ง่ายจะต้องตรวจสอบแต่ละกรณี ขอบคุณ!
fedorqui 'ดังนั้นหยุดทำอันตราย'

@fedorqui เช่นเดียวกับภาษาใด ๆ มีชุดของกฎที่จะปฏิบัติตาม สำหรับการหลบหนีสตริง bash ชุดของกฎค่อนข้างเล็กตามที่อธิบายไว้ในคู่มือ สตริงที่ง่ายที่สุดในการใช้คืออัญประกาศเดี่ยวเนื่องจากไม่มีสิ่งใดต้องการหลบหนี อย่างไรก็ตามไม่มีวิธีรวมคำพูดเดียวในสตริงที่ยกมาเดี่ยว
Austin Phillips

@fedorqui มันไม่ใช่ป่า การหลบหนีค่อนข้างทำได้ ดูโพสต์ใหม่ของฉัน
โจดังนั้น

@fedorqui คุณไม่สามารถใช้เครื่องหมายคำพูดเดี่ยวในสตริงที่มีเครื่องหมายคำพูดเดี่ยว แต่คุณสามารถ "หลีกเลี่ยง" ด้วยข้อความเช่น: 'text' '' '' more text '
CR

4

ฉันสังเกตเห็นว่า bash นั้นจะหนีอักขระบางตัวโดยอัตโนมัติเมื่อใช้การเติมอัตโนมัติ

ตัวอย่างเช่นหากคุณมีไดเรกทอรีชื่อdir:Abash จะป้อนอัตโนมัติเป็นdir\:A

เมื่อใช้สิ่งนี้ฉันได้ทำการทดลองโดยใช้อักขระของตาราง ASCII และได้รับรายการต่อไปนี้:

ตัวละครที่ทุบตีหนีเมื่อกรอกข้อมูลอัตโนมัติ : (รวมช่องว่าง)

 !"$&'()*,:;<=>?@[\]^`{|}

ตัวละครที่ทุบตีไม่หนี :

#%+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

(ฉันยกเว้น/เนื่องจากไม่สามารถใช้ในชื่อไดเรกทอรี)


2
หากคุณต้องการมีรายการที่ครอบคลุมจริง ๆ ฉันขอแนะนำให้ดูว่าตัวละครตัวprintf %qไหนทำอะไรและไม่แก้ไขหากถูกส่งผ่านเป็นอาร์กิวเมนต์
ชาร์ลส์ดัฟฟี่

มีบางครั้งที่ถึงแม้จะมีสตริงอะโพสโทรฟีคุณอาจต้องการหลีกเลี่ยงตัวอักษรและตัวเลขเพื่อสร้างอักขระพิเศษ ตัวอย่างเช่น: tr '\ n' '\ t' ซึ่งแปลอักขระบรรทัดใหม่เป็นอักขระแท็บ
Dick Guertin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.