ฉันจะทดสอบความสอดคล้องของ POSIX ของเชลล์สคริปต์ได้อย่างไร


72

เมื่อพิจารณาว่า POSIX เป็นสิ่งที่ใกล้เคียงกับมาตรฐานทั่วไปมากที่สุดในบรรดา unices ทั้งหมดฉันสนใจที่จะรู้ว่ามีเชลล์ที่รองรับมันโดยเฉพาะหรือไม่ ในขณะที่เชลล์ที่ทันสมัยส่วนใหญ่ให้การสนับสนุน POSIX (และจะเรียกใช้สคริปต์ที่สอดคล้องกับ POSIX โดยไม่มีปัญหาใด ๆ ) พวกมันทำงานได้ไม่ดีในการชี้ให้เห็นคุณลักษณะที่ไม่เข้ากันได้

มีเชลล์ที่ใช้ POSIX และ POSIX เท่านั้นในลักษณะที่มันจะโยนข้อผิดพลาดสำหรับคุณสมบัติที่ไม่เข้ากันได้หรือไม่?

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



@Gilles: บางทีฉันควรจะพูดถึงว่าผมไม่เจอคำถามนี้ dashแต่เพียงหนึ่งคำตอบปัญหาทดสอบกับ ฉันพูดถึงการพกพาเป็นบริบททั่วไปสำหรับคำถามของฉัน แต่นั่นไม่ใช่ความตั้งใจที่แท้จริง
rahmu

แน่นอนว่าฉันต้องการให้ทั้งสองคำถามเชื่อมโยงกันเพราะพวกเขาน่าจะเป็นที่สนใจของคนคนเดียวกัน พวกเขาไม่ได้ทำซ้ำด้วยวิธีการใด ๆ โดยวิธีการที่ดีคือการทดสอบที่ดีกว่าสำหรับการปฏิบัติตาม POSIX กว่ารีบ
Gilles

2
busyboxค่อนข้างใกล้กับ POSIX และ POSIX เท่านั้น สิ่งหนึ่งที่สามารถทำให้คุณเดินทางได้คือถ้าคุณติดตั้งแพ็คเกจอื่น ๆ (เช่น diffutils) มันอาจเพิ่มฟีเจอร์ ชำระเงินlivecd ของอัลไพน์ลินุกซ์ที่จะเริ่มต้นคุณด้วยสภาพแวดล้อมที่ไม่ว่าง อัลไพน์ใช้ไลบรารี musl C เพื่อให้คุณไม่ได้รับส่วนขยาย GNU ที่สามารถเพิ่มคุณลักษณะต่างๆเช่นนิพจน์ทั่วไปแบบขยาย
Michael Fox

คำตอบ:


37

น่าเสียดายที่ 'พกพา' มักเป็นข้อกำหนดที่แข็งแกร่งกว่า 'POSIX-compliant' สำหรับเชลล์สคริปต์ นั่นคือการเขียนสิ่งที่ทำงานบนเชลล์ POSIX ไม่ยากเกินไป แต่การทำให้มันทำงานบนเชลล์ในโลกแห่งความเป็นจริงนั้นยากกว่า

คุณสามารถเริ่มต้นด้วยการติดตั้งเชลล์ทุกตัวในแพ็คเกจผู้จัดการของคุณโดยเฉพาะเดเบียนที่poshฟังดูเหมือนว่าคุณต้องการอะไร (เชลล์แบบธรรมดาที่สอดคล้องกับนโยบาย) นโยบายของเดเบียนคือ POSIX โดยมีข้อยกเว้นเล็กน้อย ( echo -nระบุไว้, local... )

นอกเหนือจากนั้นการทดสอบจะครอบคลุมเชลล์จำนวนหนึ่ง (/ bin / sh โดยเฉพาะ) บนแพลตฟอร์มที่หลากหลาย ฉันทดสอบ Solaris (/ bin / sh และ xpg4 / sh) และ BSD AIX และ HP-UX นั้นสอดคล้องและไม่ทำให้เกิดปัญหา ทุบตีเป็นโลกเล็ก ๆ ของตัวเอง

ฉันอยากจะแนะนำAutoconf guideให้กับmobile shellซึ่งยอดเยี่ยมมากและประหยัดเวลาได้มาก ชิ้นใหญ่ของมันล้าสมัย แต่ก็ไม่เป็นไร เพียงแค่ข้าม TruUnix และ Ultrix และอื่น ๆ ถ้าคุณไม่สนใจ!


poshเสียงเหมือนสิ่งที่ฉันขอ ฉันจะทำแบบทดสอบเร็วที่สุด
rahmu

