การขยายพารามิเตอร์ที่ทำให้เกิดสตริงว่างจะถือว่าแตกต่างกัน


10

ปรับปรุง

ใครบางคนในรายการส่งเมลบั๊กได้ยืนยันแล้วว่านี่เป็นข้อผิดพลาด


หากใครที่สนใจการแก้ไขมีอยู่ในรุ่นล่าสุดมอบให้สาขา devel


ในขณะที่

bash -c 'echo "${1##*""}"' _ bar

พิมพ์บรรทัดว่าง

bash -c 'echo "${1##*"${1##*}"}"' _ bar

barพิมพ์

ฉันไม่เข้าใจสิ่งนี้ ${1##*}ขยายเป็นสตริงว่างดังนั้น"${1##*}"ควรได้รับการปฏิบัติเช่นเดียวกับที่เป็น""อยู่ แต่ดูเหมือนว่าทุบตีจะไม่คิดเช่นนั้น

ดูเหมือนจะมีฉันทามติเกี่ยวกับเรื่องนี้ในshการใช้งานที่นิยมอื่น ๆ:

$ sh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ash -c 'echo "${1##*"${1##*}"}"' _ bar

$ dash -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh93 -c 'echo "${1##*"${1##*}"}"' _ bar

$ mksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ posh -c 'echo "${1##*"${1##*}"}"' _ bar

$ yash -c 'echo "${1##*"${1##*}"}"' _ bar

$ zsh -c 'echo "${1##*"${1##*}"}"' _ bar

$

ทุบตี (มีหรือไม่มี--posix) เป็นเพียงคนเดียวที่ไม่สอดคล้องกับที่:

$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar

และหากไม่มีการประมวลผลของสตริงย่อยพฤติกรรมจะเป็นไปตามที่คาดไว้:

$ bash -c 'echo "${1##*"${1+}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar ''

$ 

ฉันสงสัยจริงๆว่ามีคำอธิบายสำหรับเรื่องนี้หรือไม่ซึ่งฉันไม่พบในคู่มือ นี่เป็นข้อบกพร่องหรือการตีความมาตรฐานผิดหรือเปล่า? พฤติกรรมนี้มีการบันทึกไว้ที่อื่นหรือไม่?


PS: ฉันรู้วิธีแก้ปัญหาอย่างรวดเร็วคือการเลิก PE ภายใน แต่ไม่ตอบคำถามของฉันและอาจนำไปสู่ผลลัพธ์ที่ไม่พึงประสงค์ด้วยสตริงที่มีอักขระพิเศษ


GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)พิมพ์สตริงว่าง
William Pursell

GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)พิมพ์ "bar"
William Pursell

@William ทดสอบเมื่อ 4.4.20 และ 5.0.11 และทั้งคู่พิมพ์ "bar"
oguz ismail

ดูเหมือนว่าจะมีปัญหากับการขยายตัวโดยทั่วไป ในของฉัน4.4.12(3)-release, ->echo "${BASH##*"${BASH##*}"}" /bin/bashในขณะที่echo "\${BASH##*"${BASH##*}"}"-> ${BASH##*}และeval echo "\${BASH##*"${BASH##*}"}"-> ว่างเปล่า
Jeff Y

คำตอบ:


2

นี่ไม่ใช่คำตอบ

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

$ bash -c 'echo "${1##*${1%%bar}}"' _ foobar        # case 1
bar
$ bash -c 'echo "${1##*${1%%foobar}}"' _ foobar     # case 2

$ bash -c 'echo "${1##*"${1%%bar}"}"' _ foobar      # case 3
bar
$ bash -c 'echo "${1##*"${1%%foobar}"}"' _ foobar   # case 4
foobar

กรณีที่ 1 และกรณีที่ 3 ต่างกันในเครื่องหมายคำพูด แต่การขยายตัวพารามิเตอร์ของรูปแบบ${parameter##word}กฎการใช้งานขยายตัวชื่อพา ธ wordที่จะดำเนินการ ดังนั้น*fooและ*"foo"มีพฤติกรรมเหมือนกันคำพูดคู่ในการขยายตัวชื่อพา ธ สามารถปฏิเสธจนกว่าพวกเขาจะโอบกอดตัวอักษรรูปแบบพิเศษ ( *, ?, ... ) นี่คือตัวอย่างในตัวอย่างต่อไปนี้:

$ bash -c 'echo "${1##*${2%%b*r}}"' _ 'foobar' 'f*ob*r'
bar
$ bash -c 'echo "${1##*"${2%%b*r}"}"' _ 'foobar' 'f*ob*r'
foobar

ดังนั้นถ้าเป็นกรณีนี้เหตุใดเคส 2 และเคส 4 ควรทำงานแตกต่างกันอย่างไร


เหตุใดเคส 2 และเคส 4 ควรทำงานแตกต่างกันอย่างไร ไม่มีเหตุผลทั้งสอง${1+}และ${1+""}ขยายเป็นสตริงว่างเปล่า แต่ไม่ได้รับการปฏิบัติในลักษณะที่${1##*}เป็น (ดูการแก้ไขล่าสุดของฉัน) ดังนั้นเราสามารถอนุมานได้ว่านี่เป็นข้อผิดพลาดใช่ไหม
oguz ismail

1
@oguzismail แน่นอน! หากกรณีที่ 1 และกรณีที่ 3 มีพฤติกรรมเหมือนกันดังนั้นในกรณีที่ 2 และกรณีที่ 4 ก็ควรทำตัวเหมือนกัน
kvantour
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.