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:
- 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,sourceoexithan de ser internes per força. Prova-ho: no existeix cap/usr/bin/cd. - 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 -bllista totes les comandes internes (a Bash 5.2, n’hi ha 61).helpmostra l’ajuda de les comandes internes, que no sempre tenen pàgina demanpròpia:help cd,help -d read(descripció d’una línia), ohelpsol per veure-les totes.whichno sap res de les comandes internes, perquè només busca al$PATH. Per aixòwhich cdno mostra res: fes servirtype.
Les comandes internes més útils
| Comanda | Per a què serveix | Exemple |
|---|---|---|
cd | Canviar de directori | cd ~/Documents, cd - (torna a l’anterior) |
pwd | Mostrar el directori actual | pwd |
echo | Escriure text o variables | echo "Hola, $USER" |
printf | Escriure text amb format | printf '%-10s %5d\n' joan 42 |
alias / unalias | Crear (o esborrar) dreceres de comandes | alias ll='ls -la' |
export | Fer que una variable passi als programes que llancis | export EDITOR=nano |
history | Veure l’historial de comandes | history 20 |
source (o .) | Executar un fitxer dins del shell actual | source ~/.bashrc |
read | Llegir una línia del teclat cap a una variable | read -p "Nom: " nom |
type | Dir què és una comanda | type ll |
jobs, fg, bg | Gestionar processos en segon pla | fg %1 |
set, shopt | Activar opcions del shell | shopt -s globstar |
unset | Esborrar una variable o funció | unset nom |
umask | Permisos per defecte dels fitxers nous | umask 022 |
ulimit | Límits de recursos del shell | ulimit -n |
exit | Sortir del shell (o d’un script) amb un codi | exit 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.