Zasoby do programowania przenośnych powłok


65

Jakie zasoby istnieją dla przenośnego programowania powłoki? Ostateczną odpowiedzią jest przetestowanie na wszystkich docelowych platformach, ale rzadko jest to praktyczne.

Specyfikacja POSIX / Single UNIX jest początkiem, ale nie mówi ani Tobie, jaki jest poziom wsparcia dla każdej implementacji, ani jakie są wspólne rozszerzenia. Możesz przeczytać dokumentację każdej implementacji, ale jest to bardzo czasochłonne i nie do końca dokładne.

Wydaje mi się, że idealnym formatem byłaby jakaś wersja specyfikacji POSIX z komentarzem społecznościowym, w której każda cecha jest opatrzona adnotacją poziomu wsparcia wśród różnych implementacji. Czy jest coś takiego? Czy są też inne przydatne zasoby?

Na przykład istnieją strony przenośności powłoki Svena Maschecka , ale chodzi tylko o elementy składniowe i kilka wbudowanych i obejmuje tylko stare powłoki. Szukam bardziej wszechstronnego zasobu.


2
Uwaga: Proszę nie odpowiadać tutaj, aby przytoczyć tylko jeden dokument zgodności z konkretnym wdrożeniem. Jeśli masz jedną z nich, odpowiednie tag wiki byłoby dobrym miejscem.
Gilles

1
Ktoś musi wydobyć historię zmian dla autoconfi Metaconfig(Perl rn) i zebrać wszystkie sztuczki i ich objaśniające komentarze w jednym miejscu.
geekozaur

@geekosaur: Dobra sugestia. Nigdy nie patrzyłem na wewnętrzne funkcje autoconf, czy jest coś, co można wykorzystać jako przewodnik podczas pisania własnych skryptów? Jeśli tak, to byłaby to dobra odpowiedź na moje pytanie, nawet jeśli nie jest to ostateczne.
Gilles

5
Jestem pewien, że oboje mogliście go łatwo znaleźć, ale dla dobra innych osób śledzących ten wątek, oto link do odpowiedniej strony z podręcznika autoconf: gnu.org/software/hello/manual/autoconf/Portable- Shell.html
J. Taylor

Odpowiedzi:


32

Podręcznik autoconf zawiera sekcję dotyczącą programowania przenośnych powłok .

Chociaż nie jest to specjalnie ukierunkowane na POSIX, jest to prawdopodobnie najbardziej kompletna kolekcja tego, co należy robić, a czego nie robić podczas próby napisania przenośnego kodu powłoki.


3
Jest to jeden z najlepszych zasobów, który został zbudowany podczas pisania kodu w M4, który musiał wytworzyć kod powłoki, który byłby przenośny na jak największej liczbie powłok.
Tim Post

6

Oprócz dashi poshistnieje bournesh(lub bsh) Heirloom Bourne Shell , którego można używać do wykrywania Bashism .

Projekt Heirloom zawiera także „Heirloom Toolchest”, zbiór ponad 100 standardowych narzędzi uniksowych (który może służyć jako punkt wyjścia do porównywania opcji wiersza poleceń).


2
Zauważ, że powłoka Bourne'a nie jest powłoką POSIX, więc uczynienie skryptu przenośnym do powłoki Bourne'a oznaczałoby obniżenie składni skryptu ze standardowego języka sh POSIX do wspólnego mianownika między tą składnią a składnią powłoki Bourne. Nie warte opinii, chyba że chcesz być przenośny na starożytne systemy (lub Solaris 10 i wcześniejsze i nie masz wyboru, aby użyć standardowego sh, który był w / usr / xpg4 / bin).
Stéphane Chazelas

5

Podobnie do tej odpowiedzi , spróbuj wykonać swój skrypt w sposób elegancki .

Nie zapomnij również ustawić POSIXLY_CORRECTzmiennej środowiskowej na true, ponieważ powoduje to, że wiele programów (nie tylko powłoka) przestrzega bardziej rygorystycznie standardów POSIX.


4

Pisanie skryptów za pomocą myślnika może być początkiem.


3
Testowanie za pomocą dash jest absolutnym minimum, aby uniknąć przypadkowego polegania na funkcjach ksh / bash, ale jestem o wiele więcej: wiedząc o brakach w innych powłokach (np. Słaba obsługa pułapek zsh), a przede wszystkim w narzędziach powłoki (np. findWciąż OpenBSD nie zaimplementowano -exec +).
Gilles

FWIW, OpenBSD findrobi to -exec utility {} +obecnie.
Kusalananda

2

W pewnym stopniu możesz spróbować checkbashismsw devscriptspakiecie Debian / Ubuntu .

Nie jest idealny, ale ma tę zaletę, że jest punktem wyjścia. Na przykład, nie widzi klasycznych błędów z sed/ finddotyczących GNU vs. BSD / innych różnic.

Domyślnie jest zorientowany na Debian + myślnik, -pflaga może być przydatna w twoim przypadku.


2

Dzisiaj zwykle można znaleźć powłokę POSIX w systemie, co ogólnie oznacza, że ​​możesz pisać w języku POSIX (moduł działa z błędami zgodności).

Jedynym problemem jest to, że /bin/shczasami nie jest powłoką POSIX. I musisz na stałe zakodować #!wiersz w skryptach, które mają zachowywać się jak ładne pliki wykonywalne; nie możesz po prostu poprosić użytkownika o zbadanie problemu, a następnie wywołać skrypt jako /path/to/posix/shell myscript.

Zatem sztuczka polega na użyciu funkcji POSIX w skrypcie, ale powoduje, że skrypt automatycznie znajdzie powłokę POSIX. Jednym ze sposobów na to jest:

#!/bin/sh

# At this point, we may be running under some old shell
# we have to tread carefully.

# note how we use test rather than [ ] syntax and avoid
# depending on test with no argument producing a failure;
# i.e. "test $posix_shell".

if ! test x$posix_shell = x ; then
  # the three possible shell paths are just an example;
  # please extend as necessary.

  for shell in /usr/xpg4/bin/sh /bin/bash /usr/bin/bash ; do
    if test -x $shell ; then
       posix_shell=$shell
    fi
  done
  if test x$posix_shell = x ; then
    echo "no POSIX shell found"
    exit 1
    # or we could avoid bailing here and just fall back on /bin/sh:
    # echo "falling back on /bin/sh: cross your fingers that it works"
    # posix_shell=/bin/sh
  fi
  export posix_shell

  # plain "$@" is broken in ancient shells! 
  # I seem to recall ${@+"$@"}: not sure if that's the right trick.

  exec $posix_shell $0 ${@+"$@"}  # can we count on exec in legacy shells? 
fi

# phew, at this point in the script we have been re-executed and are
# being interpreted by some reasonably modern shell. We can use $(...)
# command substitution, and other features.

Istnieją inne podejścia, takie jak generowanie kodu. Zwiększ swoje skrypty za pomocą małego skryptu, który pobiera całe pliki skryptów bez znaku #! wiersz i dodaje jeden.

Najgorsze, co możesz zrobić, to zacząć pisać całe skrypty w taki sposób, aby działały na powłoce Bourne'a od 1981 roku. Jest to konieczne tylko wtedy, gdy musisz pisać dla systemu, który tak naprawdę nie ma żadnej innej powłoki .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.