Indice
Vengono forniti in questo capitolo alcune informazioni base da cui partire per imparare a programmare su un sistema Debian abbastanza da seguire il codice sorgente impacchettato. Quello che segue è un elenco dei pacchetti importanti per la programmazione e dei corrispettivi pacchetti di documentazione.
Guide di riferimento in linea sono disponibili digitando "man
nome
" dopo aver installato i pacchetti manpages
e manpages-dev
. Le guide di riferimento in linea per gli
strumenti GNU sono disponibili digitando "info
nome_programma
", dopo aver installato i pertinenti pacchetti di
documentazione. Può essere necessario includere gli archivi
"contrib
e non-free
, oltre
all'archivio main
, dato che alcune documentazioni GFDL
non sono considerate conformi alle DFSG.
Please consider to use version control system tools. See Sezione 10.5, «Git».
![]() |
Avvertimento |
---|---|
Non usare " |
![]() |
Attenzione |
---|---|
I programmi software compilati direttamente dai sorgenti andrebbero
installati in " |
![]() |
Suggerimento |
---|---|
Esempi di codice per creare la "Canzone 99 bottiglie di birra" dovrebbe dare buone idee per praticamente tutti i linguaggi di programmazione. |
Uno script di shell è un file di testo con il bit di esecuzione impostato e contiene i comandi nel formato seguente.
#!/bin/sh ... command lines
La prima riga specifica l'interprete di shell che legge ed esegue il contenuto di questo file.
Leggere script di shell è il modo migliore per capire come funzioni un sistema *nix. In questa sezione vengono forniti alcune nozioni di riferimento e promemoria per la programmazione di shell. Vedere "Errori in shell" (http://www.greenend.org.uk/rjk/2001/04/shell.html) per imparare dagli errori.
A differenza della modalità interattiva della shell (vedere Sezione 1.5, «Il semplice comando di shell» e Sezione 1.6, «Elaborazione di testo stile Unix»), gli script di shell usano spesso parametri, costrutti condizionali e cicli.
Many system scripts may be interpreted by any one of POSIX shells (see Tabella 1.13, «Elenco di programmi shell»).
The default non-interactive POSIX shell "/bin/sh
" is a
symlink pointing to /usr/bin/dash
and used by many system
programs.
The default interactive POSIX shell is /usr/bin/bash
.
Evitare di scrivere uno script di shell con bashismi o zshismi per renderlo portabile tra tutte le shell
POSIX. Si può controllare uno script con
checkbashisms
(1).
Tabella 12.1. Elenco di bashismi tipici
Buono: POSIX | Da evitare: bashismo |
---|---|
if [ "$pippo" = "$pluto" ] ; then … |
if [ "$pippo" == "$pluto" ] ; then … |
diff -u file.c.orig file.c |
diff -u file.c{.orig,} |
mkdir /pippopluto /pippopaperino |
mkdir /pippo{pluto,paperino} |
nomefunzione() { … } |
function nomefunzione() { … } |
formato ottale: "\377 " |
formato esadecimale: "\xff " |
Il comando "echo
" deve essere usato con le precauzioni
seguenti dato che la sua implementazione è diversa negli svariati comandi
interni della shell ed esterni.
Evitare l'uso di qualsiasi opzione di comando tranne
"-n
".
Evitare l'uso di sequenze di escape nelle stringhe dato che la loro gestione è variabile.
![]() |
Nota |
---|---|
Sebbene l'opzione " |
![]() |
Suggerimento |
---|---|
Se è necessario inserire sequenze di escape nella stringa in output, usare
il comando " |
Negli script di shell vengono spesso usati parametri speciali.
Tabella 12.2. Elenco di parametri di shell
parametro di shell | valore |
---|---|
$0 |
nome della shell o dello script di shell |
$1 |
primo (1°) argomento di shell |
$9 |
nono (9°) argomento di shell |
$# |
numero di parametri posizionali |
"$*" |
"$1 $2 $3 $4 … " |
"$@" |
"$1" "$2" "$3" "$4" … |
$? |
stato d'uscita del comando più recente |
$$ |
PID dello script di shell |
$! |
PID del compito sullo sfondo avviato più recentemente |
Le nozioni base da ricordare riguardanti la espansione dei parametri sono le seguenti.
Tabella 12.3. Elenco di espansioni di parametri di shell
forma della espressione con parametri | valore se var è impostata |
valore se var non è impostata |
---|---|---|
${var:-stringa} |
"$var " |
"stringa " |
${var:+stringa} |
"stringa " |
"null " |
${var:=stringa} |
"$var " |
"stringa " (ed esegue "var=stringa ") |
${var:?string} |
"$var " |
invia con echo "stringa " allo stderr (ed esce con stato di errore) |
I due punti ":
" in tutti gli operatori nell'elenco
precedente sono di fatto opzionali.
con ":
" l'operatore =
controlla che il suo operando esista e
sia non nullo
senza ":
" l'operatore
= controlla solo che il suo operando esista
Tabella 12.4. Elenco di sostituzioni chiave di parametri di shell
forma della sostituzione di parametri | risultato |
---|---|
${var%suffisso} |
rimuove il più piccolo modello di suffisso |
${var%%suffisso} |
rimuove il più grande modello di suffisso |
${var#prefisso} |
rimuove il più piccolo modello di prefisso |
${var##prefisso} |
rimuove il più grande modello di prefisso |
Ogni comando restituisce uno stato di uscita che può essere usato in costrutti condizionali.
Successo: 0 ("Vero")
Errore: non 0 ("Falso")
![]() |
Nota |
---|---|
"0" nel contesto condizionale della shell significa "Vero", mentre "0" nel contesto condizionale in C significa "Falso". |
![]() |
Nota |
---|---|
" |
Le espressioni condizionali di base che è bene ricordare sono le seguenti.
"comando &&
se_successo_esegue_anche_questo_comando ||
true
"
"comando ||
se_non_successo_esegue_anche_questo_comando ||
true
"
Una porzione su più righe di script come la seguente
if [ conditional_expression ]; then if_success_run_this_command else if_not_success_run_this_command fi
In questo caso il "|| true
" finale era necessario per
assicurare che lo script non termini accidentalmente a tale riga quando la
shell è invocata con l'opzione "-e
".
Tabella 12.5. Elenco di operatori per paragonare file in espressioni condizionali
equazione | condizione perché venga restituito il valore logico "vero" |
---|---|
-e file |
file esiste |
-d file |
file esiste ed è una directory |
-f file |
file esiste ed è un file regolare |
-w file |
file esiste ed è scrivibile |
-x file |
file esiste ed è eseguibile |
file1 -nt file2 |
file1 è più recente di file2 (data di modifica) |
file1 -ot file2 |
file1 è più vecchio di file2 (data di modifica) |
file1 -ef file2 |
file1 e file2 sono sullo stesso device e stesso numero inode |
Tabella 12.6. Elenco di operatori per paragonare stringhe in espressioni condizionali
equazione | condizione perché venga restituito il valore logico "vero" |
---|---|
-z str |
la lunghezza di str è zero |
-n str |
la lunghezza di str è diversa da zero |
str1 = str2 |
str1 e str2 sono uguali |
str1 != str2 |
str1 e str2 non sono uguali |
str1 < str2 |
se ordinate, str1 viene prima di str2 (dipendente dalla localizzazione) |
str1 > str2 |
se ordinate, str1 viene dopo di str2 (dipendente dalla localizzazione) |
Gli operatori aritmetici di comparazione
di interi nelle espressioni condizionali sono "-eq
",
"-ne
", "-lt
",
"-le
", "-gt
" e
"-ge
".
Ci sono diverse espressioni per cicli usabili nella shell POSIX.
"for x in pippo1 pippo2 … ; do comando ; done
" ripete il
ciclo assegnando gli elementi nell'elenco "pippo1 pippo2
…
" alla variabile "x
" ed eseguendo
"comando
".
"while condizione ; do comando ; done
" ripete
"comando
" fintanto che "condizione
" è
vera.
"until condizione ; do comando ; done
" ripete
"comando
" fintanto che "condition
" è
non vera.
"break
" permette di uscire dal ciclo.
"continue
" permette di riprendere dalla successiva
iterazione del ciclo.
![]() |
Suggerimento |
---|---|
L'iterazione numerica in stile linguaggio C può
essere realizzata usando |
![]() |
Suggerimento |
---|---|
Vedere Sezione 9.4.9, «Ripetere un comando su diversi file». |
Some popular environment variables for the normal shell command prompt may not be available under the execution environment of your script.
For "$USER
", use "$(id -un)
"
For "$UID
", use "$(id -u)
"
For "$HOME
", use "$(getent passwd "$(id -u)"|cut
-d ":" -f 6)
" (this works also on Sezione 4.5.2, «La moderna gestione centralizzata del sistema»)
A grandi linee la shell elabora uno script nel modo seguente.
La shell legge una riga.
La shell raggruppa parte della riga come un unico
elemento se è racchiusa in "…"
o
'…'
.
La shell spezza le altre parti della riga in elementi in base ai caratteri seguenti.
Spazi bianchi: spazio
tabulazione <a capo>
Metacharacters: | ; & ( )
La shell controlla, per ciascun elemento non racchiuso tra
"…"
o '…'
, la presenza di parole riservate per regolare il proprio
comportamento.
Parole riservate: if then elif
else fi for in while unless do done case esac
La shell espande gli alias se non sono
racchiusi in "…"
o '…'
.
La shell espande il carattere tilde se
non è racchiuso in "…"
o '…'
.
"~
" → directory home dell'utente attuale
"~utente
" → directory home di
utente
La shell espande parametri nei loro
valori, se non sono racchiusi in '…'
.
Parametro:
"$PARAMETRO
" o "${PARAMETRO}
"
La shell espande sostituzioni di comandi,
se non sono racchiuse in '…'
.
"$( comando )
" → output di "comando
"
"` command `
" → output di "comando
"
La shell espande glob di nomi percorso
nei nomi di file corrispondenti, se non sono racchiusi in
"…"
o '…'
.
*
→ qualsiasi carattere
?
→ un carattere
[…]
→ uno qualunque dei caratteri in
"…
"
La shell cerca comando tra le cose seguenti e lo esegue.
Definizione di funzione
comando interno
file eseguibile in
"$PATH
"
La shell si sposta alla riga seguente e ripete nuovamente questo processo dall'inizio di questa sequenza.
Virgolette singole all'interno di virgolette doppie non hanno alcun effetto.
L'esecuzione di "set -x
" nella shell o l'invocazione
della shell con l'opzione "-x
" fanno sì che la shell
stampi tutti i comandi eseguiti. Ciò è piuttosto utile per il debug.
Per far sì che il proprio programma di shell sia il più portabile possibile tra i sistemi Debian, è una buona idea limitare i programmi di utilità a quelli forniti dai pacchetti essenziali.
"aptitude search ~E
" elenca i pacchetti essenziali.
"dpkg -L nome_pacchetto |grep
'/man/man.*/'
" elenca le pagine man per i comandi forniti dal
pacchetto nome_pacchetto
.
Tabella 12.7. Elenco di pacchetti contenenti piccoli programmi di utilità per script di shell
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
dash
|
V:894, I:994 | 222 | small and fast POSIX-compliant shell for sh |
coreutils
|
V:892, I:999 | 17372 | Utilità GNU di base |
grep
|
V:820, I:999 | 1118 | GNU grep , egrep and
fgrep |
sed
|
V:814, I:999 | 912 | GNU sed |
mawk
|
V:392, I:997 | 242 | small and fast awk |
debianutils
|
V:921, I:999 | 213 | utilità varie specifiche di Debian |
bsdutils
|
V:681, I:999 | 402 | utilità di base per 4.4BSD-Lite |
bsdextrautils
|
V:228, I:305 | 389 | extra utilities from 4.4BSD-Lite |
moreutils
|
V:11, I:36 | 237 | utilità Unix aggiuntive |
![]() |
Suggerimento |
---|---|
Although |
See Sezione 1.6, «Elaborazione di testo stile Unix» for examples.
Tabella 12.8. List of interpreter related packages
pacchetto | popcon | dimensione | documentazione |
---|---|---|---|
dash
|
V:894, I:994 | 222 | sh: small and fast POSIX-compliant shell for
sh |
bash
|
V:789, I:999 | 6465 | sh: "info bash " provided by
bash-doc |
mawk
|
V:392, I:997 | 242 | AWK: small and fast awk |
gawk
|
V:340, I:425 | 2456 | AWK: "info gawk " provided by
gawk-doc |
perl
|
V:600, I:991 | 705 | Perl: perl (1) and html pages
provided by perl-doc and perl-doc-html |
libterm-readline-gnu-perl
|
V:2, I:29 | 379 | Perl extension for the GNU ReadLine/History Library:
perlsh (1) |
libreply-perl
|
V:0, I:0 | 170 | REPL for Perl: reply (1) |
libdevel-repl-perl
|
V:0, I:0 | 237 | REPL for Perl: re.pl (1) |
python3
|
V:675, I:910 | 90 | Python: python3 (1) and html
pages provided by python3-doc |
tcl
|
V:27, I:342 | 22 | Tcl: tcl (3) and detail manual
pages provided by tcl-doc |
tk
|
V:26, I:334 | 22 | Tk: tk (3) and detail manual
pages provided by tk-doc |
ruby
|
V:98, I:288 | 35 | Ruby: ruby (1),
erb (1), irb (1),
rdoc (1), ri (1) |
When you wish to automate a task on Debian, you should script it with an interpreted language first. The guide line for the choice of the interpreted language is:
Use dash
, if the task is a simple one which combines CLI
programs with a shell program.
Use python3
, if the task isn't a simple one and you are
writing it from scratch.
Use perl
, tcl
,
ruby
, ... if there is an existing code using one of these
languages on Debian which needs to be touched up to do the task.
If the resulting code is too slow, you can rewrite only the critical portion for the execution speed in a compiled language and call it from the interpreted language.
Most interpreters offer basic syntax check and code tracing functionalities.
“dash -n script.sh” - Syntax check of a Shell script
“dash -x script.sh” - Trace a Shell script
“python -m py_compile script.py” - Syntax check of a Python script
“python -mtrace --trace script.py” - Trace a Python script
“perl -I ../libpath -c script.pl” - Syntax check of a Perl script
“perl -d:Trace script.pl” - Trace a Perl script
For testing code for dash
, try Sezione 9.1.4, «Readline wrapper» which accommodates
bash
-like interactive environment.
For testing code for perl
, try REPL environment for Perl
which accommodates Python-like REPL (=READ + EVAL + PRINT + LOOP)
environment for Perl.
The shell script can be improved to create an attractive GUI program. The
trick is to use one of so-called dialog programs instead of dull interaction
using echo
and read
commands.
Tabella 12.9. List of dialog programs
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
x11-utils
|
V:180, I:589 | 712 | xmessage (1): mostra un messaggio o richiesta in una
finestra (X) |
whiptail
|
V:238, I:996 | 70 | mostra riquadri di dialogo amichevoli da script di shell (newt) |
dialog
|
V:14, I:114 | 1222 | mostra riquadri di dialogo amichevoli da script di shell (ncurses) |
zenity
|
V:76, I:391 | 167 | display graphical dialog boxes from shell scripts (GTK) |
ssft
|
V:0, I:0 | 75 | Shell Scripts Frontend Tool, strumento per frontend per script di shell (contenitore per zenity, kdialog, e dialog con gettext) |
gettext
|
V:48, I:295 | 5843 | "/usr/bin/gettext.sh ": traduce messaggi |
Here is an example of GUI program to demonstrate how easy it is just with a shell script.
This script uses zenity
to select a file (default
/etc/motd
) and display it.
GUI launcher for this script can be created following Sezione 9.4.10, «Avviare un programma dalla GUI».
#!/bin/sh -e # Copyright (C) 2021 Osamu Aoki <osamu@debian.org>, 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
This kind of approach to GUI program with the shell script is useful only for simple choice cases. If you are to write any program with complexities, please consider writing it on more capable platform.
In order to process data, sh
needs to spawn sub-process
running cut
, grep
,
sed
, etc., and is slow. On the other hand,
perl
has internal capabilities to process data, and is
fast. So many system maintenance scripts on Debian use
perl
.
Let's think following one-liner AWK script snippet and its equivalents in Perl.
awk '($2=="1957") { print $3 }' |
Ciò equivale ad una qualsiasi delle righe seguenti.
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' |
L'ultima è una sorta di indovinello; sfrutta le seguenti caratteristiche di Perl.
Gli spazi bianchi sono opzionali.
Esiste una conversione automatica da numero a stringa.
Perl execution tricks via command line options:
perlrun
(1)
Perl special variables: perlvar
(1)
This flexibility is the strength of Perl. At the same time, this allows us to create cryptic and tangled codes. So be careful.
For more crazy Perl scripts, Perl Golf may be interesting.
Tabella 12.10. List of compiler related packages
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
gcc
|
V:152, I:584 | 45 | GNU C compiler |
libc6-dev
|
V:248, I:601 | 13480 | GNU C Library: Development Libraries and Header Files |
g++
|
V:60, I:511 | 15 | GNU C++ compiler |
libstdc++-10-dev
|
V:29, I:166 | 17568 | GNU Standard C++ Library v3 (development files) |
cpp
|
V:325, I:756 | 42 | GNU C preprocessor |
gettext
|
V:48, I:295 | 5843 | GNU Internationalization utilities |
glade
|
V:0, I:7 | 1730 | GTK User Interface Builder |
valac
|
V:0, I:6 | 698 | C# like language for the GObject system |
flex
|
V:8, I:86 | 1279 | LEX-compatible fast lexical analyzer generator |
bison
|
V:9, I:95 | 3111 | YACC-compatible parser generator |
susv2
|
I:0 | 16 | scarica le specifiche "The Single UNIX Specifications v2" |
susv3
|
I:0 | 16 | scarica le specifiche "The Single UNIX Specifications v3" |
golang
|
I:20 | 12 | Go programming language compiler |
rustc
|
V:2, I:12 | 9018 | Rust systems programming language |
haskell-platform
|
I:5 | 12 | Standard Haskell libraries and tools |
gfortran
|
V:10, I:90 | 16 | GNU Fortran 95 compiler |
fpc
|
I:3 | 122 122 | Free Pascal |
Here, Sezione 12.3.3, «Flex - un Lex migliorato» and Sezione 12.3.4, «Bison - Yacc migliorato» are included to indicate how compiler-like program can be written in C language by compiling higher level description into C language.
Si può impostare l'ambiente appropriato per compilare programmi scritti nel linguaggio di programmazione C nel modo seguente.
# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential
Il pacchetto libc6-dev
, cioè la libreria GNU C, fornisce
la libreria standard C che è una
raccolta di file header e routine di libreria usati dal linguaggio di
programmazione C.
Vedere come documenti di riferimento per C i seguenti.
"info libc
" (documento di riferimento per le funzioni
della libreria C)
gcc
(1) e "info gcc
"
ogni_nome_di_funzione_della_libreria_C
(3)
Kernighan & Ritchie, "The C Programming Language", 2nd edition (Prentice Hall)
Un semplice esempio "esempio.c
" può essere compilato con
una libreria "libm
" in un eseguibile
"eseg_esempio
" nel modo seguente.
$ 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
In questo esempio, l'uso di "-lm
" è necessario per fare
il link alla libreria "/usr/lib/libm.so
" nel pacchetto
libc6
per sqrt
(3). La libreria reale è
in "/lib/
" con nome file "libm.so.6
",
che è un collegamento simbolico a "libm-2.7.so
".
Si guardi l'ultimo elemento nel testo di output: ci sono più di 10 caratteri
anche se è stato specificato "%10s
".
L'uso di funzioni che operano su puntatori di memoria senza controlli sui
limiti, come sprintf
(3) e strcpy
(3) è
deprecato per prevenire exploit di tipo buffer overflow che sfruttano gli
effetti di superamento dei limiti di grandezza dei dati.
Flex è un veloce generatore di analizzatori lessicali compatibile con Lex.
Un tutorial per flex
(1) viene fornito da "info
flex
".
È necessario fornire i propri "main()
" e
"yywrap()
". Altrimenti il proprio programma flex dovrebbe
apparire così per compilare senza una libreria. Questo è dovuto al fatto che
"yywrap
" è una macro e "%option main
"
abilita implicitamente "%option noyywrap
".
%option main %% .|\n ECHO ; %%
In alternativa si può compilare con l'opzione per linker "
-lfl
" alla fine della propria riga di comando
cc
(1) (come "-ll
" per
AT&T-Lex). In questo caso non è necessario usare
"%option
".
Svariati pacchetti Debian forniscono un generatore di parser LR lookahead o parser LALR combatibile con Yacc.
Un tutorial per bison
(1) viene fornito da "info
bison
".
È necessario fornire i propri "main()
" e
"yyerror()
". "main()
" chiama
"yyparse()
" che a sua volta chiama
"yylex()
", solitamente creato con Flex.
%% %%
Lint like tools can help automatic static code analysis.
Indent like tools can help human code reviews by reformatting source codes consistently.
Ctags like tools can help human code reviews by generating an index (or tag) file of names found in source codes.
![]() |
Suggerimento |
---|---|
Configuring your favorite editor ( |
Tabella 12.12. Elenco di strumenti per l'analisi statica del codice
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
vim-ale
|
I:0 | 2022 | Asynchronous Lint Engine for Vim 8 and NeoVim |
vim-syntastic
|
I:3 | 1240 | Syntax checking hacks for vim |
elpa-flycheck
|
V:0, I:1 | 792 | modern on-the-fly syntax checking for Emacs |
elpa-relint
|
V:0, I:0 | 133 | Emacs Lisp regexp mistake finder |
cppcheck-gui
|
V:0, I:1 | 6099 | tool for static C/C++ code analysis (GUI) |
shellcheck
|
V:2, I:10 | 15452 | lint tool for shell scripts |
pyflakes3
|
V:1, I:15 | 23 | passive checker of Python 3 programs |
pylint
|
V:3, I:16 | 1580 | strumento di controllo statico del codice Python |
perl
|
V:600, I:991 | 705 | interprete con controllore interno statico del codice:
B::Lint (3perl) |
rubocop
|
V:0, I:0 | 2390 | Ruby static code analyzer |
clang-tidy
|
V:1, I:7 | 22 | clang-based C++ linter tool |
splint
|
V:0, I:4 | 2320 | strumento per controllare staticamente la presenza di bug in programmi C |
flawfinder
|
V:0, I:0 | 181 | strumento per esaminare codice sorgente C/C++ e per cercare punti deboli per la sicurezza |
black
|
V:1, I:5 | 506 | uncompromising Python code formatter |
perltidy
|
V:0, I:5 | 2101 | Perl script indenter and reformatter |
indent
|
V:0, I:11 | 425 | C language source code formatting program |
astyle
|
V:0, I:3 | 761 | Source code indenter for C, C++, Objective-C, C#, and Java |
bcpp
|
V:0, I:0 | 110 | C(++) beautifier |
xmlindent
|
V:0, I:1 | 53 | XML stream reformatter |
global
|
V:0, I:3 | 1896 | Source code search and browse tools |
exuberant-ctags
|
V:4, I:31 | 349 | build tag file indexes of source code definitions |
Debug is important part of programming activities. Knowing how to debug programs makes you a good Debian user who can produce meaningful bug reports.
Lo strumento di debug principale in Debian è
gdb
(1) che permette di ispezionare un programma mentre
viene eseguito.
Installare gdb
e i programmi correlati nel modo seguente.
# apt-get install gdb gdb-doc build-essential devscripts
Good tutorial of gdb
can be found:
“info gdb
”
“Debugging with GDB” in
/usr/share/doc/gdb-doc/html/gdb/index.html
Here is a simple example of using gdb
(1) on a
"program
" compiled with the "-g
"
option to produce debugging information.
$ 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
![]() |
Suggerimento |
---|---|
Molti comandi |
Since all installed binaries should be stripped on the Debian system by
default, most debugging symbols are removed in the normal package. In order
to debug Debian packages with gdb
(1),
*-dbgsym
packages need to be installed
(e.g. coreutils-dbgsym
in the case of
coreutils
). The source packages generate
*-dbgsym
packages automatically along with normal binary
packages and those debug packages are placed separately in debian-debug archive. Please refer to articles on Debian Wiki for more
information.
If a package to be debugged does not provide its *-dbgsym
package, you need to install it after rebuilding it by the following.
$ 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 ./
Correggere i bug se necessario.
Spostare la versione del pacchetto ad una che non crei conflitti con le
versioni ufficiali di Debian, ad esempio una che termini con
"+debug1
" quando si ricompilano versioni di cui esiste un
pacchetto, o una che termini con "~pre1
" quando si
ricompilano versioni non ancora rilasciate in pacchetti nel modo seguente.
$ dch -i
Compilare ed installare i pacchetti con i simboli di debug nel modo seguente.
$ export DEB_BUILD_OPTIONS="nostrip noopt" $ debuild $ cd .. $ sudo debi package_name*.changes
È necessario controllare gli script di compilazione del pacchetto ed
assicurarsi di usare "CFLAGS=-g -Wall
" per la
compilazione di binari.
Quando un programma va in crash, è una buona idea inviare un segnalazione di bug riportando le informazioni di backtrace.
The backtrace can be obtained by gdb
(1) using one of the
following approaches:
Crash-in-GDB approach:
Run the program from GDB.
Crash the program.
Type "bt
" at the GDB prompt.
Crash-first approach:
Update the “/etc/security/limits.conf” file to include the following:
* soft core unlimited
Type "ulimit -c unlimited
" to the shell prompt.
Run the program from this shell prompt.
Crash the program to produce a core dump file.
Load the core dump file to GDB as
"gdb gdb ./program_binary core
" .
Type "bt
" at the GDB prompt.
For infinite loop or frozen keyboard situation, you can force to crash the
program by pressing Ctrl-\
or Ctrl-C
or executing “kill -ABRT PID
”. (See
Sezione 9.4.12, «Uccidere un processo»)
![]() |
Suggerimento |
---|---|
Spesso si vede un backtrace in cui una o più delle prime righe sono in
" $ MALLOC_CHECK_=2 gdb hello |
Tabella 12.14. Elenco di comandi gdb avanzati
comando | descrizione degli scopi del comando |
---|---|
(gdb) thread apply all bt |
ottenere un backtrace per tutti i thread di un programma multi-thread |
(gdb) bt full |
ottenere i parametri nello stack delle chiamate di funzione |
(gdb) thread apply all bt full |
ottenere un backtrace e parametri: combinazione delle due opzioni precedenti |
(gdb) thread apply all bt full 10 |
ottenere un backtrace e i parametri per le prime dieci chiamate nello stack per eliminare l'output irrilevante |
(gdb) set logging on |
scrivere un registro dell'output di gdb in un file (il
file predefinito è "gdb.txt ") |
Per scoprire le dipendenze di un programma da librerie, usare
ldd
(1) nel modo seguente.
$ ldd /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)
Affinché ls
(1) funzioni in un ambiente "chroot", le
librerie in questione devono essere disponibili nell'ambiente "chroot".
Vedere Sezione 9.4.6, «Tenere traccia delle attività di un programma».
There are several dynamic call tracing tools available in Debian. See Sezione 9.4, «Monitorare, controllare ed avviare l'attività dei programmi».
Se un programma gnome preview1
ha ricevuto un errore X,
si dovrebbe leggere un messaggio del tipo seguente.
The program 'preview1' received an X Window System error.
Se ciò avviene, si può provare ad eseguire il programma con
"--sync
" ed interrompere alla funzione
"gdk_x_error
" per ottenere un backtrace.
In Debian sono disponibili svariati strumenti di rilevazione di memory leak.
Tabella 12.15. Elenco di strumenti per rilevazione di memory leak
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
libc6-dev
|
V:248, I:601 | 13480 | mtrace (1): funzionalità di debug malloc in glibc |
valgrind
|
V:6, I:44 | 77249 | strumento di debug e profilazione per la memoria |
electric-fence
|
V:0, I:5 | 72 | strumento di debug malloc (3) |
libdmalloc5
|
V:0, I:3 | 393 | libreria per il debug dell'allocazione di memoria |
duma
|
V:0, I:0 | 293 | library to detect buffer overruns and under-runs in C and C++ programs |
leaktracer
|
V:0, I:2 | 57 | tracciatore di memory leak per programmi C++ |
Tabella 12.16. List of build tool packages
pacchetto | popcon | dimensione | documentazione |
---|---|---|---|
make
|
V:141, I:591 | 1592 | "info make " fornito da make-doc |
autoconf
|
V:28, I:270 | 2033 | "info autoconf " fornito da
autoconf-doc |
automake
|
V:27, I:268 | 1836 | "info automake " fornito da
automake1.10-doc |
libtool
|
V:22, I:254 | 1198 | "info libtool " provided by libtool-doc |
cmake
|
V:16, I:117 | 26395 | cmake (1) cross-platform, open-source make system |
ninja-build
|
V:4, I:30 | 347 | ninja (1) small build system closest in spirit to Make |
meson
|
V:2, I:18 | 3213 | meson (1) high productivity build system on top of
ninja |
xutils-dev
|
V:1, I:11 | 1466 | imake (1), xmkmf (1), ecc. |
Make è un'utilità per mantenere gruppi di
programmi. Quando make
(1) viene eseguito legge il file di
regole, "Makefile
" e aggiorna il file target se dipende
da file prerequisiti che sono stati modificati dall'ultima volta che esso
stesso è stato modificato oppure se il file target non esiste. L'esecuzione
di questi aggiornamenti può avvenire in modo concorrente.
La sintassi del file di regole è la seguente.
target: [ prerequisites ... ] [TAB] command1 [TAB] -command2 # ignore errors [TAB] @command3 # suppress echoing
Qui "[TAB]
è il codice di TAB. Ciascuna riga è
interpretata dalla shell dopo la sostituzione delle variabili di make. Usare
"\
" alla fine di una riga per continuare lo script. Usare
"$$
" per inserire "$
" per valori di
ambiente per uno script di shell.
Regole implicite per il target ed i prerequisiti possono essere scritte, per esempio, nel modo seguente.
%.o: %.c header.h
In questo caso il target contiene il carattere "%
"
(esattamente un carattere). Il "%
" fa corrispondenza con
qualsiasi sottostringa non vuota nei nomi di file dei target
effettivi. Similmente i prerequisiti usano "%
" per
mostrare come i loro nomi trovino corrispondenza nei nomi dei target
effettivi.
Tabella 12.17. Elenco di variabili automatiche di make
variabile automatica | valore |
---|---|
$@ |
target |
$< |
primo prerequisito |
$? |
tutti i prerequisiti più recenti |
$^ |
tutti i prerequisiti |
$* |
"% " nome base con corrispondenza con il modello target |
Tabella 12.18. Elenco di espansioni delle variabili di make
espansione di variabile | descrizione |
---|---|
pippo1 := pluto |
espansione valida una volta sola |
pippo2 = pluto |
espansione ricorsiva |
pippo3 += pluto |
accoda |
Eseguire "make -p -f/dev/null
" per vedere le regole
interne automatiche.
Autotools is a suite of programming tools designed to assist in making source code packages portable to many Unix-like systems.
Autoconf is a tool to produce a shell script
"configure
" from "configure.ac
".
"configure
" is used later to produce
"Makefile
" from "Makefile.in
"
template.
Automake is a tool to produce
"Makefile.in
" from "Makefile.am
".
Libtool is a shell script to address the software portability problem when compiling shared libraries from source code.
![]() |
Avvertimento |
---|---|
Non sovrascrivere mai file di sistema quando si installano programmi compilati in proprio. |
Debian non tocca i file in "/usr/local/
" o
"/opt
". Perciò se si compila un programma dai sorgenti,
installarlo in "/usr/local/
" in modo che non interferisca
con Debian.
$ cd src $ ./configure --prefix=/usr/local $ make # this compiles program $ sudo make install # this installs the files in the system
Se si hanno i sorgenti originali e questi usano
autoconf
(1)/automake
(1), e se ci si
ricorda la configurazione usata, eseguire quanto segue per disinstallare un
programma.
$ ./configure all-of-the-options-you-gave-it
$ sudo make uninstall
In alternativa, se si è assolutamente certi che il processo di installazione
mette i file solo in "/usr/local/
" e lì non c'è nulla di
importante, si può cancellare tutto ciò che contiene con la riga di comando
seguente.
# find /usr/local -type f -print0 | xargs -0 rm -f
If you are not sure where files are installed, you should consider using
checkinstall
(8) from the checkinstall
package, which provides a clean path for the uninstall. It now supports to
create a Debian package with "-D
" option.
The software build system has been evolving:
Autotools on the top of Make has been the de facto standard for the portable build infrastructure since 1990s. This is extremely slow.
CMake initially released in 2000 improved speed significantly but was still build on the top of inherently slow Make.
Ninja initially released in 2012 is meant to replace Make for the further improved build speed but is also designed to have its input files generated by a higher-level build system.
Meson initially released in 2013 is the new popular and fast higher-level build system which uses Ninja as its backend.
See documents found at "The Meson Build system" and "The Ninja build system".
Pagine web dinamiche interattive di base possono essere create nel modo seguente.
Le interrogazioni vengono presentate all'utente del browser usando moduli HTML.
La compilazione e il cliccare sulle voci nel modulo invia una delle stringhe URL seguenti con i parametri codificati dal browser al web server.
"http://www.foo.dom/cgi-bin/program.pl?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
"http://www.foo.dom/cgi-bin/program.py?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
"http://www.foo.dom/program.php?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
"%nn
" nell'URL viene sostituito dal carattere con valore
esadecimale nn
.
Viene impostata la variabile d'ambiente: "QUERY_STRING="VAR1=VAL1
VAR2=VAL2 VAR3=VAL3"
".
Il programma CGI (uno qualsiasi dei
"program.*
") sul server web è eseguito con la variabile
d'ambiente "$QUERY_STRING
".
Lo stdout
del programma CGI viene inviato al browser web
ed è presentato come pagina web dinamica interattiva.
Per ragioni di sicurezza è bene non creare a mano nuovi metodi per analizzare i parametri CGI. Per loro esistono moduli Perl e Python comprovati. PHP è fornito con queste funzionalità. Quando è necessaria l'archiviazione dei dati client vengono usati i cookie HTTP. Quando è necessaria l'elaborazione dei dati lato client, viene spesso usato Javascript.
Per maggiori informazioni vedere CGI (Common Gateway Interface), Apache Software Foundation e JavaScript.
Cercare "CGI tutorial" su Google digitando l'URL codificato http://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial direttamente nell'indirizzo del browser è un buon modo per vedere lo script CGI in azione sul server di Google.
Esistono programmi per convertire codice sorgente.
Tabella 12.19. Elenco di strumenti per la traduzione di codice sorgente
pacchetto | popcon | dimensione | parola chiave | descrizione |
---|---|---|---|---|
perl
|
V:600, I:991 | 705 | AWK→PERL | converte codice sorgente da AWK a PERL:a2p (1) |
f2c
|
V:0, I:5 | 442 | FORTRAN→C | converte codice sorgente da FORTRAN 77 a C/C++: f2c (1) |
intel2gas
|
V:0, I:0 | 178 | intel→gas | convertitore da NASM (formato Intel) a GAS (GNU Assembler) |
Se si desidera creare un pacchetto Debian, leggere i documenti seguenti.
Capitolo 2, Gestione dei pacchetti in Debian per capire le basi del sistema dei pacchetti
Sezione 2.7.13, «Fare il port di un pacchetto nel sistema stabile» per capire le basi del processo di port
Sezione 9.11.4, «Sistema chroot» per capire le basi delle tecniche chroot
debuild
(1), and sbuild
(1)
Sezione 12.5.2, «Fare il debug di pacchetti Debian» per la ricompilazione per il debug
Guide for Debian
Maintainers (il pacchetto debmake-doc
)
Debian Developer's
Reference (pacchetto developers-reference
)
Manuale Debian Policyl (pacchetto
debian-policy
)
Ci sono pacchetti come debmake
,
dh-make
, dh-make-perl
, ecc., che
aiutano nella creazione dei pacchetti.