Inhaltsverzeichnis
Ich gebe hier einige Startimpulse, um Programmierung im Debian-System zumindest so weit zu erlernen, dass der Programmcode aus Debian-Quellpaketen zwecks Fehlersuche nachverfolgt werden kann. Hier einige erwähnenswerte Pakete und dazugehörige Dokumentation:
Handbuchseiten (manpages) sind verfügbar, indem Sie nach Installation der
manpages
- und manpages-dev
-Pakete
"man programmname
" eingeben. Informationen über
GNU-Werkzeuge erhalten Sie über "info programmname
" nach
Installation der entsprechenden Dokumentationspakete. Sie müssen unter
Umständen die Bereiche contrib
und
non-free
des Archivs zusätzlich zu
main
freigeben, da einige GFDL-Dokumentation als nicht
DFSG-frei angesehen wird.
Please consider to use version control system tools. See Abschnitt 10.5, „Git“.
![]() |
Warnung |
---|---|
Verwenden Sie nicht " |
![]() |
Achtung |
---|---|
Sie sollten Software, die direkt aus den Quellen kompiliert wurden, in
" |
![]() |
Tipp |
---|---|
Die Code-Beispiele zum Erzeugen des Songs "99 Bottles of Beer" sollten Ihnen gute Ideen zu nahezu allen Programmiersprachen liefern. |
Das Shellskript ist eine Textdatei mit gesetztem Ausführungsbit und enthält Befehle in der folgenden Form:
#!/bin/sh ... command lines
Die erste Zeile spezifiziert den Shell-Interpreter, der den Inhalt dieser Datei liest und ausführt.
Das Lesen von Shellskripten ist der beste Weg, um zu verstehen, wie ein Unix-artiges System arbeitet. Ich gebe hier einige Hinweise zur Shellprogrammierung. Lesen Sie "Shell Mistakes" (http://www.greenend.org.uk/rjk/2001/04/shell.html), um aus Fehlern zu lernen.
Anders als der interaktive Shell-Modus (lesen Sie Abschnitt 1.5, „Der einfache Shell-Befehl“ und Abschnitt 1.6, „Unix-ähnliche Textverarbeitung“) verwenden Shellskripte häufig Parameter, bedingte Ausdrücke und Schleifen.
Many system scripts may be interpreted by any one of POSIX shells (see Tabelle 1.13, „Liste von Shell-Programmen“).
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
.
Vermeiden Sie, in Shellskripten Bashisms
oder Zshisms (speziell für Bash oder Zsh
angepasste Shell-Befehle) zu verwenden, damit sie auf alle POSIX-Shells
portierbar sind. Sie können dies mittels checkbashisms
(1)
überprüfen.
Tabelle 12.1. Liste typischer Bashisms
Gut: POSIX | Vermeiden: Bashism |
---|---|
if [ "$foo" = "$bar" ] ; then … |
if [ "$foo" == "$bar" ] ; then … |
diff -u datei.c.orig datei.c |
diff -u datei.c{.orig,} |
mkdir /foobar /foobaz |
mkdir /foo{bar,baz} |
funktionsname() { … } |
function funktionsname() { … } |
Oktalformat: "\377 " |
Hexadezimalformat: "\xff " |
Der Befehl "echo
" muss mit Vorsicht verwendet werden, da
seine Implementierung sich zwischen Shell-Builtins und externen Befehlen
unterscheidet:
vermeiden Sie die Verwendung jeglicher Befehlsoptionen außer
"-n
";
vermeiden Sie die Verwendung von Escape-Sequenzen in Zeichenketten, da deren Handhabung unterschiedlich ist.
![]() |
Anmerkung |
---|---|
Obwohl die Option " |
![]() |
Tipp |
---|---|
Nutzen Sie den " |
Einige spezielle Shellparameter werden oft in Shellskripten verwendet:
Tabelle 12.2. Liste von Shellparametern
Shellparameter | Wert |
---|---|
$0 |
Name der Shell oder des Shellskripts |
$1 |
erstes (1.) Shellargument |
$9 |
neuntes (9.) Shellargument |
$# |
Anzahl der Parameter |
"$*" |
"$1 $2 $3 $4 … " |
"$@" |
"$1" "$2" "$3" "$4" … |
$? |
Beendigungs-Status des zuletzt ausgeführten Befehls |
$$ |
Prozessnummer (PID) des Shellskripts |
$! |
PID des zuletzt ausgeführten Hintergrundbefehls |
Grundlegende Parameterauswertungen, die Sie sich einprägen sollten:
Tabelle 12.3. Liste von Parameterauswertungen
Parameterauswertung | Wert, falls var gesetzt ist |
Wert, falls var nicht gesetzt ist |
---|---|---|
${var:-string} |
"$var " |
"string " |
${var:+string} |
"string " |
"null " |
${var:=string} |
"$var " |
"string " (und ausführen von
"var=string ") |
${var:?string} |
"$var " |
Ausgabe von "string " auf stderr (und mit Fehlerstatus beenden) |
Hierbei ist der Doppelpunkt ":
" in allen Operatoren
optional:
mit ":
" = Operatortest
für existiert und nicht Null;
ohne ":
" =
Operatortest nur für existiert.
Tabelle 12.4. Liste von Shellparameterersetzungen
Parameterersetzung | Ergebnis |
---|---|
${var%suffix} |
entferne kleinstes Suffix-Muster |
${var%%suffix} |
entferne größtes Suffix-Muster |
${var#prefix} |
entferne kleinstes Prefix-Muster |
${var##prefix} |
entferne größtes Prefix-Muster |
Jeder Befehl gibt einen Beendigungs-Status (Exit-Status) zurück, der für einen bedingten Ausdruck verwendet werden kann:
Erfolg: 0 ("Wahr/True")
Fehler: nicht 0 ("Falsch/False")
![]() |
Anmerkung |
---|---|
"0" im Kontext eines bedingten Ausdrucks für die Shell bedeutet "Wahr", während "0" im Kontext eines bedingten Ausdrucks für ein C-Programm "Falsch" bedeutet. |
![]() |
Anmerkung |
---|---|
" |
Grundlegende Ausdrucksformen für bedingte Ausdrücke, die Sie sich einprägen sollten:
"befehl &&
bei_erfolg_auch_diesen_befehl_ausführen ||
true
"
"befehl ||
falls_kein_erfolg_auch_diesen_befehl_ausführen ||
true
"
ein mehrzeiliger Skriptschnipsel wie dieser:
if [ conditional_expression ]; then if_success_run_this_command else if_not_success_run_this_command fi
Hierbei ist das "|| true
" am Ende erforderlich, um
sicherzustellen, dass das Shellskript sich bei dieser Zeile nicht
fälschlicherweise beendet, wenn die Shell mit der
"-e
"-Option aufgerufen wird.
Tabelle 12.5. Liste von Dateivergleichsoperatoren in bedingten Ausdrücken
Gleichung | Wahr wenn … |
---|---|
-e datei |
datei existiert |
-d datei |
datei existiert und ein Verzeichnis ist |
-f datei |
datei existiert und eine reguläre Datei ist |
-w datei |
datei existiert und schreibbar ist |
-x datei |
datei existiert und ausführbar ist |
datei1 -nt
datei2 |
datei1 neuer als datei2 ist (Änderungszeitpunkt) |
datei1 -ot
datei2 |
datei1 älter als datei2 ist (Änderungszeitpunkt) |
datei1 -ef
datei2 |
datei1 und datei2 die gleiche Device- und Inode-Nummer haben |
Tabelle 12.6. Liste von String-Vergleichsoperatoren im bedingten Ausdruck
Gleichung | Wahr wenn … |
---|---|
-z str |
die Länge von str gleich Null ist |
-n str |
die Länge von str nicht Null ist |
str1 = str2 |
str1 und str2 gleich sind |
str1 != str2 |
str1 und str2 ungleich sind |
str1 < str2 |
str1 in der Sortierung vor str2 erscheint (Locale-abhängig) |
str1 > str2 |
str1 in der Sortierung hinter str2 erscheint (Locale-abhängig) |
Arithmetische Ganzzahlvergleicher in
bedingten Ausdrücken sind "-eq
",
"-ne
", "-lt
",
"-le
", "-gt
" und
"-ge
".
Es gibt mehrere Ausdrucksweisen für Schleifen, die in POSIX-Shells genutzt werden können:
"for x in foo1 foo2 … ; do befehl ; done
" führt Schleifen
aus, indem Einträge aus der Liste "foo1 foo2 …
" der
Variable "x
" zugewiesen werden und dann
"befehl
" ausgeführt wird.
"while bedingung ; do befehl ; done
" wiederholt
"befehl
", solange "bedingung
" wahr
ist.
"until bedingung ; do befehl ; done
" wiederholt
"befehl
", solange "bedingung
" nicht
wahr ist.
"break
" ermöglicht, die Bearbeitung der Schleife zu
beenden.
"continue
" ermöglicht, den nächsten Umlauf der Schleife
fortzusetzen.
![]() |
Tipp |
---|---|
Die der C-Sprache ähnliche nummerische Wiederholung
(Iteration) kann realisiert werden, indem |
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 Abschnitt 4.5.2, „Modernes zentralisiertes Systemmanagement“)
Die Shell verarbeitet ein Skript im Prinzip in der folgenden Abfolge:
Die Shell liest eine Zeile.
Die Shell gruppiert Teile der Zeile zu zusammengehörigen Ausdrücken (Token) zusammen, wenn
diese sich innerhalb von "…"
oder '…'
befinden.
Die Shell splittet andere Teile der Zeile in einzelne Ausdrücke (Token) auf, wenn diese wie folgt von einander getrennt sind:
Whitespace-Zeichen: Leerzeichen
Tabulator newline
Metacharacters: | ; & ( )
Die Shell prüft jeden Ausdruck auf Schlüsselworte (wenn nicht innerhalb von
"…"
oder '…'
), um deren Verhalten
anzupassen.
Schlüsselwörter sind: if then
elif else fi for in while unless do done case esac
Die Shell expandiert Alias-Befehle (wenn
nicht innerhalb von "…"
oder '…'
).
Die Shell expandiert eine Tilde (wenn
nicht innerhalb von "…"
oder '…'
):
"~
" → Heimatverzeichnis des aktuellen Benutzers
"~benutzer
" → Heimatverzeichnis von
benutzer
Die Shell expandiert Parameter in deren
Wert (wenn nicht innerhalb von '…'
):
Parameter:
"$PARAMETER
" oder "${PARAMETER}
"
Die Shell expandiert Befehlsersetzungen / command
substitutions (wenn nicht innerhalb von '…'
):
"$( befehl )
" → die Ausgabe von
"befehl
"
"` befehl `
" → die Ausgabe von
"befehl
"
Die Shell expandiert Pfadnamenmuster in
die passenden Dateinamen (wenn nicht innerhalb von "…"
oder '…'
):
*
→ jegliche Zeichen (eins oder mehrere)
?
→ irgendein (nur ein) Zeichen
[…]
→ jegliche Zeichen von denen in
"…
"
Die Shell sucht befehl in folgenden Definitionen und führt ihn aus:
Funktions-Definition
Builtin (integrierter Befehl)
ausführbare Datei in
"$PATH
"
Die Shell geht zur nächsten Zeile und wiederholt diesen kompletten Ablauf vom Anfang.
Einfache Anführungszeichen innerhalb von doppelten Anführungszeichen haben keine Wirkung.
Das Ausführen von "set -x
" in der Shell oder das Aufrufen
einer Shell mit der Option "-x
" veranlasst die Shell,
alle ausgeführten Befehle auch auf dem Bildschirm auszugeben. Dies ist sehr
nützlich zur Fehlersuche.
Um Ihr Shellprogramm innerhalb des Debian-Systems möglichst weit portierbar zu machen, ist es eine gute Idee, die zu nutzenden Hilfsprogramme auf diejenigen einzuschränken, welche durch die essential-Pakete bereitgestellt werden:
"aptitude search ~E
" listet alle essential-Pakete auf;
"dpkg -L paketname |grep
'/man/man.*/'
" listet Handbuchseiten (manpages) derjenigen Befehle
auf, die von dem Paket paketname
bereitgestellt werden.
Tabelle 12.7. Liste der Pakete, die kleine Hilfsprogramme für Shellskripte enthalten
Paket | Popcon | Größe | Beschreibung |
---|---|---|---|
dash
|
V:896, I:994 | 222 | small and fast POSIX-compliant shell for sh |
coreutils
|
V:898, I:999 | 17372 | Grundlegende GNU-Werkzeuge |
grep
|
V:815, I:999 | 1118 | GNU grep , egrep and
fgrep |
sed
|
V:804, I:999 | 912 | GNU sed |
mawk
|
V:392, I:997 | 247 | small and fast awk |
debianutils
|
V:924, I:999 | 242 | verschiedene Hilfsprogramme speziell für Debian |
bsdutils
|
V:646, I:999 | 419 | grundlegende Kommandos aus 4.4BSD-Lite |
bsdextrautils
|
V:304, I:392 | 422 | extra utilities from 4.4BSD-Lite |
moreutils
|
V:12, I:37 | 244 | zusätzliche Unix-Hilfsprogramme |
![]() |
Tipp |
---|---|
Although |
See Abschnitt 1.6, „Unix-ähnliche Textverarbeitung“ for examples.
Tabelle 12.8. List of interpreter related packages
Paket | Popcon | Größe | Dokumentation |
---|---|---|---|
dash
|
V:896, I:994 | 222 | sh: small and fast POSIX-compliant shell for
sh |
bash
|
V:803, I:999 | 6450 | sh: "info bash " provided by
bash-doc |
mawk
|
V:392, I:997 | 247 | AWK: small and fast awk |
gawk
|
V:334, I:417 | 2456 | AWK: "info gawk " provided by
gawk-doc |
perl
|
V:611, I:991 | 719 | Perl: perl (1) and html pages
provided by perl-doc and perl-doc-html |
libterm-readline-gnu-perl
|
V:2, I:29 | 380 | 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:694, I:917 | 90 | Python: python3 (1) and html
pages provided by python3-doc |
tcl
|
V:26, I:318 | 22 | Tcl: tcl (3) and detail manual
pages provided by tcl-doc |
tk
|
V:26, I:310 | 22 | Tk: tk (3) and detail manual
pages provided by tk-doc |
ruby
|
V:102, I:279 | 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 Abschnitt 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.
Tabelle 12.9. List of dialog programs
Paket | Popcon | Größe | Beschreibung |
---|---|---|---|
x11-utils
|
V:169, I:581 | 712 | xmessage (1): eine Nachricht oder Abfrage in einem Fenster
anzeigen (X) |
whiptail
|
V:253, I:996 | 71 | nutzerfreundliche Dialogboxen von Shellskripten anzeigen (newt) |
dialog
|
V:13, I:114 | 1217 | nutzerfreundliche Dialogboxen von Shellskripten anzeigen (ncurses) |
zenity
|
V:71, I:381 | 167 | display graphical dialog boxes from shell scripts (GTK) |
ssft
|
V:0, I:0 | 75 | Werkzeug für Shellskript-Oberflächen (Aufrufprogramm für zenity, kdialog und dialog mit gettext) |
gettext
|
V:49, I:292 | 5843 | "/usr/bin/gettext.sh ": Nachricht übersetzen |
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 Abschnitt 9.4.10, „Ein Programm aus der grafischen Oberfläche heraus starten“.
#!/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.
GUI filer programs can be extended to perform some popular actions on selected files using additional extension packages. They can also made to perform very specific custom actions by adding your specific scripts.
For GNOME, see NautilusScriptsHowto.
For KDE, see Creating Dolphin Service Menus.
For Xfce, see Thunar - Custom Actions and https://help.ubuntu.com/community/ThunarCustomActions.
For LXDE, see Custom Actions.
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 }' |
Sie ist äquivalent zu jeder der folgenden Zeilen:
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' |
Das letzte ist eine Knobelaufgabe. Es nutzt die Vorteile folgender Perl-Funktionalitäten:
Der Whitespace ist optional.
Es existiert eine automatische Konvertierung von Zahlen zu Zeichenketten.
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.
Tabelle 12.10. List of compiler related packages
Paket | Popcon | Größe | Beschreibung |
---|---|---|---|
gcc
|
V:145, I:580 | 45 | GNU C compiler |
libc6-dev
|
V:233, I:596 | 13859 | GNU C Library: Development Libraries and Header Files |
g++
|
V:59, I:510 | 15 | GNU C++ compiler |
libstdc++-10-dev
|
V:31, I:200 | 17575 | GNU Standard C++ Library v3 (development files) |
cpp
|
V:322, I:748 | 42 | GNU C preprocessor |
gettext
|
V:49, I:292 | 5843 | GNU Internationalization utilities |
glade
|
V:0, I:7 | 1332 | GTK User Interface Builder |
valac
|
V:0, I:6 | 713 | C# like language for the GObject system |
flex
|
V:8, I:85 | 1279 | LEX-compatible fast lexical analyzer generator |
bison
|
V:9, I:94 | 3111 | YACC-compatible parser generator |
susv2
|
I:0 | 16 | die "Single UNIX Specifications v2" |
susv3
|
I:0 | 16 | die "Single UNIX Specifications v3" |
golang
|
I:21 | 12 | Go programming language compiler |
rustc
|
V:2, I:13 | 9018 | Rust systems programming language |
haskell-platform
|
I:5 | 12 | Standard Haskell libraries and tools |
gfortran
|
V:10, I:86 | 16 | GNU Fortran 95 compiler |
fpc
|
I:3 | 121 | Free Pascal |
Here, Abschnitt 12.3.3, „Flex - ein besseres Lex“ and Abschnitt 12.3.4, „Bison - ein besseres Yacc“ are included to indicate how compiler-like program can be written in C language by compiling higher level description into C language.
Sie können wie folgt eine korrekte Umgebung zum Kompilieren von in der C-Programmiersprache geschriebenen Programmen einrichten:
# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential
Das Paket libc6-dev
(d.h. die GNU-C-Bibliothek) bietet
als C-Standard-Bibliothek eine
Sammlung von Header-Dateien und Bibliotheksroutinen, die von der C-Sprache
genutzt werden.
Referenzen für C finden Sie über:
"info libc
" (Referenz für Funktionen der C-Bibliothek)
gcc
(1) und "info gcc
"
jeglicher_funktionsname_aus_der_c_bibliothek
(3)
Kernighan & Ritchie, "The C Programming Language", 2. Ausgabe (Prentice Hall)
Hier ein einfaches Beispiel zum Kompilieren von
"example.c
" mit der Bibliothek "libm
"
in eine ausführbare Datei "run_example
":
$ 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
Hierbei wird "-lm
" benötigt, um die Bibliothek
"/usr/lib/libm.so
" aus dem libc6
-Paket
für sqrt
(3) zu verlinken. Die eigentliche Bibliothek
liegt in "/lib/
" und hat den Dateinamen
"libm.so.6
", was ein symbolischer Link auf
"libm-2.7.so
" ist.
Schauen Sie sich den letzten Parameter im ausgegebenen Text an. Dort werden
mehr als 10 Zeichen ausgegeben, obwohl "%10s
" angegeben
wurde.
Die Verwendung von Funktionen, die Zeiger auf Speicherbereiche ohne
Bereichsüberprüfung nutzen (wie sprintf
(3) und
strcpy
(3)), wird missbilligt, um das Ausnutzen von
Pufferüberläufen zu verhindern, die obige Überlaufeffekte in Gang
bringen. Verwenden Sie stattdessen snprintf
(3) und
strncpy
(3).
Flex ist ein Lex-kompatibler schneller lexikalischer Analysegenerator.
Eine Einführung zu flex
(1) finden Sie in "info
flex
".
Sie müssen Ihre eigenen "main()
"- und
"yywrap()
"-Funktionen bereitstellen oder Ihr Programm
sollte wie folgt aussehen, um ohne eine Bibliothek zu kompilieren (dies ist
so, weil "yywrap
" ein Makro ist und "%option
main
" implizit "%option noyywrap
" aktiviert):
%option main %% .|\n ECHO ; %%
Alternativ könnten Sie mit der "-lfl
"-Linker-Option am
Ende Ihrer cc
(1)-Kommandozeile kompilieren (wie
AT&T-Lex mit "-ll
"). Es wird in diesem Fall kein
"%option
" benötigt.
Einige Pakete stellen Yacc-kompatible LR-Parser- oder LALR-Parser-Generatoren in Debian bereit:
Eine Einführung zu bison
(1) finden Sie in "info
bison
".
Sie müssen Ihre eigenen "main()
"- und
"yyerror()
"-Funktionen
bereitstellen. "main()
" ruft
"yyparse()
" auf, das wiederum
"yylex()
" aufruft, was gewöhnlich von FleX erzeugt wird.
%% %%
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.
![]() |
Tipp |
---|---|
Configuring your favorite editor ( |
Tabelle 12.12. Liste von Werkzeugen für die statische Code-Analyse
Paket | Popcon | Größe | Beschreibung |
---|---|---|---|
vim-ale
|
I:0 | 2167 | 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
|
I:0 | 133 | Emacs Lisp regexp mistake finder |
cppcheck-gui
|
V:0, I:1 | 6253 | tool for static C/C++ code analysis (GUI) |
shellcheck
|
V:2, I:10 | 15883 | lint tool for shell scripts |
pyflakes3
|
V:0, I:15 | 23 | passive checker of Python 3 programs |
pylint
|
V:4, I:17 | 1653 | Statisches Prüfprogramm für Python-Code |
perl
|
V:611, I:991 | 719 | Interpreter mit internem statischen Code-Prüfmechanismus:
B::Lint (3perl) |
rubocop
|
V:0, I:0 | 2390 | Ruby static code analyzer |
clang-tidy
|
V:1, I:7 | 25 | clang-based C++ linter tool |
splint
|
V:0, I:3 | 2320 | Werkzeug zur statischen Überprüfung von C-Programmen auf Programmfehler |
flawfinder
|
V:0, I:0 | 205 | Werkzeug zur Durchsuchung von Quellcode auf Sicherheitsschwächen |
black
|
V:1, I:6 | 559 | 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:29 | 345 | 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.
Das primäre Programm zur Fehlersuche
(Debugger) im Debian-System ist gdb
(1), welches
Ihnen erlaubt, ein Programm zu inspizieren, während es läuft.
Wir installieren gdb
und zugehörige Programme wie folgt:
# 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
![]() |
Tipp |
---|---|
Viele |
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 ./
Beheben Sie die Fehler, falls erforderlich.
Erhöhen Sie die Paketversion auf eine Versionsbezeichnung, die nicht mit
offiziellen Debian-Versionen kollidiert (Sie können z.B. ein
"+debug1
" anhängen, wenn Sie eine existierende
Paketversion neu kompilieren, oder Sie hängen "~pre1
" an,
wenn Sie eine noch nicht veröffentlichte Paketversion selbst
kompilieren). Verwenden Sie dazu:
$ dch -i
Kompilieren und installieren Sie ein Paket mit Debugging-Symbolen wie folgt:
$ export DEB_BUILD_OPTIONS="nostrip noopt" $ debuild $ cd .. $ sudo debi package_name*.changes
Sie müssen die Build-Skripte des Pakets überprüfen und sicherstellen, dass
"CFLAGS=-g -Wall
" zum Kompilieren der Binärdateien
verwendet wird.
Wenn Sie einen Programmabsturz erlitten haben, ist es eine gute Idee, einen Fehlerbericht einzureichen und an diesen per Kopieren-und-Einfügen Backtrace-Informationen (Daten zur Rückverfolgung von Vorgängen in Programmen zwecks Fehleranalyse) anzuhängen.
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
Abschnitt 9.4.12, „Einen Prozess beenden (kill)“)
![]() |
Tipp |
---|---|
Oft stellt man fest, dass in den Backtrace-Informationen eine oder mehrere
der ersten Zeilen " $ MALLOC_CHECK_=2 gdb hello |
Tabelle 12.14. Liste erweiterter gdb-Befehle
Befehl | Beschreibung |
---|---|
(gdb) thread apply all bt |
Backtrace für alle Threads eines Multi-Thread-Programms auslesen |
(gdb) bt full |
Parameter auslesen, die auf dem Aufruf-Stack der Funktionsaufrufe aufgelaufen sind |
(gdb) thread apply all bt full |
Backtrace und Parameter als Kombination der vorangegangenen Optionen auslesen |
(gdb) thread apply all bt full 10 |
Backtrace und Parameter für die ersten 10 Aufrufe auslesen, um irrelevante Ausgaben abzuschneiden |
(gdb) set logging on |
Protokoll der Ausgabe von gdb in eine Datei schreiben
(Standard ist "gdb.txt ") |
Verwenden Sie ldd
(1) wie hier, um zu ermitteln, von
welchen Bibliotheken ein Programm abhängt:
$ 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)
Damit ls
(1) in einer "chroot"-Umgebung funktioniert,
müssen die obigen Bibliotheken in der "chroot"-Umgebung vorhanden sein.
Lesen Sie dazu Abschnitt 9.4.6, „Programmaktivitäten verfolgen“.
There are several dynamic call tracing tools available in Debian. See Abschnitt 9.4, „Überwachen, Steuern und Starten von Programmaktivitäten“.
Wenn ein GNOME-Programm preview1
einen X-Fehler empfangen
hat, sollten Sie eine Meldung wie diese sehen:
The program 'preview1' received an X Window System error.
Sollte dies der Fall sein, können Sie versuchen, das Programm mit der Option
"--sync
" zu starten und einen Haltepunkt für die Funktion
"gdk_x_error
" zu setzen, um einen Backtrace zu bekommen.
Es gibt verschiedene Werkzeuge zur Erkennung von Speicherlecks in Debian:
Tabelle 12.15. Liste von Werkzeugen zur Erkennung von Speicherlecks
Paket | Popcon | Größe | Beschreibung |
---|---|---|---|
libc6-dev
|
V:233, I:596 | 13859 | mtrace (1): malloc-Debugging-Funktionalität in glibc |
valgrind
|
V:6, I:43 | 77249 | Speicher-Debugging- und Analyse-Programm |
electric-fence
|
V:0, I:5 | 72 | malloc (3)-Debugging-Programm |
libdmalloc5
|
V:0, I:3 | 393 | Bibliothek zur Fehlersuche bei Speicherzuweisungen |
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 | Werkzeug zur Verfolgung von Speicherlecks in C++-Programmen |
Tabelle 12.16. List of build tool packages
Paket | Popcon | Größe | Dokumentation |
---|---|---|---|
make
|
V:133, I:588 | 1592 | "info make " aus dem make-doc -Paket |
autoconf
|
V:29, I:270 | 2033 | "info autoconf " aus dem
autoconf-doc -Paket |
automake
|
V:28, I:268 | 1836 | "info automake " aus dem
automake1.10-doc -Paket |
libtool
|
V:22, I:253 | 1198 | "info libtool " provided by libtool-doc |
cmake
|
V:17, I:118 | 26660 | cmake (1) cross-platform, open-source make system |
ninja-build
|
V:5, I:31 | 347 | ninja (1) small build system closest in spirit to Make |
meson
|
V:2, I:19 | 3255 | meson (1) high productivity build system on top of
ninja |
xutils-dev
|
V:1, I:10 | 1485 | imake (1), xmkmf (1) usw. |
Make ist ein Werkzeug, um Gruppen von Programmen
zu betreuen. Bei Ausführung des Befehls make
(1) liest
make
die Regeldatei "Makefile
" und
aktualisiert ein Ziel (Target), falls sich Dateien, von denen das Makefile
abhängt, seit der letzten Modifizierung des Targets verändert haben oder
falls das Target nicht existiert. Die Ausführungen dieser Aktualisierungen
können zeitgleich erfolgen.
Die Syntax der Regeldatei ist folgende:
target: [ prerequisites ... ] [TAB] command1 [TAB] -command2 # ignore errors [TAB] @command3 # suppress echoing
Hierbei ist "[TAB]
" ein TAB-Code. Jede Zeile wird nach
Ersetzung der Variablen durch die Shell interpretiert. Verwenden Sie
"\
" am Ende einer Zeile, um den Befehl in der nächsten
Zeile fortzusetzen. Zur Angabe von Umgebungsvariablen müssen Sie statt
"$
" hier "$$
" schreiben.
Implizite Regeln für das Target und Voraussetzungen können z.B. wie folgt angegeben werden:
%.o: %.c header.h
Hier enthält das Target das Zeichen "%
" (exakt eines
davon). Das "%
" passt auf jeden nicht leeren Teil-String
in den eigentlichen Dateinamen des Targets. Auch die Voraussetzungen nutzen
auf ähnliche Art ein "%
", um den Bezug zum Namen des
Targets anzuzeigen.
Tabelle 12.17. Liste von automatischen make-Variablen
automatische Variable | Wert |
---|---|
$@ |
Target |
$< |
erste Voraussetzung |
$? |
alle neueren Voraussetzungen |
$^ |
alle Voraussetzungen |
$* |
"% " trifft auf den Stamm im Target-Muster zu |
Tabelle 12.18. Liste von make-Variablenexpandierungen
Variablenexpandierung | Beschreibung |
---|---|
foo1 := bar |
einmalige Expandierung |
foo2 = bar |
rekursive Expandierung |
foo3 += bar |
anhängen |
Führen Sie "make -p -f/dev/null
" aus, um alle internen
automatischen Regeln zu sehen.
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.
![]() |
Warnung |
---|---|
Überschreiben Sie keine Systemdateien, wenn Sie Ihre selbst kompilierten Programme installieren. |
Debian verändert keine Dateien unter "/usr/local/
" oder
"/opt
". Wenn Sie also ein Programm aus den Quellen
kompilieren, sollten Sie es in "/usr/local/
"
installieren, damit es nicht mit Debian kollidiert.
$ cd src $ ./configure --prefix=/usr/local $ make # this compiles program $ sudo make install # this installs the files in the system
Wenn Sie noch den Original-Quellcode haben, dieser
autoconf
(1)/automake
(1) nutzt und Sie
noch wissen, wie Sie es konfiguriert haben, verfahren Sie wie folgt, um das
Programm zu deinstallieren:
$ ./configure all-of-the-options-you-gave-it
$ sudo make uninstall
Wenn Sie sich absolut sicher sind, dass der Installationsprozess Dateien nur
unter "/usr/local/
" abgelegt hat und und es nichts
Wichtiges mehr dort gibt, können Sie alternativ auch alles löschen, wie
hier:
# 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".
Einfache interaktive dynamische Webseiten können wie folgt erstellt werden:
Abfragen werden mittels HTML-Formularen dem Browser-Nutzer präsentiert.
Das Ausfüllen und Anklicken von Formulareinträgen sendet einen URL-String mit kodierten Parametern vom Browser zum Webserver:
"http://www.foo.dom/cgi-bin/program.pl?WERT1=WERT1&WERT2=WERT2&WERT3=WERT3
"
"http://www.foo.dom/cgi-bin/program.py?VAR1=WERT1&VAR2=WERT2&VAR3=WERT3
"
"http://www.foo.dom/program.php?VAR1=WERT1&VAR2=WERT2&VAR3=WERT3
"
"%nn
" in einer URL wird durch ein Zeichen mit
hexadezimalem nn
-Wert ersetzt.
Die Umgebungsvariable wird gesetzt als: "ABFRAGE_STRING="VAR1=WERT1
VAR2=WERT2 VAR3=WERT3"
".
Ein CGI-Programm (irgendeines von
"program.*
") auf dem Webserver führt sich selbst mit der
Umgebungsvariable "$ABFRAGE_STRING
" aus.
Die Standardausgabe (stdout
) eines CGI-Programms wird zum
Webbrowser gesandt und dort als interaktive dynamische Webseite angezeigt.
Aus Sicherheitsgründen wird empfohlen, keinen eigenen zusammengebastelten Code zum Parsen von CGI-Parametern zu verwenden. Es gibt dafür etablierte Module in Perl und Python. PHP unterstützt diese Funktionalitäten. Wenn eine Speicherung der Daten auf dem Client nötig ist, werden HTTP-Cookies verwendet. Ist eine Verarbeitung der Daten auf dem Client erforderlich, wird häufig Javascript genutzt.
Für weitere Informationen wird auf das Common Gateway Interface, die Apache Software Foundation und JavaScript verwiesen.
Die Suche nach "CGI tutorial" auf Google durch Eingabe der kodierten URL http://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial direkt in der Adresszeile des Browsers ist eine gute Möglichkeit, das CGI-Skript auf dem Google-Server in Aktion zu beobachten.
Es gibt verschiedene Programme zur Übersetzung von Quellcode:
Tabelle 12.19. Liste von Programmen zur Übersetzung von Quellcode
Paket | Popcon | Größe | Schlüsselwort | Beschreibung |
---|---|---|---|---|
perl
|
V:611, I:991 | 719 | AWK → PERL | Quellcode von AWK nach PERL konvertieren: a2p (1) |
f2c
|
V:0, I:5 | 442 | FORTRAN → C | Quellcode von FORTRAN 77 nach C/C++ konvertieren: f2c (1) |
intel2gas
|
V:0, I:0 | 178 | intel → gas | Konvertierer von NASM (Intel-Format) nach GNU Assembler (GAS) |
Wenn Sie ein Debian-Paket erstellen möchten, lesen Sie folgendes:
Kapitel 2, Debian-Paketmanagement, um die Grundlagen des Paketsystems zu verstehen;
Abschnitt 2.7.13, „Ein Paket auf das Stable-System portieren“, um den grundlegenden Portierungsprozess zu verstehen;
Abschnitt 9.11.4, „Chroot-System“, um die grundlegenden chroot-Techniken zu verstehen;
debuild
(1), and sbuild
(1)
Abschnitt 12.5.2, „Fehlersuche in einem Debian-Paket (Debugging)“ für Informationen zum Rekompilieren von Quellcode zwecks Fehlersuche (Debugging);
Handbuch für
Debian-Paketbetreuer (aus dem debmake-doc
-Paket).
Debian-Entwicklerreferenz
(aus dem developers-reference
-Paket);
Debian Policy-Handbuch (aus dem
debian-policy
-Paket);
Es gibt auch Pakete wie debmake
,
dh-make
, dh-make-perl
usw., die beim
Paketieren helfen.