Diferents shebangs per a Linux: guia completa i pràctica

Darrera actualització: 27/02/2026
Autor: Isaac
  • El shebang «#!» indica al nucli quin intèrpret executarà l'script, podent utilitzar shells com a bash, sh o llenguatges com Python i Perl.
  • Escollir entre /bin/sh, /bin/bash o /usr/bin/env depèn de si es busca compatibilitat POSIX, extensions de bash o més portabilitat.
  • L'efectivitat del shebang canvia segons que s'invoqui l'script explícitament, com a executable o amb «.»/source, influint en subshells i entorn.
  • Les redireccions POSIX, canonades i operadors específics de bash permeten controlar entrada, sortida i errors dels processos als scripts.

Shebang a scripts de Linux

Quan comences a escriure scripts a GNU/Linux és molt fàcil perdre's amb la famosa primera línia que comença per #!, l'anomenat shebang que indica quin intèrpret executarà l'script . I és clar, així que veus exemples amb /bin/bash , altres amb /bin/sh , alguns amb /usr/bin/env python o fins i tot línies més rares com #!/bin/sh – , el dubte apareix: què poso jo als meus scripts i per què?

En les següents línies anem a esmicolar a fons el concepte de shebang, els diferents intèrprets disponibles a Linux, quan fer servir cada variant i quines bones pràctiques seguir . També veurem com es relaciona amb POSIX, amb distribucions com ara Debian o Ubuntu, amb la manera d'invocar scripts i amb llenguatges com Python, Perl o AWK, de manera que tinguis una visió global i pràctica.

manual de bash
Article relacionat:
Manual de Bash: guia completa de scripting a Linux

Què és exactament el shebang a Linux

El terme shebang (o hashbang) és el nom que es dóna a la seqüència de caràcters «#!» col·locada a la primera línia d'un fitxer de text executable en sistemes tipus Unix . La seva única missió és indicar al nucli quin programa ha d'utilitzar com a intèrpret per llegir i executar el contingut d'aquest fitxer.

Tot i que visualment sembla un simple comentari, la combinació de «#!» seguida d'una ruta absoluta a un executable té un significat especial pel sistema. Quan llences un script amb permisos d'execució, per exemple ./script.sh, el nucli llegeix la primera línia; si detecta el patró #!, pren el que ve a continuació com ruta de l'intèrpret i construeix internament una trucada equivalent a executar aquest intèrpret passant l'script com a paràmetre.

Des del punt de vista del llenguatge, el caràcter «#» continua sent l'inici d'un comentari per a shells com sh o bash , per la qual cosa aquesta línia no s'interpreta com a codi del mateix script sinó que només té significat per al sistema operatiu. Per això, si no es troba a la primera línia, es considera un comentari normal i el kernel ho ignora completament.

El mecanisme és general: es pot fer servir shebang amb qualsevol executable interpretador , no només amb shells. És habitual veure'l amb Python, Perl, AWK, Ruby o altres llenguatges de scripting , cosa que permet invocar el fitxer directament sense haver d'escriure l'ordre del llenguatge cada vegada.

Com actua el sistema operatiu en executar un script amb shebang

Quan un fitxer de text té permisos d'execució i el crides amb ./nom_script argument1 argument2 , el nucli segueix una seqüència molt concreta: llegeix la primera línia del fitxer, detecta el «#!», identifica la ruta de l'intèrpret i llança aquest programa passant-li l'script i els seus arguments.

A la pràctica, si tens un fitxer executable anomenat programa la primera línia del qual és #!/usr/bin/awk -f, en executar ./programa arg1 arg2 en realitat el sistema llança una cosa equivalent a /usr/bin/awk -f ./programa arg1 arg2. Aquesta traducció la fa el mateix nucli de manera transparent, de manera que tu només veus que el fitxer s'executa.

Aquest mateix mecanisme s'aplica a altres llenguatges: si l'script conté #!/usr/bin/env python, el sistema executarà l'ordre «/usr/bin/env python» passant l'script com a primer argument. Env s'encarrega de buscar l'intèrpret de Python al PATH de l'usuari, el que fa que aquest enfocament sigui més portable entre sistemes amb rutes diferents.