1
ฉันตอบก่อนพบคำถามที่เกี่ยวข้อง! หรูเป็นเดเบียนดังนั้นจะไม่ได้รับการบรรจุในทุกระบบ นอกจากนี้เปลือกไม่จำเป็นต้องเป็นกังวลมากที่สุด; ความเข้ากันไม่ได้ของ sed เป็นปัญหาใหญ่เช่น
นิโคลัสวิลสัน

ฉันจะไม่รบกวนการย้ายไปยังเชลล์ Bourne ของ Solaris / bin / sh (ซึ่งไม่ใช่ POSIX) Solaris เหมือนกับยูนิเซฟสมัยใหม่ทั้งหมดมี POSIX shell มันเพิ่งเกิดขึ้นไม่ได้อยู่ในตำแหน่งปกติ (/ usr / xpg4 / bin / sh)
Stéphane Chazelas

น่าเศร้าที่เราจัดส่งสคริปต์ที่ต้องทำงานอย่างน้อยทุก / bin / sh มันไม่ได้เลวร้ายอย่างที่ ... ฉันไม่อยากทำ
Nicholas Wilson

2
เหตุผลที่ฉันปฏิบัติต่อ / bin / sh สำคัญเนื่องจากมันถูกเรียกใช้จาก shebang ในสคริปต์จำนวนมาก "/ usr / bin / env sh" แทบจะไม่ได้รับการปรับปรุง หากคุณกำลังใช้ความพยายามในการทำให้บางสิ่งบางอย่างทำงานกับเชลล์ที่ไม่ใช่ POSIX ฉันรู้สึกว่าฉันอาจจัดลำดับความสำคัญ / bin / sh ของแต่ละระบบด้วย จะไม่นานก่อนที่ลูกค้าบางรายจะเรียกใช้สคริปต์ของคุณด้วยเชลล์เริ่มต้นซึ่งไม่ใช่ทั้งหมดที่ไม่สมเหตุสมผล
Nicholas Wilson

28

คุณสามารถใช้ShellCheck (GitHub)เป็น linter สำหรับเชลล์สคริปต์ของคุณ นอกจากนี้ยังมีรุ่นออนไลน์

เพื่อตรวจสอบปัญหาความเข้ากัน POSIX (เช่นSC2039 ) ที่บรรทัด shebang#!/bin/shของเชลล์สคริปต์ของคุณควรจะ นอกจากนี้คุณยังสามารถส่งผ่านไปยัง--shell=shshellcheck

ตัวอย่าง ( test.sh):

#!/bin/sh
if [[ $HOSTNAME == test ]]; then
    echo fail &> foo
fi

ผลลัพธ์ ( shellcheck test.sh):

In test.sh line 2:
if [[ $HOSTNAME == test ]]; then
   ^-- SC2039: In POSIX sh, [[ ]] is undefined.
      ^-- SC2039: In POSIX sh, HOSTNAME is undefined.    

In test.sh line 3:
    echo fail &> foo
              ^-- SC2039: In POSIX sh, &> is undefined.

1
ทุกปีเหล่านี้และฉันไม่เคยได้ยิน ShellCheck ... ขอบคุณสำหรับลิงค์!
Ton van den Heuvel

เครื่องมือที่ดีที่สุด! โดยเฉพาะอย่างยิ่งการมีเวอร์ชันออนไลน์มันยอดเยี่ยมมากที่จะตรวจสอบโค้ดอย่างรวดเร็ว!
Mecki

12

Bash จะทำงานในโหมดที่เข้ากันได้กับ POSIX หากPOSIXLY_CORRECTตั้งค่าตัวแปรสภาพแวดล้อม จาก manpage:

   POSIXLY_CORRECT
          If  this  variable  is  in the environment when bash starts, the
          shell enters posix mode before reading the startup files, as  if
          the  --posix  invocation option had been supplied.  If it is set
          while the shell is running, bash enables posix mode, as  if  the
          command set -o posix had been executed.

ยูทิลิตี้ GNU อื่น ๆ อีกมากมายจะให้เกียรติPOSIXLY_CORRECTเช่นกันดังนั้นหากคุณอยู่ในระบบที่มีเครื่องมือ GNU ส่วนใหญ่ (เช่นระบบ Linux ส่วนใหญ่) นี่เป็นการเริ่มต้นที่ดีถ้าเป้าหมายของคุณคือความสอดคล้องของ POSIX


21
แม้จะอยู่ในโหมด POSIX ทุบตียังจะช่วยให้บางคนที่ไม่ใช่ POSIX [[ให้บริการเช่น
จอร์แดน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.