Tabla de contenidos
Algunos consejos para quién quiera aprender a programar en el sistema Debian para trazar el código fuente. Aquí están los paquetes más importantes y los paquetes de documentación más importantes para la programación.
Las referencia en línea está disponible escribiendo «man
nombre
» tras instalar los paquetes manpages
y
manpages-dev
. La referencia en línea para las
herramientas GNU están disponibles escribiendo «info
nombre_de_programa
» después de instalar los paquetes
correspondientes de documentación. Pude necesitar incluir los repositorios
contrib
y non-free
además del
repositorio main
ya que una parte de la documentación
GFDL no se considera que cumple con DFSG.
Por favor, considera la posibilidad de utilizar las herramientas del sistema de control de versiones. Ver Sección 10.5, “Git”.
Aviso | |
---|---|
No use« |
Atención | |
---|---|
Puede instalar programas de software directametne compilado de la fuente en
« |
Sugerencia | |
---|---|
Los ejemplos de código para crear «La canción de 99 botellas de Cerveza« le aportará buenas ideas para prácticamente cualquier lenguaje de programación. |
Un archivo de órdenes es un archivo de texto con el bit de ejecución activado y contiene órdenes con el formato siguiente.
#!/bin/sh ... command lines
La primera línea determina cuál es el intérprete de órdenes que se encarga de leer y ejecutar el contenido del archivo.
La lectura de archivos de órdenes es la mejor manera de entender como funciona un sistema tipo Unix. Aquí, doy algunos apuntes para la programación de archivos de órdenes. Consulte «Errores con el intérprete de órdenes« (https://www.greenend.org.uk/rjk/2001/04/shell.html) para aprender los errores más comunes.
A diferencia del uso interactivo del intérprete de órdenes (consulte Sección 1.5, “Órdenes simples para el intérprete de órdenes” y Sección 1.6, “Operaciones de texto al estilo de Unix”) en los archivos de órdenes se usan generalmente parámetros, condiciones y bucles.
Muchos scripts en el sistema se pueden ejecutar por cualquier shell POSIX (ver Tabla 1.13, “Relación de intérpretes de órdenes”).
El shell POSIX no interactivo por defecto "/usr/bin/sh
"
es un enlace simbólico que apunta a /usr/bin/dash
y lo
utiliza muchos programas del sistema.
El shell POSIX interactivo predeterminado es
/usr/bin/bash
.
Evite escribir archivos de órdenes con particularidades de bash o zs para
hacerlo portable entre intérpretes de órdenes POSIX. Puede comprobarlo
utilizando checkbashisms
(1).
Tabla 12.1. Relación de particularidades de bash
Bien: POSIX | Mal: bashism |
---|---|
if [ «$foo« = «$bar« ] ; then … |
if [ «$foo« == «$bar« ] ; then … |
diff -u archivo.c.orig archivo.c |
diff -u archivo.c{.orig,} |
mkdir /foobar /foobaz |
mkdir /foo{bar,baz} |
funcname() { … } |
function funcname() { … } |
formato octal: «\377 » |
formato hexadecimal: «\xff » |
La orden «echo
» debe utilizarse con cuidado ya que su
implementación cambia entre la orden interna y la externa.
Evite utilizar cualquier opción excepto -n
».
Evite utilizar secuencias de escape en una cadena ya que su tratamiento varia.
Nota | |
---|---|
Ya que la opción « |
Sugerencia | |
---|---|
Utilice la orden « |
Frecuentemente son utilizados por el intérprete de órdenes parámetros especiales
Tabla 12.2. Relación de los parámetros de intérprete de órdenes
parámetro del intérprete de órdenes | valor |
---|---|
$0 |
nombre del archivo de órdenes |
$1 |
primer parámetro del archivo de órdenes |
$9 |
noveno parámetro del archivo de órdenes |
$# |
parámetro posicionado en el número |
«$*« |
«$1 $2 $3 $4 … « |
«$@« |
«$1« «$2« «$3« «$4« … |
$? |
estado de finalización de la orden más reciente |
$$ |
PID de este archivo de órdenes |
$! |
PID del trabajo en segundo plano que se ha iniciado más recientemente |
Lasexpansiones de parámetros fundamentales que debe recordar son las que se muestran.
Tabla 12.3. Relación de expansiones de parámetros del intérprete de órdenes
forma de expresión del parámetro | valor si var esta activado |
valor si var no está asignado |
---|---|---|
${var:-string} |
«$var » |
«string » |
${var:+string} |
«string » |
«null » |
${var:=string} |
«$var » |
«string » (y ejecuta «var=string ») |
${var:?string} |
«$var » |
echo «string » a stderr
(y finalizar con error) |
Aquí, el símbolo «:
» en todos estos operadores es
realmente opcional.
con «:
» el operador =
comprueba que existe y no es null
sin «:
» el operador =
comprueba únicamente si existe
Tabla 12.4. Relación de las sustituciones clave de parámetros del intérprete de órdenes
formulario de sustitución del parámetro | resultado |
---|---|
${var%suffix} |
elimina patrón del sufijo más pequeño |
${var%%suffix} |
elimina el patrón del sufijo más largo |
${var#prefix} |
elimina el patrón del prefijo más pequeño |
${var##prefix} |
elimina el patrón del prefijo más largo |
Cada comando devuelve un estado de salida que puede usarse para expresiones condicionales.
Éxito: 0 («Verdadero«)
Error: no 0 («Falso«)
Nota | |
---|---|
En el contexto del intérprete de órdenes «0« es equivalente a «verdadero«, mientras que en contexto de una condición en C «0« significa «falso«. |
Nota | |
---|---|
« |
Algunas expresiones condicionales que es importante recordar son las que se muestran.
«orden &&
si_éxito_ejecuta_esta_orden_además || true
»
«orden ||
si_no_tiene_éxito_ejecuta_esta_orden_además ||
true
»
Un pequeño archivo de órdenes de varias líneas como se muestra
if [ conditional_expression ]; then if_success_run_this_command else if_not_success_run_this_command fi
Aquí se añade «|| true
» para asegurarnos de que el
archivo de órdenes no finaliza en esta línea si el intérprete de órdenes se
llama con la bandera «-e
».
Tabla 12.5. Relación de operadores para comparar archivos en la expresión condicional
ecuación | condición que devuelve un verdadero lógico |
---|---|
-e archivo |
archivo existe |
-d archivo |
archivo existe y es un directorio |
-f archivo |
archivo existe y es un archivo normal |
-w archivo |
archivo existe y se puede modificar |
-x archivo |
archivo existe y es ejecutable |
archivo1 -nt
archivo2 |
archivo es más nuevo quearchivo2 (respecto de la modificación) |
archivo1 -ot
archivo2 |
archivo1 es más viejo que archivo2 (modificación) |
archivo1 -ef
archivo2 |
archivo1 y archivo2 están en el mismo dispositivo y tienen el mismo número de inodo |
Tabla 12.6. Relación de operadores de comparación de cadenas en expresiones condicionales
ecuación | condición que devuelve un verdadero lógico |
---|---|
-z str |
la longitud de str es cero |
-n str |
la longitud de str no es cero |
str1 = str2 |
str1 y str2 son iguales |
str1 != str2 |
str1 y str2 no son iguales |
str1 < str2 |
str1 está antes que str2 (depende de la configuración regional) |
str1 > str2 |
str1 está después de la str2 (depende de la configuración local) |
Los operadores aritméticos de comparación
de enteros en la expresión original son «-eq
»,
«-ne
», «-lt
»,
«-le
», «-gt
» y
«-ge
».
Existen diferentes bucles en el intérprete de órdenes POSIX.
«for x in foo1 foo2 … ; do comand0 ; done
» asigna
secuencialmente elementos de la relación «foo1 foo2 …
» a
la variable «x
» y ejecuta «comando
».
«while condition ; do command ; done
» repite
«command
» mientras «condition
» sea
verdadero.
«until condition ; do command ; done
» repite
«command
» mientras «condition
» no sea
verdadero.
«break
» permite salir del bucle.
«continue
» permite continuar con la próxima iteración del
bucle.
Sugerencia | |
---|---|
La iteración sobre números como la del lenguaje C
puede realizarse con la utilización de |
Sugerencia | |
---|---|
Ver Sección 9.4.9, “Repetición de una orden sobre archivos”. |
Algunas variables del entorno populares para el símbolo del sistema del shell normal pueden no estar disponibles en el entorno de ejecución de su script.
Para "$USER
", usar "$(id -un)
"
Para "$UID
", usa "$(id -u)
"
Para "$HOME
", utiliza "$(getent passwd "$(id
-u)"|cut -d ":" -f 6)
" (esto también funciona en Sección 4.5.2, “La actual gestión centralizada de sistemas”)
El shell procesa un script aproximadamente como la siguiente secuencia.
el intérprete de órdenes lee la línea
El intérprete de órdenes agrupa como un único
elemento la parte de la línea incluida entre
«…«
o '…'
.
el intérprete de órdenes divide el resto de la línea en elementos como se muestra.
Espacios en blanco: space
tab newline
Metacaracteres: < > | ; & ( )
El intérprete de órdenes comprueba si cada elemento es una palabra reservada para adaptar su comportamiento si
no esta incluida entre «…«
o '…'
.
palabras reservadas: si entonces
elif else fi para in while a menos que se haga caso esac
el intérprete de órdenes expande los alias si no están incluidos entre
«…«
o '…'
El intérprete de órdenes expande las tilde si no están incluidas entre
«…«
o '…'
.
«~
» → el directorio home del usuario actual
«~user
» → el directorio home de
usuario
el intérprete de órdenes expande los parámetros a sus valores si no están incluidos
entre '…'
parámetro:
«$PARAMETER
» o «${PARAMETER}
»
el intérprete de órdenes expande la sustitución de
órdenes si no está incluida entre '…'
«$( comando )
» → la salida de
«comando
»
«` command `
» → la salida de «command
»
el intérprete de órdenes expande las rutas de
nombres que encajan con nombres de archivos si no están incluidas
entre «…«
o '…'
*
→ cualquier carácter
?
→ un carácter
[…]
→ cualquiera de los caracteres en
«…
»
el intérprete de órdenes busca las órdenes como se muestra y los ejecuta
definición de lafunción
orden interna
archivo ejecutable en
«$PATH
»
el intérprete de órdenes va a la siguiente línea y repite este proceso de nuevo desde el inicio de la secuencia
Las comillas simples no tienen efecto dentro de comillas dobles.
Si ejecuta «set -x
» en el intérprete de órdenes o lo
llama con la opción «-x
» hace que se impriman todas las
órdenes ejecutadas. Esto puede ser muy útil para la depuración.
Para hacer los archivos de órdenes tan portables como sea posible entre sistemas Debian, es una buena idea limitar las utilidades a aquellos que son proporcionados por los paquetes esenciales.
«aptitude search ~E
» relación de paquetes esenciales.
«dpkg -L package_name | grep
'/man/man.*/'
» relación de páginas del manual de órdenes del
paquete package_name
.
Tabla 12.7. Relación de paquetes que contienen pequeñas utilidades para los archivos de órdenes
paquete | popularidad | tamaño | descripción |
---|---|---|---|
dash
|
V:884, I:997 | 191 | Shell compatible con POSIX pequeño y rápido para sh |
coreutils
|
V:880, I:999 | 18307 | Utilidades fundamentales GNU |
grep
|
V:782, I:999 | 1266 | GNU grep , egrep y
fgrep |
sed
|
V:790, I:999 | 987 | GNU sed |
mawk
|
V:442, I:997 | 285 | pequeño y rápido awk |
debianutils
|
V:907, I:999 | 224 | utilidades varias específicas de Debian |
bsdutils
|
V:519, I:999 | 356 | utilidades básicas de BSD-Lite 4.4 |
bsdextrautils
|
V:596, I:713 | 339 | Herramientas adicionales de 4.4BSD-Lite |
moreutils
|
V:15, I:38 | 231 | utilidades adicionales de Unix |
Sugerencia | |
---|---|
Aunque |
Ver un ejemplo en Sección 1.6, “Operaciones de texto al estilo de Unix”.
Tabla 12.8. Lista de paquetes relacionados con el intérprete
paquete | popularidad | tamaño | documentación |
---|---|---|---|
dash
|
V:884, I:997 | 191 | sh: shell pequeño y rápido compatible con POSIX
para sh |
bash
|
V:838, I:999 | 7175 | sh: "info bash " proporcionado
por el paquete bash-doc |
mawk
|
V:442, I:997 | 285 | AWK: pequeño y rápido awk |
gawk
|
V:285, I:349 | 2906 | AWK: "info gawk " proporcionado
por gawk-doc |
perl
|
V:707, I:989 | 673 | Perl: perl (1) y páginas html
proporcionadas por perl-doc y perl-doc-html
|
libterm-readline-gnu-perl
|
V:2, I:29 | 380 | Extensión de Perl para la biblioteca GNU ReadLine/History Library:
perlsh (1) |
libreply-perl
|
V:0, I:0 | 171 | REPL para Perl: reply (1) |
libdevel-repl-perl
|
V:0, I:0 | 237 | REPL para Perl: re.pl (1) |
python3
|
V:718, I:953 | 81 | Python: python3 (1) y
páginas html proporcionadas por python3-doc |
tcl
|
V:25, I:218 | 21 | Tcl: tcl (3) páginas de manual
detalladas proporcionadas por tcl-doc |
tk
|
V:20, I:211 | 21 | Tk: tk (3) y páginas detalladas
del manual proporcionadas por tk-doc |
ruby
|
V:86, I:208 | 29 | Ruby: ruby (1),
erb (1), irb (1),
rdoc (1), ri (1) |
Cuando deseas automatizar una tarea en Debian, deberías programarla primero con un lenguaje interpretado. La línea guía para la elección del lenguaje interpretado es:
Utilizadash
, si la tarea es sencilla y combina programas
CLI con un programa shell.
Utiliza python3
, si la tarea no es sencilla y la estás
escribiendo desde cero.
Usa perl
, tcl
,
ruby
, ... si hay un código existente usando uno de estos
lenguajes en Debian que necesita ser retocado para hacer la tarea.
Si el código resultante es demasiado lento, puede reescribir sólo la parte crítica para la velocidad de ejecución en un lenguaje compilado y llamarlo desde el lenguaje interpretado.
La mayoría de los intérpretes ofrecen funciones básicas de comprobación sintáctica y rastreo de código.
“dash -n script.sh” - Comprobación de sintaxis de un script de Shell
“dash -x script.sh” - Trazar un script de Shell
"python -m py_compile script.py" - Comprobación sintáctica de un script Python
"python -mtrace --trace script.py" - Rastrear un script de Python
"perl -I ../libpath -c script.pl" - Comprobación sintáctica de un script Perl
“perl -d:Trace script.pl” - Trazar un script de Perl
Para probar el código para dash
, prueba Sección 9.1.4, “Readline wrapper” que se acomoda a un entorno interactivo tipo
bash
.
Para probar código para perl
, prueba el entorno REPL para
Perl que acomoda Python-like REPL (=READ + EVAL + PRINT + LOOP)
entorno para Perl.
El script de shell se puede mejorar para crear un programa GUI atractivo.
El truco es usar uno de los llamados programas de diálogo en lugar de una
interacción ligera usando los comandosecho
y
read
.
Tabla 12.9. Lista de programas de diálogo
paquete | popularidad | tamaño | descripción |
---|---|---|---|
x11-utils
|
V:192, I:566 | 651 | xmessage (1): muestra un mensaje o realiza un pregunta en
una ventana(X) |
whiptail
|
V:284, I:996 | 56 | muestra cuadros de diálogo de fácil uso para los archivos de órdenes (newt) |
dialog
|
V:11, I:99 | 1227 | muestra cuadros de diálogo de fácil uso para los archivos de órdenes (ncurses) |
zenity
|
V:76, I:363 | 183 | mostrar cuadros de diálogo gráficos a partir de scripts de shell (GTK) |
ssft
|
V:0, I:0 | 75 | Herramienta de interfaz de archivo de órdenes (cubierto con zenity, kdialog y dialog con gettext) |
gettext
|
V:56, I:259 | 5818 | «/usr/bin/gettext.sh »: traduce un mensajes |
Aquí hay un ejemplo del programa GUI para demostrar lo fácil que es sólo con un script de shell.
Este script usa zenity
para seleccionar un archivo
(predeterminado /etc/motd
) y mostrarlo.
El lanzador GUI para este script se puede crear siguiendo Sección 9.4.10, “Iniciar un programa desde el interfaz gráfico de usuario”.
#!/bin/sh -e # Copyright (C) 2021 Osamu Aoki <[email protected]>, Public Domain # vim:set sw=2 sts=2 et: DATA_FILE=$(zenity --file-selection --filename="/etc/motd" --title="Select a file to check") || \ ( echo "E: File selection error" >&2 ; exit 1 ) # Check size of archive if ( file -ib "$DATA_FILE" | grep -qe '^text/' ) ; then zenity --info --title="Check file: $DATA_FILE" --width 640 --height 400 \ --text="$(head -n 20 "$DATA_FILE")" else zenity --info --title="Check file: $DATA_FILE" --width 640 --height 400 \ --text="The data is MIME=$(file -ib "$DATA_FILE")" fi
Este tipo de aproximación al programa GUI con el shell script es útil sólo para casos de elección simple. Si va a escribir cualquier programa con complejidades, por favor considera escribirlo en una plataforma más capaz.
Los programas archivadores GUI pueden ampliarse para realizar algunas acciones populares en archivos seleccionados utilizando paquetes de extensión adicionales. También pueden realizar acciones personalizadas muy específicas añadiendo sus scripts específicos.
Para GNOME, ver NautilusScriptsHowto.
Para KDE, ver Creación de menús de servicio Dolphin.
Para Xfce, ver Thunar - Acciones personalizadas y https://help.ubuntu.com/community/ThunarCustomActions.
Para LXDE, ver Acciones personalizadas.
Para procesar los datos, sh
necesita generar subprocesos
que ejecuten cut
, grep
,
sed
, etc., es lento. Por otro lado,
perl
tiene capacidades internas para procesar datos, y es
rápido. Así que muchos scripts de mantenimiento del sistema en Debian usan
perl
.
Pensemos en seguir un fragmento de la secuencia de comandos AWK de una sola línea y sus equivalentes en Perl.
awk '($2=="1957") { print $3 }' |
Esto es equivalente a cualquiera de las siguientes líneas.
perl -ne '@f=split; if ($f[1] eq "1957") { print "$f[2]\n"}' |
perl -ne 'if ((@f=split)[1] eq "1957") { print "$f[2]\n"}' |
perl -ne '@f=split; print $f[2] if ( $f[1]==1957 )' |
perl -lane 'print $F[2] if $F[1] eq "1957"' |
perl -lane 'print$F[2]if$F[1]eq+1957' |
El último es retorcido. Utiliza algunas de las funcionalidades avanzadas de Perl.
El espacio en blanco es opcional.
La conversión entre números y cadenas se realiza de forma automática.
Trucos de ejecución de Perl mediante las opciones de la línea de comandos:
perlrun
(1)
Variables especiales de Perl: perlvar
(1)
Esta flexibilidad es el punto fuerte de Perl. Al mismo tiempo, esto nos permite crear códigos crípticos y enredados. Así que ten cuidado.
Tabla 12.10. Lista de paquetes relacionados con el compilador
paquete | popularidad | tamaño | descripción |
---|---|---|---|
gcc
|
V:167, I:550 | 36 | Compilador de GNU C |
libc6-dev
|
V:248, I:567 | 12053 | Biblioteca C de GNU: Bibliotecas de desarrollo y archivos de cabecera |
g++
|
V:56, I:501 | 13 | Compilador GNU C++ |
libstdc++-10-dev
|
V:14, I:165 | 17537 | GNU Standard C++ Library v3 (archivos de desarrollo) |
cpp
|
V:334, I:727 | 18 | Preprocesador GNU C |
gettext
|
V:56, I:259 | 5818 | Utilidades de internacionalización GNU |
glade
|
V:0, I:5 | 1204 | Desarrollador de interfaces de usuario GTK |
valac
|
V:0, I:4 | 725 | Lenguaje similar a C# para el sistema GObject |
flex
|
V:7, I:73 | 1243 | LEX-compatible generador analizador de léxico rápido |
bison
|
V:7, I:80 | 3116 | YACC-compatible generador de analizador |
susv2
|
I:0 | 16 | cumple «La Especificación Única de UNIX v2« |
susv3
|
I:0 | 16 | cumple «La Especificación Única de UNIX v3« |
susv4
|
I:0 | 16 | buscar "Las especificaciones únicas de UNIX v4" |
golang
|
I:20 | 11 | Compilador del lenguaje de programación Go |
rustc
|
V:3, I:14 | 8860 | Lenguaje de programación de sistemas Rust |
haskell-platform
|
I:1 | 12 | Bibliotecas y herramientas estándarHaskell |
gfortran
|
V:6, I:62 | 15 | Compilador de GNU Fortran 95 |
fpc
|
I:2 | 103 | Pascal libre |
Aquí, Sección 12.3.3, “Flex — una mejora de Lex” y Sección 12.3.4, “Bison — una mejora de Yacc” se incluyen para indicar cómo se puede escribir un programa similar a un compilador en lenguaje C compilando una descripción de nivel superior en lenguaje C.
Puede configurar su entorno para la compilación de programas escritos en el lenguaje de programación C como se muestra.
# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential
El paquete libc6-dev
, a saber, la biblioteca GNU C,
aporta la biblioteca estándar de C
que es un conjunto de archivos de cabecera y rutinas de biblioteca
utilizadas por el lenguaje de programación C.
Consulte las referencias siguientes sobre C.
«info libc
» (referencia de las funciones de la biblioteca
de C)
gcc
(1) y «info gcc
»
nombre_de_cada_función_de_la_biblioteca_de_C
(3)
Kernighan & Ritchie, «The C Programming Language«, 2nd edición (Prentice Hall)
Un ejemplo simple " example.c
" se puede compilar con
una biblioteca " libm
" en un ejecutable "
run_example
" de la siguiente manera.
$ cat > example.c << EOF #include <stdio.h> #include <math.h> #include <string.h> int main(int argc, char **argv, char **envp){ double x; char y[11]; x=sqrt(argc+7.5); strncpy(y, argv[0], 10); /* prevent buffer overflow */ y[10] = '\0'; /* fill to make sure string ends with '\0' */ printf("%5i, %5.3f, %10s, %10s\n", argc, x, y, argv[1]); return 0; } EOF $ gcc -Wall -g -o run_example example.c -lm $ ./run_example 1, 2.915, ./run_exam, (null) $ ./run_example 1234567890qwerty 2, 3.082, ./run_exam, 1234567890qwerty
Aquí, se necesita «-lm
» para enlazar la biblioteca
«/usr/lib/libm.so
» del paquete libc6
para utilizar la función sqrt
(3). La biblioteca real
está ubicada en «/lib/
» con el nombre de archivo
«libm.so.6
», el cual es un enlace simbólico a
«libm-2.7.so
».
Mire el último elemento de la salida. Tiene incluso más de 10 caracteres a
pesar de tener «%10s
».
La utilización de operaciones de punteros sin comprobar los límites, como
ocurre con sprintf
(3) y strcpy
(3), no
se utilizan para evitar el desbordamiento del buffer que puede provocar
problemas desconocidos. En su lugar se utilizan
snprintf
(3) y strncpy
(3).
Flex es un generador rápido de analizadores léxicos compatible con Lex.
Puede encontrar un tutorial de flex
(1) en «info
flex
».
Se pueden encontrar muchos ejemplos sencillos en
"/usr/share/doc/flex/examples/
". [7]
Los paquetes que proporcionan un mejor y compatible Yacc son el analizador sintáctico LR o el analizador sintáctico LALR de Debian.
Puede encontrar un tutorial de bison
(1) en «info
bison
».
Puede que sea necesario que proporcione su propio
«main()
» y «yyerror()
». El método
«main()
» invoca «yyparse()
» el cual
invoca «yylex()
», que normalmente se crea con Flex.
He aquí un ejemplo para crear un sencillo programa de calculadora de terminal.
Vamos a crear example.y
:
/* calculator source for bison */ %{ #include <stdio.h> extern int yylex(void); extern int yyerror(char *); %} /* declare tokens */ %token NUMBER %token OP_ADD OP_SUB OP_MUL OP_RGT OP_LFT OP_EQU %% calc: | calc exp OP_EQU { printf("Y: RESULT = %d\n", $2); } ; exp: factor | exp OP_ADD factor { $$ = $1 + $3; } | exp OP_SUB factor { $$ = $1 - $3; } ; factor: term | factor OP_MUL term { $$ = $1 * $3; } ; term: NUMBER | OP_LFT exp OP_RGT { $$ = $2; } ; %% int main(int argc, char **argv) { yyparse(); } int yyerror(char *s) { fprintf(stderr, "error: '%s'\n", s); }
Vamos a crear example.l
:
/* calculator source for flex */ %{ #include "example.tab.h" %} %% [0-9]+ { printf("L: NUMBER = %s\n", yytext); yylval = atoi(yytext); return NUMBER; } "+" { printf("L: OP_ADD\n"); return OP_ADD; } "-" { printf("L: OP_SUB\n"); return OP_SUB; } "*" { printf("L: OP_MUL\n"); return OP_MUL; } "(" { printf("L: OP_LFT\n"); return OP_LFT; } ")" { printf("L: OP_RGT\n"); return OP_RGT; } "=" { printf("L: OP_EQU\n"); return OP_EQU; } "exit" { printf("L: exit\n"); return YYEOF; } /* YYEOF = 0 */ . { /* ignore all other */ } %%
A continuación, ejecute lo siguiente desde el símbolo del sistema para probar esto:
$ bison -d example.y $ flex example.l $ gcc -lfl example.tab.c lex.yy.c -o example $ ./example 1 + 2 * ( 3 + 1 ) = L: NUMBER = 1 L: OP_ADD L: NUMBER = 2 L: OP_MUL L: OP_LFT L: NUMBER = 3 L: OP_ADD L: NUMBER = 1 L: OP_RGT L: OP_EQU Y: RESULT = 9 exit L: exit
Lint herramientas similares pueden ayudar a análisis de código estático automático.
Indent como herramientas pueden ayudar a las revisiones humanas de código reformateando los códigos fuente de forma coherente.
Ctags como herramientas pueden ayudar a las revisiones humanas de código mediante la generación de un archivo de índice (o etiqueta) de los nombres que se encuentran en los códigos fuente.
Sugerencia | |
---|---|
Configurar tu editor favorito ( |
Tabla 12.12. Relación de las herramientas para el análisis de código estático
paquete | popularidad | tamaño | descripción |
---|---|---|---|
vim-ale
|
I:0 | 2591 | Motor asíncrono Lint para Vim 8 y NeoVim |
vim-syntastic
|
I:3 | 1379 | Trucos de comprobación sintáctica para vim |
elpa-flycheck
|
V:0, I:1 | 808 | moderna comprobación sintáctica sobre la marcha para Emacs |
elpa-relint
|
V:0, I:0 | 147 | Buscador de errores regexp de Emacs Lisp |
cppcheck-gui
|
V:0, I:1 | 7224 | herramienta para el análisis de código C/C++ (GUI) |
shellcheck
|
V:2, I:13 | 18987 | herramienta útil para scripts de shell |
pyflakes3
|
V:2, I:15 | 20 | Verificado pasivo de programas Python 3 |
pylint
|
V:4, I:20 | 2018 | comprobador de código estático Python |
perl
|
V:707, I:989 | 673 | intérprete con comprobador de código estático interno:
B::Lint (3perl) |
rubocop
|
V:0, I:0 | 3247 | Analizador de código estático Ruby |
clang-tidy
|
V:2, I:11 | 21 | Herramienta de verificación de formato de regla C++ basada en Clang |
splint
|
V:0, I:2 | 2320 | herramienta para la comprobación estática de errores de programación en C |
flawfinder
|
V:0, I:0 | 205 | herramienta que examina código fuente en C/C++ para encontrar debilidades de seguridad |
black
|
V:3, I:13 | 660 | Formateador de código Python agresivo |
perltidy
|
V:0, I:4 | 2493 | Indentador y reformateador de scripts de Perl |
indent
|
V:0, I:7 | 431 | Programa de formateo del código fuente en lenguaje C |
astyle
|
V:0, I:2 | 785 | Indentador de código fuente para C, C++, Objective-C, C# y Java |
bcpp
|
V:0, I:0 | 111 | Embellecer C(++) |
xmlindent
|
V:0, I:1 | 53 | reformateador del flujo XML |
global
|
V:0, I:2 | 1908 | Herramientas de búsqueda y exploración de código fuente |
exuberant-ctags
|
V:2, I:20 | 341 | Crea un índice de archivo de etiquetas de definiciones del código fuente |
universal-ctags
|
V:1, I:11 | 3386 | Crea un índice de archivo de etiquetas de definiciones del código fuente |
La depuración es una parte importante de las actividades de programación. Saber cómo depurar programas lo convierte en un buen usuario de Debian que puede producir informes de errores significativos.
El principal depurador en Debian es
gdb
(1) el cual permite inspeccionar un programa mientras
se ejecuta.
Instalamos gdb
y otros programas relevantes como se
muestra.
# apt-get install gdb gdb-doc build-essential devscripts
Se puede encontrar un buen tutorial de gdb
:
“info gdb
”
“Depuración con GDB” en
/usr/share/doc/gdb-doc/html/gdb/index.html
Aquí hay un ejemplo simple del uso de gdb
(1) en un
"programa
" compilado con la opción
"-g
" para generar información de depuración.
$ gdb program (gdb) b 1 # set break point at line 1 (gdb) run args # run program with args (gdb) next # next line ... (gdb) step # step forward ... (gdb) p parm # print parm ... (gdb) p parm=12 # set value to 12 ... (gdb) quit
Sugerencia | |
---|---|
Existen abreviaturas para la mayor parte de las órdenes de
|
Dado que todos los archivos binarios instalados deben eliminarse en el
sistema Debian de forma predeterminada, la mayoría de los símbolos de
depuración se eliminan en el paquete normal. Para depurar paquetes Debian
con gdb
(1), se deben instalar paquetes
*-dbgsym
(p. ej., coreutils-dbgsym
en
el caso de coreutils
). Los paquetes fuente generan
automáticamente paquetes *-dbgsym
junto con paquetes
binarios normales y esos paquetes de depuración se colocan por separado en
el archivo debian-debug. Consulte los
artículos en Debian Wiki para
obtener más información.
Si un paquete que se va a depurar no proporciona su paquete
*-dbgsym
, debe instalarlo después de reconstruirlo de la
siguiente manera.
$ mkdir /path/new ; cd /path/new $ sudo apt-get update $ sudo apt-get dist-upgrade $ sudo apt-get install fakeroot devscripts build-essential $ apt-get source package_name $ cd package_name* $ sudo apt-get build-dep ./
Si lo necesita corrija los errores.
Cuando recompile la publicación de un paquete ya existente elija una que no
exista en Debian, p. ej. añadiéndole «+debug1
» o
añadiéndole «~pre1
» como se muestra.
$ dch -i
Compila o instala los paquetes con los símbolos de depuración de la siguiente manera.
$ export DEB_BUILD_OPTIONS="nostrip noopt" $ debuild $ cd .. $ sudo debi package_name*.changes
Necesita comprobar que los archivos de órdenes del paquete y utilizar
«CFLAGS=-g -Wall
» para la compilación de binarios.
Cuando encuentre un programas que no funciona, es una buena idea al informar del error añadir información sobre las trazas de su ejecución.
El backtrace se puede obtener mediante gdb
(1) usando uno
de los siguientes enfoques:
Enfoque de los errores en GDB:
Ejecuta el programa desde GDB.
Bloquea el programa.
Escriba "bt
" en el indicador de GDB.
Primer enfoque de los errores:
Actualiza el archivo “/etc/security/limits.conf” para incluir lo siguiente:
* soft core unlimited
Escribe "ulimit -c ilimitado
" en el indicador de shell.
Ejecuta el programa desde este indicador de shell
Bloquea el programa para generar un archivo core dump.
Cargar el archivo core dump a GDB como
"gdb gdb ./program_binary core
" .
Escriba "bt
" en el indicador de GDB.
Para un bucle infinito o una situación de teclado congelado, puede forzar el
bloqueo del programa pulsando Ctrl-\
o
Ctrl-C
o ejecutando “kill -ABRT
PID
”. (Ver Sección 9.4.12, “Matando un proceso”)
Sugerencia | |
---|---|
Frecuentemente encontrará en primeras líneas « $ MALLOC_CHECK_=2 gdb hello |
Tabla 12.14. Relación de órdenes avanzadas gdb
orden | descripción de la funcionalidad de la orden |
---|---|
(gdb) hilo aplica a todos bt |
recogen trazas de todos los hilos para programas multihilo |
(gdb) bt full |
recoge los parámetros de la pila de las llamadas de función |
(gdb) thread apply all bt full |
recoge trazas y parámetros como una combinación de las opciones anteriores |
(gdb) thread apply all bt full 10 |
recoge trazas y parámetros de las 10 llamadas más recientes para eliminar información no relevante |
(gdb) set logging on |
escribe la salida del registro de gdb a un archivo (por
defecto «gdb.txt ») |
Utilice como se muestra ldd
(1) para determinar las
bibliotecas de las que depende un programa.
$ ldd /usr/bin/ls librt.so.1 => /lib/librt.so.1 (0x4001e000) libc.so.6 => /lib/libc.so.6 (0x40030000) libpthread.so.0 => /lib/libpthread.so.0 (0x40153000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Para que ls
(1) funcione en un entorno `chroot` las
bibliotecas siguientes deben estar disponibles en dicho entorno.
Consulte Sección 9.4.6, “Trazando la actividad de un programa”.
Hay varias herramientas de rastreo dinámico de llamadas disponibles en Debian. Consulta Sección 9.4, “Monitoreando, controlando e iniciando lo que hacer los programas”.
Si el programa GNOME preview1
ha recibido un error de las
X se puede ver el mensaje como se muestra.
The program 'preview1' received an X Window System error.
En este caso, puede intentar ejecutar el programa con
«--sync
», y poner un punto de ruptura en la función
«gdk_x_error
» con el fin de obtener trazas.
Existen varias herramientas de detección de fugas de memoria en Debian.
Tabla 12.15. Relación de herramientas de detección de fugas de memoria
paquete | popularidad | tamaño | descripción |
---|---|---|---|
libc6-dev
|
V:248, I:567 | 12053 | mtrace (1): funcionalidad de depuración de malloc en glibc |
valgrind
|
V:6, I:37 | 78191 | depurador y analizador de memoria |
electric-fence
|
V:0, I:3 | 73 | depurador malloc (3) |
libdmalloc5
|
V:0, I:2 | 390 | biblioteca de depuración de la asignación de memoria |
duma
|
V:0, I:0 | 296 | biblioteca para detectar desbordamientos y subdesbordamientos de búfer en programas C y C++ |
leaktracer
|
V:0, I:1 | 56 | programas C++ para trazar fugas de memoria |
Tabla 12.16. Lista de paquetes de herramientas de compilación
paquete | popularidad | tamaño | documentación |
---|---|---|---|
make
|
V:151, I:555 | 1592 | «info make » proporcionado por make-doc |
autoconf
|
V:31, I:230 | 2025 | «info autoconf » proporcionado con
autoconf-doc |
automake
|
V:30, I:228 | 1837 | «info automake » proporcionado con
automake1.10-doc |
libtool
|
V:25, I:212 | 1213 | "info libtool " proporcionado por
libtool-doc |
cmake
|
V:17, I:115 | 36607 | cmake (1) sistema make multiplataforma de código abierto |
ninja-build
|
V:6, I:41 | 428 | ninja (1) pequeño sistema de construcción más cercano en
espíritu a Make |
meson
|
V:3, I:22 | 3759 | meson (1) sistema de construcción de alta productividad
sobre ninja |
xutils-dev
|
V:0, I:9 | 1484 | imake (1), xmkmf (1), etc. |
Make es una utilidad para mantener grupos de
programas. La ejecución de make
(1) consiste en, la
lectura del archivo de reglas «Makefile
» por parte de
make
y la actualización de un objetivo si los archivos
que son necesarios han sido modificados desde la última vez o si el objetivo
no existe. La ejecución de estas actualizaciones pueden suceder de
concurrentemente.
La sintaxis del archivo de reglas es la que se muestra.
target: [ prerequisites ... ] [TAB] command1 [TAB] -command2 # ignore errors [TAB] @command3 # suppress echoing
Aquí «[TAB]
» es un código TAB. Cada línea es interpretada
por el intérprete de órdenes después de la sustitución de las
variables. Utilice «\
» al final de la línea para
continuar el archivo de órdenes. Utilice «$$
» para
incluir «$
» par los valores del entorno para el archivo
de órdenes.
Las reglas implícitas y los prerequisitos para un objetivos pueden ser escrito, por ejemplo, como se muestra.
%.o: %.c header.h
Aquí, el objetivo contiene el carácter «%
» (únicamente un
carácter). El carácter %
» encaja con cualquier cadena no
vacía que corresponda a los nombres de archivo del objetivo real. Así mismo
el prerrequisito utiliza «%
» para mostrar como se
relaciones sus nombres con los nombres del objetivo real.
Tabla 12.17. Relación de variables automáticas de make
variable automática | valor |
---|---|
$@ |
objetivo |
$< |
primer prerrequisitos |
$? |
todos los prerrequisitos nuevos |
$^ |
todos los prerequisitos |
$* |
«% » encaja la raíz en el patrón del objetivo |
Tabla 12.18. Relación de expansiones de variables de make
expansión variable | descripción |
---|---|
foo1 := bar |
expansión por única vez |
foo2 = bar |
expansión recursiva |
foo3 += bar |
anexar |
Ejecute «make -p -f/dev/null
»para ver las reglas internas
automática.
Autotools es un conjunto de herramientas de programación diseñadas para ayudar a que los paquetes de código fuente sean portables a muchos sistemas Unix-like.
Autoconf es una herramienta para generar
scripts de shell "configure
" desde
"configure.ac
".
"configure
" se usa más adelante para producir
"Makefile
" a partir de la plantilla
"Makefile.in
".
Automake es una herramienta para producir
"Makefile.in
" a partir de
"Makefile.am
".
Libtool es un script de shell para abordar el problema de la portabilidad del software al compilar bibliotecas compartidas a partir del código fuente.
Aviso | |
---|---|
Cuando compile programas y los instale no sobreescriba los archivos del sistema. |
Debian no modifica los archivos en «/usr/local/
» o
«/opt
». Así que si compila un programa desde el código
fuente, instalarlo en «/usr/local/
» para que no
interfiera con Debian.
$ cd src $ ./configure --prefix=/usr/local $ make # this compiles program $ sudo make install # this installs the files in the system
Si se tiene el código original, se utiliza
autoconf
(1)/automake
(1) y se recuerda
como se configuró, ejecute lo siguiente para realizar la desinstalación del
programa.
$ ./configure all-of-the-options-you-gave-it
$ sudo make uninstall
Otra manera, si está totalmente seguro de que la instalación solo únicamente
archivos en «/usr/local/
» y no hay nada importante allí,
puede borrar todo su contenido como se muestra.
# find /usr/local -type f -print0 | xargs -0 rm -f
Si no estás seguro de dónde se instalaron los archivos, puede considerar
usar checkinstall
(8) del paquete
checkinstall
, que proporcionará una ruta de
desinstalación clara. Ahora admite la creación de paquetes Debian con la
opción "-D
".
El sistema de creación del software ha ido evolucionando:
Autotools en la parte superior de Make ha sido el estándar de facto para la infraestructura de compilación portátil desde 1990. Esto es extremadamente lento.
CMake lanzado inicialmente en el 2000 mejoró la velocidad significativamente pero fue construido originalmente sobre el inherentemente lento Make. (Ahora Ninja puede ser tu backend).
Ninja, lanzado inicialmente en 2012, está destinado a sustituir a Make para mejorar aún más la velocidad de la compilación y está diseñado para que tus archivos sean generados por un sistema de compilación de nivel superior.
Meson lanzado inicialmente en 2013 es el nuevo, popular y rápido sistema de compilación de nivel superior que utiliza Ninja como backend.
Consulta los documentos que se encuentran en "El sistema de construcción Meson" y "El sistema de construcción Ninja".
Se pueden crear páginas web dinámicas básicas como se muestra.
Las consultas se presentan al navegador del usuario utilizando formularios HTML.
Rellenando y pulsado sobre las entradas del formulario se envía la cadena URL con los parámetros codificados desde el navegador al servidor web.
«https://www.foo.dom/cgi-bin/program.pl?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
»
«https://www.foo.dom/cgi-bin/program.py?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
»
«https://www.foo.dom/program.php?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
»
«%nn
» en la URL se sustituye por el carácter hexadecimal
que tiene el valor nn
.
Las variables de entorno se asignan como: «QUERY_STRING=«VAR1=VAL1
VAR2=VAL2 VAR3=VAL3«
».
Un programa CGI (independientemente de su
extensión «programa.*
») en un servidor web se ejecuta a
si mimo con la variable de entorno «$QUERY_STRING
».
La salida
de un programa CGI se envía al servidor web y
se representa como una página web dinámica.
Por seguridad es mejor no realizar de forma manual o de otras formas la gestión de análisis de los parámetros CGI. Existen módulos para ello en Perl y Python. PHP tiene dicha funcionalidad. Cuando se necesita almacenar información del usuario, se utilizan las cookies HTTP cookies. Cuando se necesita procesar información en el lado del cliente, normalmente se utiliza Javascript.
Para mayor información, ver Interfaz de Pasarela Común (Common Gateway Interface), La Fundación de Software Apache (The Apache Software Foundation) y JavaScript.
Buscar "tutorial CGI" en Google escribiendo la URL codificada https://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial directamente en la dirección del navegador es una buena forma de ver el script CGI en acción en el servidor de Google.
Existen aplicaciones para convertir código fuente de un lenguaje a otro.
Tabla 12.19. Relación de herramientas de traducción de código fuente
paquete | popularidad | tamaño | palabra clave | descripción |
---|---|---|---|---|
perl
|
V:707, I:989 | 673 | AWK→PERL | convertir código fuente de AWK a PERL: a2p (1) |
f2c
|
V:0, I:3 | 442 | FORTRAN→C | convierte código fuente de FORTRAN 77 a C/C++: f2c (1) |
intel2gas
|
V:0, I:0 | 178 | intel→gas | convierte de NASM (formato Intel) a GAS (Ensamblador GNU) |
Si quiere hacer un paquete Debian, lea lo siguiente.
Capítulo 2, Gestión de paquetes Debian para comprender los fundamentos del sistema de paquetes
Sección 2.7.13, “Portar un paquete a un sistema estable” para comprender lo fundamental del proceso de portabilidad
Sección 9.11.4, “Sistemas chroot” para comprender los fundamentos de la técnica de chroot
debuild
(1), y sbuild
(1)
Sección 12.5.2, “Depurando un paquete Debian” para la recompilación con la finalidad de la depuración
Guía de Mantenedores Debian (Guide
for Debian Maintainers) (el paquete debmake-doc
)
Referencia para desarrolladores
Debian (el paquete developers-reference
).
Manual Directrices de Debian (en
el paquete debian-policy
)
Existen paquetes que ayudan al empaquetado como debmake
,
dh-make
, dh-make-perl
, etc.