Comandes internes de Bash (builtins) | Iespai
Bash

Les comandes internes de Bash: què són, com reconèixer-les i com aprofitar-les



Quan escrius una comanda a Bash, normalment el shell busca un programa amb aquell nom als directoris de la variable $PATH (/usr/local/bin, /usr/bin…) i l’executa. Però hi ha un grup de comandes que no són cap fitxer del disc: formen part del mateix Bash i sempre estan carregades a la memòria. Són les comandes internes (builtins). En aquest post veurem quines són, per què existeixen, com distingir-les de les externes i com treure’n profit.


Què són i per què existeixen

Una comanda interna és una funció del propi intèrpret Bash. Quan l’executes, Bash no ha de buscar cap fitxer ni crear cap procés nou: ho fa ell mateix. Això té dues conseqüències:

  1. Algunes comandes només poden ser internes. Un programa extern s’executa en un procés fill i no pot canviar l’estat del shell que l’ha llançat. Per això cd (canviar el directori actual del shell), export (definir variables que heretaran els programes que llancis), alias, source o exit han de ser internes per força. Prova-ho: no existeix cap /usr/bin/cd.
  2. Són més ràpides. No cal crear un procés ni carregar un programa del disc. En una comanda sola no ho notes, però en un bucle sí. En un Raspberry Pi 4, mil echo:
$ time (for i in {1..1000}; do echo hola >/dev/null; done)
real 0m0.039s

$ time (for i in {1..1000}; do /bin/echo hola >/dev/null; done)
real 0m3.794s

Gairebé cent vegades més lent amb el programa extern.


Com saber si una comanda és interna: type

La comanda type (que també és interna) t’ho diu:

$ type cd ls echo time
cd is a shell builtin
ls is /usr/bin/ls
echo is a shell builtin
time is a shell keyword

Algunes comandes existeixen de les dues maneres: com a comanda interna i com a programa (normalment de les GNU coreutils). Amb type -a les veus totes, en l’ordre en què Bash les buscaria:

$ type -a echo
echo is a shell builtin
echo is /usr/bin/echo
echo is /bin/echo

Passa el mateix amb pwd, test, [, kill, printf… Sempre guanya la interna, i no es comporten exactament igual. Per exemple, /bin/echo --version mostra la versió de coreutils, mentre que l’echo de Bash escriu literalment --version. Si vols forçar el programa extern, escriu-ne la ruta completa (/bin/echo) o fes servir env echo.

Altres eines útils:

  • compgen -b llista totes les comandes internes (a Bash 5.2, n’hi ha 61).
  • help mostra l’ajuda de les comandes internes, que no sempre tenen pàgina de man pròpia: help cd, help -d read (descripció d’una línia), o help sol per veure-les totes.
  • which no sap res de les comandes internes, perquè només busca al $PATH. Per això which cd no mostra res: fes servir type.

Les comandes internes més útils

ComandaPer a què serveixExemple
cdCanviar de directoricd ~/Documents, cd - (torna a l’anterior)
pwdMostrar el directori actualpwd
echoEscriure text o variablesecho "Hola, $USER"
printfEscriure text amb formatprintf '%-10s %5d\n' joan 42
alias / unaliasCrear (o esborrar) dreceres de comandesalias ll='ls -la'
exportFer que una variable passi als programes que llancisexport EDITOR=nano
historyVeure l’historial de comandeshistory 20
source (o .)Executar un fitxer dins del shell actualsource ~/.bashrc
readLlegir una línia del teclat cap a una variableread -p "Nom: " nom
typeDir què és una comandatype ll
jobs, fg, bgGestionar processos en segon plafg %1
set, shoptActivar opcions del shellshopt -s globstar
unsetEsborrar una variable o funcióunset nom
umaskPermisos per defecte dels fitxers nousumask 022
ulimitLímits de recursos del shellulimit -n
exitSortir del shell (o d’un script) amb un codiexit 1

Exemples pràctics

Moure’t pels directoris

$ cd /etc
$ pwd
/etc
$ cd -
/home/oscar

En tens més detalls als posts de cd i pwd.

Àlies: dreceres per a comandes llargues

$ alias ll='ls -la'
$ alias gst='git status'
$ type ll
ll is aliased to `ls -la'

Sense arguments, alias mostra tots els àlies definits. Debian i Ubuntu ja en porten alguns al ~/.bashrc, com alias ls='ls --color=auto'. Els àlies que defineixes al terminal es perden en tancar-lo: per fer-los permanents, afegeix-los al final del teu ~/.bashrc i recarrega’l amb source ~/.bashrc.

Variables d’entorn amb export

$ export PATH="$PATH:$HOME/bin"
$ echo "$PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/home/oscar/bin

Ara Bash també buscarà programes al directori ~/bin. Igual que amb els àlies, el canvi només dura fins que tanquis la sessió: per fer-lo permanent, posa la línia al ~/.bashrc (o al ~/.profile). Ho tens explicat a els fitxers d’inici de sessió de Bash.

Una variable definida sense export (EDITOR=nano) només la veu el shell actual, no els programes que llancis des d’ell.

L’historial

$ history 3
  501  cd /etc
  502  ls
  503  history 3

Pots tornar a executar una comanda de l’historial pel seu número amb !501, repetir l’última amb !! (molt útil per fer sudo !! quan t’has oblidat del sudo) o cercar-hi amb Ctrl+R. En tens molts més trucs al post sobre la comanda history.

Demanar dades en un script

#!/bin/bash
read -p "Com et dius? " nom
printf 'Hola, %s!\n' "$nom"

Comandes internes als scripts

Quan escriguis scripts, aprofita les comandes internes i les expansions de Bash en lloc de cridar programes externs dins de bucles. Per exemple, ${fitxer%.txt} treu l’extensió sense haver de cridar basename o sed, i [[ ... ]] fa comparacions sense cridar test. En un bucle que es repeteix milers de vegades, la diferència és molt gran, com has vist amb l’exemple de echo.


Conclusió

Les comandes internes són la part del treball que Bash fa ell mateix, sense llançar cap programa. Algunes, com cd o export, no podrien funcionar d’una altra manera; d’altres, com echo o printf, existeixen per rapidesa. Recorda type per saber què estàs executant realment i help per consultar-ne l’ajuda.

Posts relacionats

Esta web usa cookies.