Làm cách nào tôi có thể kiểm tra sự tuân thủ POSIX của tập lệnh shell?


72

Xem xét rằng POSIX là thứ gần nhất với một tiêu chuẩn chung trong tất cả các đơn vị, tôi muốn biết liệu có vỏ nào hỗ trợ riêng nó hay không. Mặc dù hầu hết các trình bao hiện đại đều cung cấp hỗ trợ cho POSIX (và sẽ chạy các tập lệnh tuân thủ POSIX mà không gặp vấn đề gì), chúng không làm tốt việc chỉ ra các tính năng không tuân thủ.

Có vỏ nào chỉ thực hiện POSIX và POSIX, theo cách mà nó sẽ gây ra lỗi cho bất kỳ tính năng không tuân thủ nào không?

EDIT Tôi muốn làm rõ rằng tôi không yêu cầu các mẹo chung để viết các kịch bản shell di động. Các câu hỏi liên quan được đề cập trong các ý kiến ​​đã bao gồm điều này. Tôi đã nghĩ đến câu hỏi này khi tôi phát hiện ra rằng bashcó một --posixlựa chọn nhưng chỉ để khám phá ra rằng nó chỉ ảnh hưởng đến một số hành vi thâm nhập không chính xác những gì tôi đang tìm kiếm.



@Gilles: Có lẽ tôi nên đề cập rằng tôi đã bắt gặp câu hỏi này nhưng chỉ có một câu trả lời gợi ý thử nghiệm với dash. Tôi đã đề cập đến tính di động như một bối cảnh chung cho câu hỏi của tôi nhưng đó không phải là mục đích thực sự của nó.
rahmu

Chắc chắn, tôi muốn hai câu hỏi được liên kết bởi vì chúng có thể được quan tâm đến cùng một người. Chúng không trùng lặp bằng bất kỳ phương tiện nào. Nhân tiện, posh là một thử nghiệm tốt hơn cho việc tuân thủ POSIX so với dấu gạch ngang.
Gilles

2
busybox chỉ khá gần với POSIX và POSIX. Một điều có thể khiến bạn gặp khó khăn là nếu bạn cũng cài đặt các gói khác (như diffutils) thì nó có thể thêm các tính năng. Kiểm tra livecd của linux alpine giúp bạn bắt đầu với một môi trường busybox thuần túy. Alpine sử dụng thư viện musl C để bạn không nhận được các phần mở rộng GNU có thể thêm các tính năng như các biểu thức thông thường mở rộng.
Michael Fox

Câu trả lời:


37

Thật không may, 'xách tay' thường là một yêu cầu mạnh mẽ hơn 'tuân thủ POSIX' đối với các tập lệnh shell. Đó là, viết một cái gì đó chạy trên bất kỳ vỏ POSIX nào không quá khó, nhưng để nó chạy trên bất kỳ vỏ thế giới thực nào thì khó hơn.

Bạn có thể bắt đầu bằng cách cài đặt mọi shell trong trình quản lý gói của mình, đặc biệt là poshâm thanh của debian giống như những gì bạn muốn (SHD Ordinary tuân thủ chính sách). Chính sách của Debian là POSIX với một vài ngoại lệ ( echo -nđược chỉ định, local...).

Ngoài ra, thử nghiệm phải bao gồm một số shell (/ bin / sh đặc biệt) trên một loạt các nền tảng. Tôi thử nghiệm trên Solaris (/ bin / sh và xpg4 / sh) và BSD. AIX và HP-UX rất tuân thủ và không gây ra sự cố. bash là một thế giới nhỏ của riêng mình.

Tôi muốn giới thiệu hướng dẫn Autoconf cho shell di động , nó hoàn toàn tuyệt vời và tiết kiệm rất nhiều thời gian. Khối lớn của nó đã lỗi thời, nhưng không sao; chỉ cần bỏ qua TruUnix và Ultrix và cứ thế nếu bạn không quan tâm!


poshthực sự nghe giống như những gì tôi yêu cầu. Tôi sẽ làm một số xét nghiệm ngay khi tôi có thể.
rahmu

1
Tôi đã trả lời trước khi phát hiện ra câu hỏi liên quan! posh là một thứ debian, vì vậy sẽ không được đóng gói trên mọi hệ thống. Ngoài ra, vỏ không nhất thiết phải là điều đáng lo ngại nhất; không tương thích sed là một vấn đề lớn, ví dụ.
Nicholas Wilson

Tôi sẽ không bận tâm đến việc chuyển sang Solaris / bin / sh aka Bourne shell (không phải là POSIX). Solaris giống như tất cả các đơn vị hiện đại có vỏ POSIX, nó chỉ xảy ra ở vị trí thông thường (/ usr / xpg4 / bin / sh)
Stéphane Chazelas

Đáng buồn thay, chúng tôi gửi các tập lệnh phải chạy trên ít nhất mỗi / bin / sh. Nó không tệ như tất cả những điều đó ... Tôi thà không phải làm điều đó.
Nicholas Wilson

2
Lý do tôi coi / bin / sh là quan trọng là vì nó được gọi từ shebang trong rất nhiều tập lệnh. "/ Usr / bin / env sh" hầu như không phải là một sự cải tiến. Nếu bạn sẽ nỗ lực để làm cho một cái gì đó hoạt động trên các vỏ không phải POSIX, tôi cảm thấy tôi cũng có thể ưu tiên mỗi / bin / sh của mỗi hệ thống. Sẽ không lâu nữa trước khi một số khách hàng chạy tập lệnh của bạn với trình bao mặc định, điều này không hợp lý lắm.
Nicholas Wilson

28

Bạn có thể sử dụng ShellCheck (GitHub) như một kẻ nói dối cho các kịch bản shell của bạn. Ngoài ra còn có một phiên bản trực tuyến .

Để phát hiện các sự cố tương thích POSIX (ví dụ SC2039 ), dòng shebang của tập lệnh shell của bạn phải là #!/bin/sh. Bạn cũng có thể vượt qua --shell=shđể shellcheck.

Ví dụ ( test.sh):

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

Kết quả ( 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
Tất cả những năm này và tôi chưa bao giờ nghe nói về ShellCheck ... cảm ơn vì liên kết!
Ton van den Heuvel

Công cụ tốt nhất! Đặc biệt là có một phiên bản trực tuyến của nó là tuyệt vời để nhanh chóng kiểm tra một đoạn mã!
Mecki

12

Bash sẽ chạy trong chế độ tuân thủ POSIX nếu POSIXLY_CORRECTbiến môi trường được đặt. Từ trang hướng dẫn:

   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.

Nhiều tiện ích GNU khác cũng sẽ tôn vinh POSIXLY_CORRECT, vì vậy nếu bạn đang sử dụng hệ thống với các công cụ GNU chủ yếu (ví dụ: hầu hết các hệ thống Linux), đây là một khởi đầu tốt nếu mục tiêu của bạn là tuân thủ POSIX.


21
Ngay cả trong chế độ POSIX, bash vẫn sẽ cho phép một số tính năng không phải POSIX như [[.
jordanm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.