És important destacar que aquesta característica forma part del comportament dels sistemes Unix i Linux. En entorns com MS Windows, on el sistema associa l'execució a l'extensió del fitxer (per exemple, .exe), la línia amb «#!» s'ignora llevat que utilitzeu capes de compatibilitat o entorns específics com Cygwin o WSL.

Intèrprets de comandes i famílies de shells

El shebang es recolza directament en l'existència dels diferents intèrprets d'ordres o shells que hi ha instal·lats en un sistema GNU/Linux . Un shell és el programa que actua d'intermediari entre l'usuari i el sistema, processant les ordres, variables, funcions i estructures de control que us indiquem, ja sigui interactivament o mitjançant un script.

A l'univers Unix hi ha diverses famílies de shells amb sintaxi similar al seu interior . La família més estesa és la del Bourne Shell (sh) , que va donar lloc a derivats com bash, dash, ksh, zsh o ash . Aquests shells comparteixen gran part de la seva sintaxi bàsica, especialment aquella definida per l'estàndard POSIX, encara que cadascun incorpora extensions pròpies.

Dins aquesta família, bash (Bourne Again Shell) és l'intèrpret d'ordres per defecte en la majoria de distribucions Linux. Ofereix moltes funcionalitats addicionals (historial avançat, autocompletat, arrays, estructura select, operadors extra, etc.) respecte al Bourne Shell original. Els seus fitxers de configuració típics per a usuaris són ~/.bashrc y ~/.bash_profile.

Un altre actor important és dash (Debian Almquist Shell), un shell molt lleuger i ràpid, amb menys característiques que bash però més ajustat a l'estàndard POSIX. A Debian i Ubuntu, per exemple, /bin/sh sol ser un enllaç simbòlic a /bin/dash, precisament perquè els scripts del sistema (com els d'arrencada) es beneficiïn de la seva rapidesa i menor consum.

També trobem ksh (Korn Shell), centrat en funcions avançades de programació de scripts que poden competir en alguns escenaris amb eines com awk o perl . I, en una altra família diferent, hi ha csh (C Shell) i el seu derivat tcsh , que es caracteritzen per una sintaxi semblant al llenguatge C però amb un ús força menor que els Bourne-like.

El paper de /bin/sh i l'estàndard POSIX

Una de les claus per no embolicar-se amb els diferents shebangs és entendre què representa realment /bin/sh a cada sistema i què pinta aquí l'estàndard POSIX. Històricament, el Bourne Shell original es deia /bin/sh i estava disponible a totes les variants de Unix, fins al punt de convertir-se en un estàndard de facto.

  Emmagatzematge persistent en memòria (PMEM): què és i com es fa servir

L'IEEE va prendre aquesta realitat com a base per definir l'especificació POSIX 1003.2 (ISO 9945.2) , que descriu un llenguatge d'ordres estàndard. La major part dels shells de la família Bourne (bash, dash, ksh, etc.) implementen aquest estàndard , afegint-hi a partir d'aquí extensions particulars. Gràcies a això, un script escrit seguint les regles POSIX per a sh sol poder executar-se sense problemes a qualsevol d'aquests shells compatibles.

En sistemes GNU/Linux moderns, ja no existeix el Bourne Shell original, sinó implementacions compatibles amb ell. La ruta /bin/sh es manté com un enllaç simbòlic a un daquests shells. En algunes distribucions apunta a / Bin / bash, mentre que a Debian i Ubuntu sol apuntar a /bin/dash, decisió motivada pel desig que els scripts del sistema (#!/bin/sh) s'executin amb un intèrpret més ràpid i lleuger.

La conseqüència pràctica per a tu és clara: si el teu shebang és #!/bin/sh i escrius l'script respectant POSIX, hauries de poder executar-lo correctament tant amb dash com amb bash o ksh. Si en canvi aprofites extensions pròpies de bash (com certs tipus de bucles, arrays o operadors) (per exemple per scripts amb menús d'opcions), hauries d'usar explícitament #!/bin/bash o un equivalent basat en env.

Per això moltes guies recomanen que els scripts de sistema i d'ús general usin #!/bin/sh amb sintaxi POSIX, mentre que els scripts personals o d'usuari que depenen de característiques concretes de bash indiquin clarament /bin/bash a la línia del shebang.

Exemples de shebang per a diferents intèrprets

A partir de tot això, és fàcil entendre per què trobem diferents variants de shebang. Els més freqüents per a shells a Linux són línies com #!/bin/bash, #!/bin/dash, #!/bin/zsh, #!/bin/tcsh o #!/bin/csh. Cadascuna indica que l'script ha de ser llegit per un intèrpret d'ordres diferent, amb les seves pròpies particularitats sintàctiques.

En molts sistemes, bash s'instal·la per defecte a /bin/bash, així que la línia:

#!/bin/bash

fa que el nucli invoqui aquest executable concret. És l'opció habitual quan voleu utilitzar capacitats específiques de bash com a arrays indexats de forma nativa, el bucle for (( )), l'estructura select i un llarg etcètera d'extensions que no són presents en un sh POSIX mínim.

També pots trobar-te amb shebang com #!/usr/bin/perl, #!/usr/bin/env python3 o #!/usr/bin/env awk. En aquests casos, l'script no està pensat per a ser llegit per un intèrpret d'ordres sinó per altres llenguatges de scripting. La filosofia és la mateixa: la primera línia indica quin programa es farà servir per interpretar el contingut del fitxer.

Amb AWK, per exemple, un script executable que comenci amb:

#!/usr/bin/awk -f

serà tractat pel sistema com un fitxer d'ordres AWK i s'executarà com si haguessis trucat directament a /usr/bin/awk -f script.awk. El patró és idèntic per a Perl, Python i altres llenguatges habituals en entorns Unix.

Shebangs típics a Bash i Shell Script: pros i contres

Un dels dilemes més freqüents en escriure scripts és triar entre #!/usr/bin/env bash, #!/bin/bash, #!/bin/sh o variants similars. No hi ha una resposta única que valgui per a tot, però sí criteris raonables per a cada cas.

Quan uses #!/bin/bash estàs fixant directament la ruta absoluta a l'intèrpret. Això és simple, predictible i funciona bé a la majoria de distribucions GNU/Linux d'escriptori o servidor, on bash sol estar disponible en aquesta ubicació. El desavantatge és que en alguns entorns més exòtics o minimalistes aquesta ruta podria no existir.

D'altra banda, #!/usr/bin/env bash delega al programa env la tasca de localitzar el binari de bash al PATH de l'usuari. Aquest enfocament és més portable entre sistemes diferents (per exemple, a macOS, BSD o instal·lacions personalitzades) perquè no assumeix una ruta fixa, sinó que confia que bash estigui accessible al PATH. A canvi, depèn que /usr/bin/env sí que existeixi, una cosa gairebé universal però no absolutament garantida.

Quant a #!/bin/sh, la idea és just la contrària: no forçar bash, sinó declarar que l'script compleix l'estàndard POSIX i es pot executar amb l'intèrpret d'ordres «per defecte» del sistema. A Debian i Ubuntu això serà dash; en altres distribucions pot ser bash o un altre intèrpret d'ordres. És l'opció recomanada quan cerques màxima compatibilitat, rapidesa i adhesió a l'estàndard, sempre que et limitis a la sintaxi POSIX.

la variant #!/bin/sh - afegeix un matís: aquest guió pot servir perquè l'intèrpret arrenqui amb certes opcions, per exemple no carregant fitxers d'inici interactius o activant modes específics (segons l'intèrpret d'ordres concret). És menys comú en scripts corrents, però es pot veure en contextos molt controlats.

Diferències entre sintaxi POSIX i extensions de bash

Un punt clau per escollir bé el shebang és saber quina sintaxi estàs usant realment al teu script . Dos exemples il·lustren molt bé la diferència entre escriure a POSIX pur o dependre d'extensions de bash.

Un bucle for totalment POSIX compatible podria ser una cosa així:

#!/bin/sh
for VAR in 0 1 2 3
do
   echo "$VAR"
done

Aquest tipus de construcció és entesa sense problemes per sh, dash, bash i qualsevol intèrpret d'ordres que implementi l'estàndard POSIX. El més lògic és acompanyar-lo d'un shebang genèric com #!/bin/sh, de manera que pugui aprofitar l'intèrpret d'ordres que el sistema cregui convenient.

En canvi, bash ofereix un estil de bucle numèric més proper a llenguatges tipus C:

#!/bin/bash
for (( VAR=0; VAR<4; VAR++ ))
do
   echo "$VAR"
done

Aquesta sintaxi amb for (( )) no forma part de l'estàndard POSIX i no és compresa per shells mínims com a dash. Si executes aquest script amb /bin/dash script_bash.sh obtindràs errors de sintaxi, mentre que amb /bin/bash script_bash.sh funcionarà perfectament.

Per això, cada vegada que utilitzis funcionalitats específiques de bash hauries de declarar-ho clarament al shebang, En comptes d'usar #!/bin/sh. En cas contrari, el vostre script podrà fallar silenciosament en sistemes que utilitzin un shell POSIX estricte per a sh.

  Reparació Automàtica De Windows 10 No Funciona. Causes, Solucions, Alternatives

Com influeix el shebang segons la manera d'invocar un script

L'efecte del shebang no és el mateix en totes les maneres d'invocar un script. Depenent de si crides a l'script explícitament mitjançant un shell, l'executes com a fitxer o ho «importes» amb el punt, el comportament canvia.

Si uses invocació explícita , per exemple:

/bin/sh script_ejemplo.sh
/bin/dash script_ejemplo.sh
/bin/bash script_ejemplo.sh

el shebang s'ignora. L'intèrpret d'ordres que heu escrit al principi de l'ordre és el que s'usarà per interpretar l'script , sigui quina sigui la primera línia del fitxer. D'aquesta manera podeu provar un mateix script amb diferents shells per veure si compleix l'estàndard POSIX o si aprofita extensions d'un de concret.

Amb invocació implicat, quan llances directament ./script_ejemplo.sh després d'haver-li donat permisos d'execució, el kernel sí que mira la línia del shebang per decidir quin programa executarà el contingut. En aquest cas es crea un subshell o procés fill de l'intèrpret d'ordres actual que serà l'intèrpret que llegeixi l'script.

Hi ha a més la invocació amb punt (.) o source en bash, Tal que:

. script_ejemplo.sh

En aquest mode, l'script no s'executa en un procés fill sinó en el mateix intèrpret d'ordres actual . Això significa que les variables, funcions i canvis d'entorn que faci l'script afectaran directament la sessió actual. En aquest cas, el shebang també s'ignora perquè no es llança un nou intèrpret.

Tot això té conseqüències pràctiques importants: segons com invoquis l'script, l'usuari efectiu i els permisos del procés que l'executa poden canviar o no. Si truqueu a un script des d'un shell amb usuari normal, el procés fill heretarà aquest usuari i no podrà, per exemple, modificar fitxers protegits com /etc/passwd, llevat que es forci una altra cosa amb mecanismes com su -c o similars.

Ús del shebang en scripts reals

En crear un script des de zero a Linux, el més habitual és començar sempre per la línia de shebang que indiqui clarament l'intèrpret que vols utilitzar. Per exemple, si esteu escrivint un script senzill en bash per mostrar un banner, podries crear un fitxer mi_script.sh així:

#!/bin/bash
echo "Contenido de mi script"

Amb el fitxer desat, el següent pas és donar-li permisos dexecució amb una ordre com chmod +x mi_script.sh. A partir d'aquell moment el pots executar simplement amb ./mi_script.sh des del directori on us trobeu, sempre que el vostre PATH i permisos us ho permetin.

Si prefereixes utilitzar un shell POSIX estricte, pots canviar la primera línia a #!/bin/sh i escriure el contingut de l'script de manera compatible. Això és especialment útil en scripts que voleu reutilitzar en molts sistemes diferents, incloent entorns d'arrencada o scripts baix /etc/init.d/ on se sol emprar aquest enfocament.

Una alternativa molt estesa, sobretot en llenguatges com Python, és fer servir #!/usr/bin/env python3. Aquí la idea és deixar que env cerqueu l'executable de Python 3 al PATH i el llanci. Això evita dependre que l'intèrpret estigui exactament a /usr/bin/python3, cosa que pot variar segons la distribució o l'entorn.

De la mateixa manera, pots tenir scripts en Perl, AWK o fins i tot en shells menys habituals, sempre que la ruta (o l'ordre amb env) que posis a la línia del shebang apunti a un executable real existent al sistema on es corregi.

Bones pràctiques en triar i escriure el shebang

Perquè els vostres scripts siguin manejables, mantenibles i portables, convé seguir una sèrie de bones pràctiques a l'hora d'escriure la línia de shebang i configurar els permisos . Són detalls senzills que eviten molts mals de cap més endavant.

El primer és indicar sempre l'intèrpret adequat per al llenguatge o intèrpret d'ordres que estiguis utilitzant. Si l'script està escrit en bash i utilitza extensions específiques, no posis #!/bin/sh; si és Python 3, no facis servir simplement python si en el vostre sistema aquesta comanda llança Python 2. Ajusta la línia per reflectir la realitat del codi.

Com a norma general, és preferible utilitzar rutes absolutes al shebang, per exemple /bin/bash o /usr/bin/python3, per evitar ambigüitats. No obstant això, quan vols màxima portabilitat entre sistemes heterogenis, la tècnica de /usr/bin/env resulta molt útil, ja que cerca l'intèrpret al PATH i s'adapta millor a entorns on no controles la instal·lació exacta.

Un altre punt essencial és recordar sempre fer executables els fitxers de script amb chmod +x. Encara que els pots invocar trucant explícitament a l'intèrpret (per exemple bash script.sh), atorgar-los permís d'execució permet que es comportin com qualsevol altra ordre del sistema, especialment si afegeixes el directori al teu PATH (per exemple ~/scripts).

Des del punt de vista organitzatiu, és molt recomanable desar els teus scripts en un directori dedicat, com ~/bin o ~/scripts, i afegir-ho al PATH de l'usuari. Així evites tenir arxius executables escampats i aconsegueixes una experiència similar a la de fer servir ordres «oficials».

Finalment, encara que no està directament relacionat amb el shebang, comentar adequadament el codi dins de l'script en facilita la comprensió futura . Afegir comentaris sobre què fa l'script, quines assumpcions fa sobre l'entorn i quina sintaxi específica d'intèrpret d'ordres utilitza ajuda a decidir ràpidament quin shebang és el més apropiat si en algun moment has de modificar-lo.

Redireccions, descriptors i la seva relació amb l'intèrpret d'ordres

Per entendre bé la feina dels shells i, per extensió, de molts scripts que usen shebang, convé repassar com Linux associa recursos del sistema a fitxers i descriptors. En aquest model, gairebé tot s'exposa com un arxiu: directoris, dispositius, sockets, processos, pseudo-fitxers a /proc o /dev, Etc

Quan un procés vol llegir o escriure en un recurs, heu d'obrir el fitxer corresponent amb una trucada al sistema, obtenint un descriptor de fitxer que és simplement un número sencer. Aquest número identifica lassociació entre el procés i el recurs. Cada procés té la seva pròpia taula de descriptors, accessible per exemple a través de /proc/PID/fd/.

Per convenció, qualsevol procés té normalment associats tres descriptors especials: 0 (entrada estàndard), 1 (sortida estàndard) i 2 (sortida d'error estàndard) . L'intèrpret d'ordres que utilitzes a la terminal fa que el descriptor 0 apunti al teclat, mentre que 1 i 2 apunten a la pantalla. La majoria de comandes POSIX estan escrites per llegir de l'entrada estàndard (descriptor 0) i escriure a la sortida estàndard (1) o d'errors (2).

  Com crear i administrar un entorn d'instal·lació desatesa a Windows 11

Quan llances una ordre des d'un shell, el procés fill hereta l'associació d'aquests descriptors 0, 1 i 2 del procés pare , llevat que es faci alguna cosa explícita per canviar-los. D'aquí neix la potència de les redireccions: pots demanar a l'intèrpret d'ordres que reassigni aquests descriptors a fitxers o altres recursos abans de llançar el procés fill.

Per modificar els descriptors del propi intèrpret d'ordres actual s'usa l'ordre exec, permetent associar un descriptor a un fitxer per a lectura, escriptura o ambdues coses, duplicar descriptors o tancar-los. Per exemple, exec 4< /tmp/fichero vincula el descriptor 4 de l'intèrpret d'ordres amb /tmp/fichero per a lectura, de manera que més tard puguis fer ls >&4 per enviar la sortida de ls aquest descriptor.

Redireccions POSIX en ordres i scripts amb shebang

A nivell de comandes individuals (i per tant dins de qualsevol script sigui quin sigui el seu shebang), les redireccions POSIX permeten canviar de forma declarativa quin fitxer o recurs s'associa a cada descriptor en el procés fill . La sintaxi bàsica és:

comando op fichero_o_descriptor

on n és el descriptor (0, 1, 2, etc.), op és l'operador de redirecció (<, >, >>, <&, >&, Etc.) i fitxer_o_descriptor és la ruta o descriptor objectiu. Si omets n, es prenen valors per defecte (0 per a entrada, 1 per a sortida).

Les redireccions d'entrada (<) fan que l'ordre llegeixi des d'un fitxer en comptes de des de l'entrada estàndard. Per exemple, cat < fichero aconsegueix que «fitxer» es converteixi en l'entrada estàndard de cat, que seguirà escrivint a la sortida estàndard (pantalla).

Les redireccions de sortida (> y >>) envien la sortida estàndard a un fitxer, truncant el contingut anterior (>) o afegint al final (>>). Combinades amb 2> o 2>&1, permeten també redirigir els missatges d'error. És molt habitual en scripts amb shebang veure línies de l'estil ls -l /bin/bash ./script > fichero 2>&1 per agrupar la sortida normal i d'error en un mateix fitxer.

Existeixen també els anomenats Here-Documents, que s'escriuen amb << delimitador i permeten introduir text encastat directament al propi script. Tot allò que escriguis fins al delimitador es converteix en l'entrada estàndard de l'ordre. Per exemple:

cat << END > fichero

farà que tot allò teclejat fins a la línia que contingui sol END es guardi a fichero. Aquesta tècnica s'usa molt dins de scripts amb shebang per generar fitxers de configuració o blocs de text llargs sense haver de crear fitxers temporals a mà.

Ús de canonades i operadors específics de Bash

Un altre mecanisme clau és la canonada o pipeline, representada per l'operador «|». Quan escrius alguna cosa com comando1 | comando2, l'intèrpret d'ordres associa la sortida estàndard de comando1 amb l'entrada estàndard de comando2, De manera que la informació flueix d'un procés a l'altre sense passar per fitxers intermedis.

Aquest patró està tan assumit que es fa servir gairebé sense pensar: ls | more envia el llistat produït per ls a more, que ho presenta per pantalla paginant-ho. En un script amb un shebang POSIX o de bash la semàntica és la mateixa; l'únic que canvia és quin shell interpreta la canonada.

A més dels operadors definits per POSIX, bash afegeix algunes dreceres pròpies per a redireccions combinades. Per exemple, cmd &> fichero o cmd >& fichero fan que tant la sortida estàndard com la derror es redirigeixin al mateix fitxer, equivalents a cmd > fichero 2>&1. Aquestes formes abreujades no són portables a tots els shells POSIX, així que si uses hauries d'assegurar-te que el shebang apunti explícitament a bash.

Un dels detalls més fins en treballar amb redireccions a scripts és l'ordre. L'intèrpret d'ordres analitza les redireccions d'esquerra a dreta abans d'executar l'ordre. Canviar la vostra posició pot alterar el resultat de forma significativa, com s'aprecia en exemples del tipus ls /tmp 2> file 1>&2 per davant d' 1>&2 ls /tmp 2> file.

Quan vols descartar informació per complet, és clàssic recórrer al fitxer nul /dev/null, que actua com un «forat negre» per a la sortida. Per exemple, ls -l /usr > /dev/null 2>&1 fa que la sortida estàndard i la d'errors desapareguin, cosa molt habitual per a scripts que no han de mostrar res excepte error crític.

Tot plegat, entendre bé el concepte de shebang, les diferències entre /bin/sh i /bin/bash, el paper de POSIX, els diferents intèrprets disponibles i les possibilitats de redirecció i canonades et permet escriure scripts molt més robustos i portables. Si escolliu conscientment la línia inicial, respecteu la sintaxi adequada per a cada intèrpret d'ordres i cuideu l'entorn d'execució, els vostres scripts es comportaran de manera predictible en la majoria de sistemes GNU/Linux i Unix, des de senzills guions a la vostra carpeta personal fins a complexes rutines d'arrencada del sistema.