Reacties
- Het gaat er echt om hoe draagbaar je wilt zijn . Alleen Unixen? Alle op Linux-kernel gebaseerde boxen? Alle systemen zelfs oude Win 3.0 en VMS (grapje)?
/bin/sh
is meestal een goed minimum, houd er rekening mee datsh
nietbash
.. . verwachten op de meeste GNU / Linux systemen. - Hoewel Android de linux-kernel gebruikt en de standaardshell is afgeleid van bash via ash, is het gebruikersland niet erg Unix-achtig en missen veel standaardtools.
Antwoord
Voor draagbaarheid kun je er gerust van uitgaan dat #!/bin/sh
zal een shell vinden die grotendeels POSIX-compatibel is op elk standaard Unix- of Linux-systeem, maar dat is het zo ongeveer.
In FreeBSD, OpenBSD en NetBSD ( samen met DragonFly, PC-BSD en enkele andere afgeleiden), bevindt bash zich op /usr/local/bin/bash
(als het is geïnstalleerd), dus de /usr/bin/env
benadering biedt overdraagbaarheid tussen Linux en BSD.
Android is geen standaard Unix- of Linux-systeem. Op mijn niet-geroote Android-telefoon, geen van /usr/bin/env
, /bin/bash
o r zelfs /bin/sh
bestaan, en de systeemshell is /system/bin/sh
.
Een shellscript dat de #!
(shebang) zal proberen uit te voeren in de shell die het op sommige systemen heeft aangeroepen, of kan een andere standaardinterpreter gebruiken (/bin/bash
bijvoorbeeld) , op andere systemen. En hoewel dit mogelijk werkt in Android, is het niet gegarandeerd dat het werkt in andere besturingssystemen, waar gebruikers ervoor kunnen kiezen een interactieve shell te gebruiken die niet bash
. (Ik gebruik tcsh in FreeBSD, waar het de standaard shell is, en shebang-less script wordt geïnterpreteerd door de aanroepende shell.)
Dus vanaf waar ik zit, ziet het eruit alsof het is niet mogelijk om een shellscript te maken dat draagbaar is tussen Android- en niet-Android-systemen (Linux of Unix), omdat Android de dingen anders doet.
Opmerkingen
- In mijn ervaring zou
/bin/sh
moeten verwijzen naar iets meer alsbsh
ofdash
danbash
, wat relatief opgeblazen is en dus de voorkeur heeft voor interactief gebruik. - Hier zitten een paar fouten. Er zijn nog veel (meestal commerciële) Unices hier in de buurt (de meeste van hen Solaris 10 en eerder) waar
/bin/sh
de Bourne-winkel is l, geen POSIX-shell, POSIX specificeert niet ' het pad vansh
. De meeste shells (enexecp
/env
/find -exec...
) interpreteren een she-bang- less script met het systeem ' ssh
, slechts weinigen interpreteren het met zichzelf en als ze dat doen, doen ze het in POSIX-compatibiliteitsmodus. Dat ' is de standaard / POSIX-manier om script uit te voeren, maar dat veronderstelt dat de beller zich in een POSIX-omgeving bevindt. - Met betrekking tot * BSD
bash
is optioneel. Het betekent dat er goede kansen zijn dat zelfs/usr/local/bin/bash
niet bestaat op de systemen (om nog maar te zwijgen over eigen systemen zoals Solaris, AIX of HP-Ux). - @ StephaneChazelas – re POSIX, ik ben het er natuurlijk mee eens, en dat ' s waarom de woorden die ik gebruikte " waren, meestal POSIX-compatibel ". Maar deze vraag ging over draagbaarheid, in plaats van waar POSIX te vinden is, en men kan ' niet vertrouwen op een shell die altijd op één locatie wordt gevonden. Wat betreft de standaardinterpreter, een script zonder shebang dat in tcsh wordt uitgevoerd, wordt geïnterpreteerd door tcsh op FreeBSD. Het is duidelijk dat er ' s inconsistentie ook daar is, dus ik ' heb het antwoord dienovereenkomstig bijgewerkt.
- @Ouki – ja natuurlijk, ik dacht niet dat ' dat relevant was voor de vraag. Maar ik ' heb die verduidelijking aan het antwoord toegevoegd voor de duidelijkheid.
Antwoord
In mijn ervaring hebben #!/bin/sh
en #!/bin/bash
altijd de juiste omgeving gevonden op de weinige systemen waaraan ik heb gewerkt . Ik moet nog een uitzondering tegenkomen. Ik vind ook dat het routinematig wordt gebruikt in aan shell scripting gerelateerde teksten waarvan ik veronderstel dat ze zijn geschreven met het oog op draagbaarheid vanwege het diverse publiek.
Kan “niet hetzelfde zeggen met #!/usr/bin/env
.Sommige systemen hebben het geïnstalleerd als #!/bin/env
en hebben in het verleden mijn Python-scripts verbroken. Dus ik ga met de tweede opsomming.
Hier is wat ondersteuning voor mijn bovenstaande bewering:
Op CentOS release 5.7 krijg ik het volgende:
$ which env /bin/env
Op Ubuntu 12.04 Precise Pangolin:
$ which env /usr/bin/env
Bovendien, tenminste in één ouder systeem, herinner ik me de beheerders coreutils
op /opt
geïnstalleerd om de een of andere reden (dit is misschien geen best practice). Aangezien env
maakt deel uit van coreutils
, gebruikers kregen het uiteindelijk op /opt/coreutils/bin/env
. Toegegeven, ik heb niet alle systemen gebruikt, dus het antwoord is gebaseerd op mijn beperkte ervaring.
/bin/bash
is bijvoorbeeld zeker geen FreeBSD (zou be/usr/local/bin/bash
aangezien bash geen deel uitmaakt van de standaardshells)./usr/bin/env
(SCO wat barel is bestaande, NextStep die bijna uitgestorven is – plus natuurlijk de meest voorkomende niet-Unix-systemen zoals Android of Windows). Aan de andere kant bestaat/bin/bash
vrijwel alleen op niet-embedded Linux./bin/sh
is een veilige gok op elke Unix, maar een paar oudere systemen hebben daar een niet-POSIX Bourne-shell.which env
isn ' t relevant: er zijn nogal wat systemen waarbij/usr/bin
een symbolische link is naar/bin
of vice versa, waardoor beide/usr/bin/env
en/bin/env
bruikbaar. Het gaat erom dat/usr/bin/env
aanwezig is, wat het geval is op alle Linux-distributies die ik ' ooit heb gezien of waarvan ik heb gehoord (en zou zoveel dingen breken dat niemand het zou doen).