shell script header voor beste compatibiliteit [duplicate]

Deze vraag heeft hier al antwoorden :

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 dat sh niet bash .. . 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 als bsh of dash dan bash, 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 van sh. De meeste shells (en execp / env / find -exec...) interpreteren een she-bang- less script met het systeem ' s sh, 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.

Reacties

  • /bin/bash is bijvoorbeeld zeker geen FreeBSD (zou be /usr/local/bin/bash aangezien bash geen deel uitmaakt van de standaardshells).
  • Het ' is eerder het tegenovergestelde: alleen bij sommige zeer zeldzame systemen ontbreekt /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.
  • @Gilles Bedankt voor de info. Ik heb mijn antwoord bijgewerkt met enig bewijs van wat ik heb gezien op sommige systemen die ik ben tegengekomen.
  • 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).

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *