Bagaimana saya bisa menguji kepatuhan POSIX untuk skrip shell?

72

Mempertimbangkan bahwa POSIX adalah hal yang paling dekat dengan standar umum di antara semua kesatuan, saya tertarik mengetahui apakah ada shell yang mendukungnya secara eksklusif. Sementara sebagian besar shell modern menyediakan dukungan untuk POSIX (dan akan menjalankan skrip yang sesuai dengan POSIX tanpa masalah), mereka tidak melakukan pekerjaan yang baik untuk menunjukkan fitur-fitur yang tidak sesuai.

Apakah ada shell yang mengimplementasikan POSIX dan POSIX saja, sedemikian rupa sehingga akan menimbulkan kesalahan untuk fitur yang tidak sesuai?

EDIT Saya ingin mengklarifikasi bahwa saya tidak meminta tips umum untuk menulis skrip shell portabel. Pertanyaan terkait yang disebutkan dalam komentar sudah mencakup ini. Saya memikirkan pertanyaan ini ketika saya menemukan bahwa bashada --posixpilihan tetapi hanya untuk menemukan bahwa itu hanya mempengaruhi beberapa perilaku intimisasi yang tidak persis apa yang saya cari.

rahmu
sumber
4
Terkait: Sumber daya untuk pemrograman shell portabel
Gilles 'SO- stop being evil'
@Gilles: Mungkin saya harus menyebutkan bahwa saya menemukan pertanyaan ini tetapi hanya satu jawaban yang menyarankan pengujian dash. Saya menyebutkan portabilitas sebagai konteks umum untuk pertanyaan saya, tetapi itu bukan maksud sebenarnya.
rahmu
Tentu, saya ingin kedua pertanyaan itu dikaitkan karena mereka cenderung menarik bagi orang yang sama. Mereka bukan duplikat dengan cara apa pun. Omong-omong, posh adalah tes yang lebih baik untuk kepatuhan POSIX daripada tanda hubung.
Gilles 'SO- berhenti bersikap jahat'
2
busybox cukup dekat dengan POSIX dan POSIX saja. Satu hal yang dapat membuat Anda tersandung adalah jika Anda juga menginstal paket lain (seperti diffutils) maka itu mungkin menambah fitur. Lihat livecd alpine linux yang memulai Anda dengan lingkungan busybox murni. Alpine menggunakan pustaka C musl sehingga Anda tidak mendapatkan ekstensi GNU yang dapat menambahkan fitur seperti ekspresi reguler yang diperluas.
Michael Fox

Jawaban:

37

Sayangnya, 'portable' biasanya persyaratan yang lebih kuat daripada 'POSIX-compliant' untuk skrip shell. Yaitu, menulis sesuatu yang berjalan pada shell POSIX tidak terlalu sulit, tetapi membuatnya berjalan pada shell dunia nyata lebih sulit.

Anda dapat mulai dengan memasang setiap shell di manajer paket Anda, khususnya debian yang poshterdengar seperti yang Anda inginkan (Shell Biasa yang Sesuai Kebijakan). Kebijakan Debian adalah POSIX dengan beberapa pengecualian ( echo -nditentukan, local...).

Selain itu, pengujian harus mencakup beberapa shell (/ bin / sh khususnya) pada berbagai platform. Saya menguji pada Solaris (/ bin / sh dan xpg4 / sh), dan BSD. AIX dan HP-UX sangat patuh dan tidak menyebabkan masalah. bash adalah dunianya sendiri.

Saya akan merekomendasikan panduan Autoconf untuk shell portabel , yang benar-benar brilian dan menghemat banyak waktu. Potongan besar itu sudah usang, tapi tidak apa-apa; lewati saja TruUnix dan Ultrix dan seterusnya jika Anda tidak peduli!

Nicholas Wilson
sumber
poshmemang terdengar seperti apa yang saya minta. Saya akan melakukan beberapa tes secepat mungkin.
rahmu
1
Saya menjawab sebelum menemukan pertanyaan terkait! mewah adalah hal yang debian, jadi tidak akan dikemas pada setiap sistem. Juga, shell tidak selalu menjadi hal yang paling dikhawatirkan; ketidakcocokan sed adalah masalah besar, misalnya.
Nicholas Wilson
Saya tidak akan repot porting ke Solaris / bin / sh alias Bourne shell (yang bukan POSIX). Solaris seperti semua persatuan modern memiliki cangkang POSIX, hanya saja kebetulan tidak berada di lokasi yang biasa (/ usr / xpg4 / bin / sh)
Stéphane Chazelas
Sayangnya, kami mengirimkan skrip yang harus dijalankan setidaknya setiap / bin / sh. Ini tidak seburuk semua itu ... Aku lebih suka tidak harus melakukannya.
Nicholas Wilson
2
Alasan saya memperlakukan / bin / sh sama pentingnya adalah karena itu dipanggil dari shebang dalam begitu banyak skrip. "/ usr / bin / env sh" bukan merupakan peningkatan. Jika Anda akan berusaha membuat sesuatu bekerja pada cangkang non-POSIX, saya rasa saya mungkin juga memprioritaskan setiap sistem / bin / sh. Tidak akan lama sebelum beberapa pelanggan menjalankan skrip Anda dengan shell default, yang tidak masuk akal.
Nicholas Wilson
28

Anda dapat menggunakan ShellCheck (GitHub) sebagai linter untuk skrip shell Anda. Ada juga versi online .

Untuk mendeteksi masalah kompatibilitas POSIX (mis. SC2039 ), baris shebang dari skrip shell Anda seharusnya #!/bin/sh. Anda juga bisa lewat --shell=shke shellcheck.

Contoh ( test.sh):

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

Hasil ( 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.
JohnLate
sumber
1
Bertahun-tahun dan saya tidak pernah mendengar tentang ShellCheck ... terima kasih untuk tautannya!
Ton van den Heuvel
Alat terbaik yang pernah ada! Apalagi memiliki versi daring itu luar biasa dengan cepat memeriksa sepotong kode!
Mecki
12

Bash akan berjalan dalam mode yang sesuai dengan POSIX jika POSIXLY_CORRECTvariabel lingkungan diatur. Dari halaman manual:

   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.

Banyak utilitas GNU lain juga akan dihormati POSIXLY_CORRECT, jadi jika Anda menggunakan sistem dengan alat-alat GNU yang dominan (misalnya kebanyakan sistem Linux), ini adalah awal yang baik jika tujuan Anda adalah kesesuaian POSIX.

James Sneeringer
sumber
21
Bahkan dalam mode POSIX, bash masih akan mengizinkan beberapa fitur non-POSIX seperti [[.
jordanm