มีรหัส sh ที่ไม่ถูกต้องรหัส bash syntactically?


31

มีshรหัสใดที่ไม่ถูกต้องรหัส bash syntactically (จะไม่ barf ในไวยากรณ์)?

ฉันกำลังคิดที่จะเขียนทับshด้วยbashสำหรับคำสั่งบางอย่าง


1
ฉันเดาโดยถูกต้องฉันหมายถึงถูกต้อง syntactically ดังนั้นมันจะไม่ barf ในไวยากรณ์
Alexander Mills

2
โทเค็นแตกต่างกันอย่างไร เช่น((อยู่ในใจ
ccorn

1
สำหรับ distros บางตัว/usr/bin/shเป็นเพียง sym-link ไป/usr/bin/bash(ฉันใช้ CentOS 7.3 และเป็น) คุณควรตรวจสอบเพื่อดูว่าshเป็นbashdistro ของคุณหรือไม่
Centimane

1
ไม่กี่ปีที่ผ่านมาโครงการทั้งหมดของฉันพังเมื่อบางสิ่งบางอย่าง "อัพเกรด" ในทุบตี ผมต้องเปลี่ยนสาย shebang ทั้งหมดของฉันจากไป#!/bin/sh #!/bin/bashจากนั้นทุกอย่างทำงานได้อีกดังนั้นคุณต้องระวังให้ดี มันอาจเกิดขึ้นเมื่อพวกเขาเริ่มใช้เส้นประแทนการทุบตีเพื่อดวลจุดโทษ
Joe

1
@ โจนั่นคือสิ่งที่ตรงกันข้ามกับที่ OP ขอ - คุณมีรหัสทุบตีที่ติดฉลากผิดว่าเป็นรหัส sh แต่ไม่ใช่ OP กำลังถามว่าพวกเขาสามารถมีรหัสsh (จริง, ไม่ติดฉลาก) ที่แตกเมื่อมันทำงานด้วย bash ไม่ใช่ว่าพวกเขาสามารถมี bash code ที่แบ่งเมื่อมันทำงานด้วย sh (ซึ่งเห็นได้ชัด - ถ้าส่วนขยาย bash ไม่ได้ มีผลกระทบกับคุณลักษณะภาษาที่มีอยู่ แต่จะไม่เป็นส่วนขยาย)
Charles Duffy

คำตอบ:


49

นี่คือรหัสบางอย่างที่ทำสิ่งที่แตกต่างใน POSIX sh และ Bash:

hello &> world

ไม่ว่าจะเป็น "ไม่ถูกต้อง" สำหรับคุณฉันไม่รู้

ในทุบตีก็เปลี่ยนเส้นทางทั้งส่งออกมาตรฐานและข้อผิดพลาดมาตรฐานจากลงในแฟ้มhello worldใน POSIX shมันจะทำงานhelloในพื้นหลังจากนั้นทำการเปลี่ยนเส้นทางที่ว่างเปล่าworldเพื่อตัดทอน (เช่นจะถือว่าเป็น& >)

มีมากมายของกรณีอื่น ๆ ที่ส่วนขยายทุบตีจะทำสิ่งที่พวกเขาเมื่อทำงานภายใต้อยู่bashและจะมีผลกระทบที่แตกต่างกันใน shPOSIX ตัวอย่างเช่นการขยายรั้งเป็นอีกและมันก็ทำงานเหมือนกันภายใต้โหมด POSIX ของ Bash และไม่


ตราบที่ข้อผิดพลาดทางไวยากรณ์คงที่ไป Bash มีทั้งคำสงวน (เช่น[[และtime) ไม่ได้ระบุโดย POSIX เช่นที่[[ xเป็นรหัสเชลล์ POSIX ที่ถูกต้อง แต่ข้อผิดพลาดทางไวยากรณ์ของ Bash และประวัติของข้อบกพร่องที่เข้ากันไม่ได้ POSIXต่างๆเช่นหนึ่งจากคำถามนี้ :

x=$(cat <<'EOF'
`
EOF
)
bash: line 2: unexpected EOF while looking for matching ``'
bash: line 5: syntax error: unexpected end of file

ข้อผิดพลาดทางไวยากรณ์เท่านั้นเป็นคำจำกัดความที่ค่อนข้างอันตรายของ "ไม่ถูกต้อง" สำหรับทุกสถานการณ์ที่มีความสำคัญ แต่ก็มี


3
โปรดทราบว่าในขณะที่การขยายตัวของรั้งในปัจจุบันทำให้ bash (และ zsh, pdksh, ksh93) ไม่สอดคล้องPOSIX กำลังทำงานเพื่อเพิ่มการจัดเตรียมในข้อกำหนดเพื่อให้การขยายรั้ง (และ{fd}>fileปัญหาที่คล้ายกัน) เพื่อทุบตีสามารถสอดคล้องอีกครั้ง จะยังคงไม่ระบุ แต่สคริปต์ที่สอดคล้องจะต้องทำecho "{a,b}"ก็คือพวกเขาต้องการ{a,b}ที่จะส่งออก) ดูการสนทนาที่เริ่มต้นขึ้น
Stéphane Chazelas

2
เกี่ยวข้องกับคำถาม & คำตอบนี้: austingroupbugs.net/view.php?id=1191#c3983
Stéphane Chazelas

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

1
@ Rich: แน่นอน ฉันไม่ได้ใช้ระบบใด ๆ ที่/bin/shมีการทุบตีดังนั้นถ้าฉันไม่ได้ตระหนักถึงการทุบตีนี้อย่างจริงจังการเขียนบรรทัดคำสั่งสิ่งนี้อาจเกิดขึ้นได้ง่าย ระยะห่างในคำตอบทำให้ดูไม่น่าเป็นไปได้ แต่hello&>worldไกลน้อยกว่า
..

2
ที่จริงฉันเห็นข้อผิดพลาดเนื่องจากความ&>แตกต่างเมื่อเดือนที่แล้ว!
Gordon Davisson

16

ตัวอย่างสั้น ๆ :

time()(:)

timeใน Bash เป็นคำที่สงวนไว้และทำงานแตกต่างจากtimeโปรแกรม อาจเป็นไปได้ว่าคุณจะทำลายสคริปต์เชิงปฏิบัติบางตัวที่พยายามแยกผลลัพธ์timeจากการใช้ bash แต่ในทางเทคนิคแล้วมันไม่ใช่ข้อผิดพลาดทางไวยากรณ์ นิยามใหม่ของtimeฟังก์ชันจะหายาก แต่ทำให้เกิดข้อผิดพลาดทางไวยากรณ์ตามที่คำถามนี้ระบุ

ตัวอย่างที่สั้นกว่า:

a():

ใช้ได้ในdashแต่ไม่เป็นไปตาม POSIX


3
โดยทั่วไปแล้วคำใด ๆ ที่เป็นคำหลักที่ไม่เป็นมาตรฐานหรือคำสั่ง builtin ใน Bash จะทำให้เกิดผลเช่นเดียวกัน นอกจากนี้จะtimeมีสิ่งที่ชอบdeclare, function, และselect coprocแม้ว่าบางรายการจะถูกทำเครื่องหมายอย่างชัดเจนว่าไม่ได้ระบุในมาตรฐาน ( คำหลักและบิลด์ / ยูทิลิตี้ ) แต่ฉันไม่เห็นเช่นtimeหรือcoprocในรายการ และการใช้--posixดูเหมือนจะไม่ช่วย
ilkkachu
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.