Innehållsförteckning
Jag ger några tips för att människor ska lära sig programmering på Debian-systemet tillräckligt för att spåra den paketerade källkoden. Här är anmärkningsvärda paket och motsvarande dokumentationspaket för programmering.
Online-referenser finns tillgängliga genom att skriva "man
name" efter installation av paketen manpages
och manpages-dev. Online-referenser för GNU-verktygen
finns tillgängliga genom att skriva "info programnamn"
efter att du har installerat de relevanta dokumentationspaketen. Du kan
behöva inkludera arkiven contrib- och
non-free utöver main eftersom vissa
GFDL-dokumentationer inte anses vara DFSG-kompatibla.
Tänk på att använda verktyg för versionskontrollsystem. Se Avsnitt 10.5, ”Git”.
|
Varning |
|---|---|
|
Använd inte " |
|
Observera |
|---|---|
|
Du bör installera program som är direkt kompilerade från källkod i
" |
|
Tips |
|---|---|
|
Kodexempel för att skapa "Song 99 Bottles of Beer" bör ge dig goda idéer om praktiskt taget alla programmeringsspråk. |
Shellskriptet är en textfil med exekveringsbiten aktiverad och innehåller kommandon i följande format.
#!/bin/sh ... command lines
Den första raden anger vilken shell-tolk som ska läsa och exekvera filinnehållet.
Att läsa skalskript är det bästa sättet att förstå hur ett Unix-liknande system fungerar. Här ger jag några tips och påminnelser för programmering i skalet. Se "Shell Mistakes"(https://www.greenend.org.uk/rjk/2001/04/shell.html) för att lära dig av misstag.
Till skillnad från det interaktiva läget i shell (se Avsnitt 1.5, ”Det enkla shell-kommandot” och Avsnitt 1.6, ”Unix-liknande textbehandling”) används ofta parametrar, villkor och loopar i shell-skript.
Många systemskript kan tolkas av något av POSIX-skalen (se Tabell 1.13, ”Lista över skalprogram”).
Det icke-interaktiva POSIX-skalet "/usr/bin/sh" är en
symbolisk länk som pekar på /usr/bin/dash och används av
många systemprogram.
Det interaktiva POSIX-shell som används som standard är
/usr/bin/bash.
Undvik att skriva ett skalskript med bashisms eller zshisms för att göra det portabelt mellan alla
POSIX-skal. Du kan kontrollera det med checkbashisms(1).
Tabell 12.1. Lista över typiska bashismer
| Bra: POSIX | Undvik: bashism |
|---|---|
if [ "$foo" = "$bar" ] ; then .. |
if [ "$foo" == "$bar" ] ; then .. |
diff -u fil.c.orig fil.c |
diff -u fil.c{.orig,} |
mkdir /foobar /foobaz |
mkdir /foo{bar,baz} |
funcname() { ... } |
funktion funcname() { ... } |
oktalformat: "\377" |
hexadecimalt format: "\xff" |
Kommandot "echo" måste användas med försiktighet eftersom
dess implementering skiljer sig mellan inbyggda och externa kommandon i
skalet.
Undvik att använda några kommandoval utom "-n".
Undvik att använda escape-sekvenser i strängen eftersom hanteringen av dem varierar.
|
Notera |
|---|---|
|
Alternativet " |
|
Tips |
|---|---|
|
Använd kommandot " |
Speciella shell-parametrar används ofta i shell-skriptet.
Tabell 12.2. Lista över skalparametrar
| skalparameter | värde |
|---|---|
$0 |
namnet på skalet eller skalskriptet |
$1 |
första (1st) skalargumentet |
$9 |
nionde (9:e) skalargumentet |
$# |
antal positionsparametrar |
"$*" |
"$1 $2 $3 $4 ... " |
"$@" |
"$1" "$2" "$3" "$4" .. |
$? |
utgångsstatus för det senaste kommandot |
$$ |
PID för detta shell-skript |
$! |
PID för det senast startade bakgrundsjobbet |
Grundläggande parameterutvidgningar att komma ihåg är följande.
Tabell 12.3. Lista över expansioner av skalparametrar
| parameter uttryck form | värde om var är inställd |
värde om var inte är inställd |
|---|---|---|
${var:-string} |
"$var" |
"sträng" |
${var:+string} |
"sträng" |
"null" |
${var:=string} |
"$var" |
"string" (och kör "var=string") |
${var:?string} |
"$var" |
echo "string" till stderr (och avsluta med fel) |
Här är kolon ":" i alla dessa operatorer faktiskt
valfritt.
med ":" =
operatörstest för exist och inte null
utan ":" =
operatörstest för endast existera
Tabell 12.4. Lista över ersättningar för viktiga skalparametrar
| formulär för parametersubstitution | resultat |
|---|---|
${var%suffix} |
ta bort minsta suffixmönster |
${var%%suffix} |
ta bort största suffixmönster |
${var#prefix} |
ta bort minsta prefixmönster |
${var##prefix} |
ta bort största prefixmönster |
Varje kommando returnerar en utgångsstatus som kan användas för villkorliga uttryck.
Framgång: 0 ("True")
Fel: non 0 ("False")
|
Notera |
|---|---|
|
"0" i skalvillkorskontexten betyder "sant", medan "0" i C-villkorskontexten betyder "falskt". |
|
Notera |
|---|---|
|
" |
Grundläggande villkorliga idiom att komma ihåg är följande.
"kommando &&
if_success_run_this_command_too || true"
"kommandot ||
if_not_success_run_this_command_too || true"
Ett skriptutdrag med flera rader enligt följande
if [ conditional_expression ]; then if_success_run_this_command else if_not_success_run_this_command fi
Här behövdes det efterföljande "|| true" för att
säkerställa att detta skalskript inte avslutas på denna rad av misstag när
skalet anropas med flaggan "-e".
Tabell 12.5. Lista över operatorer för filjämförelse i det villkorliga uttrycket
| ekvation | villkor som ska returnera logiskt sant |
|---|---|
- e-fil |
filen finns |
- d-fil |
filen finns och är en katalog |
-f fil |
filen finns och är en vanlig fil |
- w-fil |
filen finns och är skrivbar |
-x fil |
filen finns och är körbar |
fil1 -nt fil2 |
fil1 är nyare än fil2 (modifiering) |
fil1 -ot fil2 |
fil1 är äldre än fil2 (modifiering) |
fil1 -ef fil2 |
fil1 och fil2 finns på samma enhet och har samma inode-nummer |
Tabell 12.6. Lista över operatorer för strängjämförelse i det villkorliga uttrycket
| ekvation | villkor som ska returnera logiskt sant |
|---|---|
-z str |
längden på str är noll |
-n str |
längden på str är inte noll |
str1 = str2 |
str1 och str2 är lika |
str1!= str2 |
str1 och str2 är inte lika |
str1 < str2 |
str1 sorteras före str2 (beroende på lokal) |
str1 > str2 |
str1 sorteras efter str2 (lokalberoende) |
Aritmetiska heltalsjämförelseoperatorer i
det villkorliga uttrycket är "-eq",
"-ne", "-lt",
"-le", "-gt" och
"-ge".
Det finns flera loop-idiom som kan användas i POSIX-skal.
"for x in foo1 foo2 ... ; do command ; done" loopar genom
att tilldela objekt från listan "foo1 foo2 ..." till
variabeln "x" och utföra "command".
"while condition ; do command ; done" upprepar
"command" medan "condition" är sant.
"until condition ; do command ; done" upprepar
"command" medan "condition" inte är
sant.
"break" gör det möjligt att lämna loopen.
"continue" gör det möjligt att återuppta nästa iteration
av loopen.
|
Tips |
|---|---|
|
Den numeriska iterationen som liknar C-språkets kan
realiseras genom att använda |
Vissa populära miljövariabler för den normala kommandoprompten i shell kanske inte är tillgängliga i exekveringsmiljön för ditt skript.
För "$USER", använd "$(id -un)"
För "$UID", använd "$(id -u)"
För "$HOME" använder du "$(getent passwd "$(id
-u)"|cut -d ":" -f 6)" (detta fungerar även på Avsnitt 4.5.2, ”Den moderna centraliserade systemhanteringen”)
Shell bearbetar ett skript ungefär enligt följande sekvens.
Shell läser en rad.
Skalet grupperar en del av raden som en
token om den ligger inom "..." eller
'... '.
Shell delar upp andra delar av en rad i tokens på följande sätt.
Whitespaces: mellanslag
flik nytt streck
Metatecken: < > | ; & ( )
Skalet kontrollerar det reserverade ordet
för varje token för att anpassa sitt beteende om det inte finns inom
"..." eller '... '.
reserverat ord: if then elif
else fi for in while unless do done case esac
Skalet expanderar alias om det inte finns
inom "..." eller '...'.
Skalet expanderar tilde om det inte finns
inom "..." eller '... '.
"~" → den aktuella användarens hemkatalog
"~användare" →
användarensanvändarens hemkatalog
Skalet expanderar parametern till dess
värde om den inte finns inom '...'.
parameter:
"$PARAMETER" eller "${PARAMETER}"
Skalet expanderar kommandosubstitutionen
om den inte finns inom '...'.
"$( kommando )" → utdata från
"kommando"
"`kommando `" → utdata från "kommando"
Skalet expanderar sökvägsnamnet glob till
matchande filnamn om det inte finns inom "..." eller
'...'.
* → alla tecken
? → ett tecken
[...] → något av tecknen i "... "
Shell letar upp kommandot från följande och utför det.
definition av funktion
inbyggt kommando
körbar fil i "$PATH"
Skalet går till nästa rad och upprepar denna process igen från början av denna sekvens.
Enkla citattecken inom dubbla citattecken har ingen effekt.
Om du kör "set -x" i skalet eller anropar skalet med
alternativet "-x" skriver skalet ut alla kommandon som
har körts. Detta är ganska praktiskt för felsökning.
För att göra ditt skalprogram så portabelt som möjligt mellan olika Debian-system är det en god idé att begränsa hjälpprogrammen till sådana som tillhandahålls av viktiga paket.
"aptitude search ~E" listar viktiga paket.
"dpkg -L paketnamn |grep
'/man/man.*/'" listar handböcker för kommandon som erbjuds av
paket_namn paketet.
Tabell 12.7. Lista över paket som innehåller små verktygsprogram för skalskript
| paket | popcon | storlek | beskrivning |
|---|---|---|---|
dash
|
V:910, I:998 | 207 | litet och snabbt POSIX-kompatibelt skal för sh |
coreutils
|
V:897, I:999 | 18457 | GNU:s centrala verktyg |
grep
|
V:765, I:999 | 1297 | GNU grep, egrep och
fgrep |
sed
|
V:801, I:999 | 987 | GNU sed |
mawk
|
V:458, I:997 | 296 | liten och snabb awk |
debianutils
|
V:922, I:998 | 225 | diverse verktyg som är specifika för Debian |
bsdutils
|
V:429, I:999 | 335 | grundläggande verktyg från 4.4BSD-Lite |
bsdextrautils
|
V:725, I:841 | 361 | extra verktyg från 4.4BSD-Lite |
moreutils
|
V:16, I:38 | 231 | ytterligare Unix-verktyg |
|
Tips |
|---|---|
|
Även om |
Se Avsnitt 1.6, ”Unix-liknande textbehandling” för exempel.
Tabell 12.8. Lista över tolkrelaterade paket
| paket | popcon | storlek | dokumentation |
|---|---|---|---|
dash
|
V:910, I:998 | 207 | sh: litet och snabbt POSIX-kompatibelt skal för
sh |
bash
|
V:875, I:999 | 7273 | sh: "info bash" tillhandahålls
av bash-doc |
mawk
|
V:458, I:997 | 296 | AWK: liten och snabb awk |
gawk
|
V:255, I:315 | 3289 | AWK: "info gawk"
tillhandahålls av gawk-doc |
perl
|
V:673, I:990 | 841 | Perl: perl(1) och html-sidor
tillhandahålls av perl-doc och
perl-doc-html |
libterm-readline-gnu-perl
|
V:2, I:28 | 439 | Perl-tillägg för GNU ReadLine/History Library: perlsh(1) |
libreply-perl
|
I:0 | 171 | REPL för Perl: svar(1) |
libdevel-repl-perl
|
V:0, I:0 | 237 | REPL för Perl: re.pl(1) |
python3
|
V:714, I:969 | 82 | Python: python3(1) och
html-sidor tillhandahålls av python3-doc |
tcl
|
V:23, I:188 | 20 | Tcl: tcl(3) och detaljerade
manualsidor som tillhandahålls av tcl-doc |
tk
|
V:18, I:182 | 20 | Tk: tk(3) och detaljerade
manualsidor som tillhandahålls av tk-doc |
ruby
|
V:67, I:171 | 32 | Ruby: ruby(1),
erb(1), irb(1),
rdoc(1), ri(1) |
När du vill automatisera en uppgift på Debian bör du först skripta den med ett tolkat språk. Riktlinjerna för valet av tolkat språk är:
Använd dash om det handlar om en enkel uppgift som
kombinerar CLI-program med ett skalprogram.
Använd python3, om uppgiften inte är enkel och du skriver
den från grunden.
Använd perl, tcl,
ruby, ... om det finns en befintlig kod som använder
något av dessa språk på Debian som behöver förbättras för att utföra
uppgiften.
Om den resulterande koden är för långsam kan du skriva om endast den del som är kritisk för exekveringshastigheten i ett kompilerat språk och anropa den från det tolkade språket.
De flesta tolkar erbjuder grundläggande funktioner för syntaxkontroll och kodspårning.
"dash -n script.sh" - Syntaxkontroll av ett Shell-skript
"dash -x script.sh" - Spåra ett Shell-skript
"python-m py_compile script .py" - Syntaxkontroll av ett Python-skript
"python -mtrace --trace script .py" - Spåra ett Python-skript
"perl -I ../libpath -c script.pl" - Syntaxkontroll av ett Perl-skript
"perl -d: Trace script.pl" - Spåra ett Perl-skript
För att testa kod för dash, prova Avsnitt 9.1.4, ”Omslag för läslinje” som rymmer bash-liknande
interaktiv miljö.
För att testa kod för Perl, prova REPL-miljö för Perl som
rymmer Python-liknande REPL (=READ + EVAL + PRINT + LOOP)
-miljö för Perl.
Shell-skriptet kan förbättras för att skapa ett attraktivt GUI-program.
Tricket är att använda något av de s.k. dialogprogrammen istället för tråkig
interaktion med echo och
read-kommandon.
Tabell 12.9. Lista över dialogprogram
| paket | popcon | storlek | beskrivning |
|---|---|---|---|
x11-utils
|
V:217, I:565 | 651 | xmessage(1): visa ett meddelande eller en fråga i ett
fönster (X) |
whiptail
|
V:284, I:996 | 62 | visar användarvänliga dialogrutor från shell-skript (newt) |
dialog
|
V:9, I:85 | 493 | visar användarvänliga dialogrutor från shell-skript (ncurses) |
zenity
|
V:77, I:355 | 190 | visa grafiska dialogrutor från skalskript (GTK) |
ssft
|
V:0, I:0 | 75 | Shell Scripts Frontend Tool (wrapper för zenity, kdialog och dialog med gettext) |
gettext
|
V:51, I:234 | 7165 | "/usr/bin/gettext.sh": översätt meddelande |
Här är ett exempel på ett GUI-program som visar hur enkelt det är att bara använda ett skalskript.
Detta skript använder zenity för att välja en fil
(standard /etc/motd) och visa den.
GUI-startprogrammet för detta skript kan skapas enligt Avsnitt 9.4.10, ”Starta ett program från 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
Den här typen av tillvägagångssätt för GUI-program med shell-skript är endast användbart för enkla val. Om du ska skriva något program med komplexitet bör du överväga att skriva det på en mer kapabel plattform.
GUI-filprogram kan utökas för att utföra vissa populära åtgärder på utvalda filer med hjälp av ytterligare tilläggspaket. De kan också göras för att utföra mycket specifika anpassade åtgärder genom att lägga till dina specifika skript.
För GNOME, se NautilusScriptsHowto.
För KDE, se Skapa Dolphins servicemenyer.
För Xfce, se Thunar - Anpassade åtgärder och https://help.ubuntu.com/community/ThunarCustomActions.
För LXDE, se Anpassade åtgärder.
För att bearbeta data måste sh skapa underprocesser som
kör cut, grep, sed,
etc. och är långsamma. Å andra sidan har perl interna
funktioner för att bearbeta data och är snabb. Så många
systemunderhållsskript på Debian använder perl.
Låt oss tänka på följande one-liner AWK-skriptutdrag och dess motsvarigheter i Perl.
awk '($2=="1957") { print $3 }' |
Detta är likvärdigt med någon av följande rader.
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' |
Den sista är en gåta. Den utnyttjade följande Perl-funktioner.
Det vita tecknet är valfritt.
Den automatiska konverteringen sker från tal till sträng.
Tricks för Perl-körning via kommandoradsalternativ:
perlrun(1)
Specialvariabler för Perl: perlvar(1)
Denna flexibilitet är styrkan i Perl. Samtidigt gör det att vi kan skapa kryptiska och trassliga koder. Så var försiktig.
Tabell 12.10. Lista över kompilatorrelaterade paket
| paket | popcon | storlek | beskrivning |
|---|---|---|---|
gcc
|
V:134, I:565 | 36 | GNU C-kompilator |
libc6-dev
|
V:266, I:585 | 13574 | GNU C-biblioteket: Utvecklingsbibliotek och huvudfiler |
g++
|
V:53, I:526 | 13 | GNU C++-kompilator |
libstdc++-14-dev
|
V:27, I:203 | 24507 | GNU Standard C++ Library v3 (utvecklingsfiler) |
cpp
|
V:323, I:725 | 18 | GNU C preprocessor |
gettext
|
V:51, I:234 | 7165 | GNU:s internationaliseringsverktyg |
glade
|
V:0, I:3 | 1613 | GTK-byggare för användargränssnitt |
valac
|
V:0, I:3 | 532 | C#-liknande språk för GObject-systemet |
flex
|
V:6, I:70 | 1239 | LEX-kompatibel snabb generator för lexikal analys |
bison
|
V:6, I:75 | 3118 | YACC-kompatibel parser-generator |
susv2
|
I:0 | 16 | hämta"The Single UNIX Specifications v2" |
susv3
|
I:0 | 16 | hämta"The Single UNIX Specifications v3" |
susv4
|
I:0 | 16 | hämta"The Single UNIX Specifications v4" |
golang
|
I:21 | 12 | Go programmeringsspråk kompilator |
rustc
|
V:4, I:18 | 13748 | Rust system programmeringsspråk |
gfortran
|
V:4, I:53 | 15 | GNU Fortran 95-kompilator |
fpc
|
I:2 | 104 | Fri Pascal |
Här ingår Avsnitt 12.3.3, ”Flex - en bättre Lex” och Avsnitt 12.3.4, ”Bison - en bättre Yacc” för att visa hur ett kompilatorliknande program kan skrivas i C-språk genom att kompilera en beskrivning på högre nivå till C-språk.
Du kan skapa en lämplig miljö för att kompilera program som är skrivna i programmeringsspråket C genom att göra följande.
# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential
Paketet libc6-dev, dvs GNU C Library, tillhandahåller
C-standardbiblioteket som är en
samling av rubrikfiler och biblioteksrutiner som används av
programmeringsspråket C.
Se referenser för C som följande.
"info libc" (referens till C-bibliotekets funktioner)
gcc(1) och "info gcc"
varje_C_biblioteks_funktionsnamn(3)
Kernighan & Ritchie, "The C Programming Language", 2:a upplagan (Prentice Hall)
Ett enkelt exempel ".c" kan kompileras med ett bibliotek
"libm" till en körbar fil
"run_example" på följande sätt.
$ 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
Här behövs "-lm" för att länka biblioteket
"/usr/lib/libm.so" från libc6-paketet
för sqrt(3). Det faktiska biblioteket finns i
"/lib/" med filnamnet "libm.so.6", som
är en symlänk till "libm-2.7.so".
Titta på den sista parametern i utdatatexten. Det finns mer än 10 tecken
trots att "%10s" har angetts.
Användningen av funktioner för pekarminnesoperationer utan gränskontroller,
t.ex. sprintf(3) och strcpy(3), avråds
för att förhindra buffer overflow-exploateringar som utnyttjar ovanstående
överskridningseffekter. Använd istället snprintf(3) och
strncpy(3).
Flex är en Lex-kompatibel snabb generator för lexikal analys.
Handledning för flex(1) kan hittas i "info
flex".
Många enkla exempel finns under
"/usr/share/doc/flex/examples/". [7]
Flera paket tillhandahåller en Yacc-kompatibel lookahead LR-parser eller LALR-parsergenerator i Debian.
Handledning för bison(1) finns i "info
bison".
Du måste tillhandahålla dina egna "main()" och
"yyerror()". "main()"anropar
"yyparse()" som anropar "yylex()", vanligtvis
skapat med Flex.
Här följer ett exempel på hur du skapar ett enkelt kalkylatorprogram för terminalen.
Låt oss skapa exempel.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);
}
Låt oss skapa, exempel.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 */ }
%%
Kör sedan följande från shellprompten för att prova detta:
$ 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-liknande verktyg kan hjälpa till med automatisk statisk kodanalys.
Indragningsliknande verktyg kan underlätta mänskliga kodgranskningar genom att omformatera källkoder på ett konsekvent sätt.
Taggar som verktyg kan hjälpa mänskliga kodgranskare genom att generera en indexfil (eller taggfil) med namn som finns i källkoder.
|
Tips |
|---|---|
|
Om du konfigurerar din favoritredigerare ( |
Tabell 12.12. Lista över verktyg för statisk kodanalys
| paket | popcon | storlek | beskrivning |
|---|---|---|---|
vim-ale
|
I:0 | 2833 | Asynkron Lint-motor för Vim 8 och NeoVim |
vim-syntastic
|
I:2 | 1379 | Syntaxkontroll-hacks för vim |
elpa-flycheck
|
V:0, I:1 | 826 | modern on-the-fly syntaxkontroll för Emacs |
elpa-relint
|
V:0, I:0 | 150 | Emacs Lisp regexp misstagssökare |
cppcheck-gui
|
V:0, I:1 | 7682 | verktyg för statisk analys av C/C++-kod (GUI) |
shellcheck
|
V:2, I:15 | 35220 | lint-verktyg för shell-skript |
pyflakes3
|
V:2, I:15 | 20 | passiv kontroll av Python 3-program |
pylint
|
V:4, I:20 | 2089 | Statisk kontroll av Python-kod |
perl
|
V:673, I:990 | 841 | tolk med intern statisk kodkontroll: B::Lint(3perl) |
rubocop
|
V:0, I:1 | 3247 | Analysator för statisk kod i Ruby |
clang-tidy
|
V:1, I:12 | 22 | clang-baserat C++ linter-verktyg |
splint
|
V:0, I:1 | 2328 | verktyg för att statiskt kontrollera C-program för buggar |
flawfinder
|
V:0, I:0 | 205 | verktyg för att undersöka C/C++-källkod och leta efter säkerhetsbrister |
black
|
V:4, I:16 | 10138 | kompromisslös Python-kodformaterare |
perltidy
|
V:0, I:3 | 3086 | Indenterare och omformaterare av Perl-skript |
indent
|
V:0, I:5 | 438 | C-språk källkod formateringsprogram |
astyle
|
V:0, I:2 | 769 | Källkodsindenter för C, C++, Objective-C, C# och Java |
bcpp
|
V:0, I:0 | 114 | C(++) förskönare |
xmlindent
|
V:0, I:0 | 52 | Omformatering av XML-ström |
global
|
V:0, I:1 | 1923 | Verktyg för att söka och bläddra i källkod |
exuberant-ctags
|
V:1, I:14 | 341 | skapa taggfilsindex för källkodsdefinitioner |
universal-ctags
|
V:1, I:12 | 4238 | skapa taggfilsindex för källkodsdefinitioner |
Felsökning är en viktig del av programmeringsaktiviteter. Att veta hur man felsöker program gör dig till en bra Debian-användare som kan producera meningsfulla felrapporter.
Den primära felsökaren på Debian är
gdb(1) som gör att du kan inspektera ett program medan
det körs.
Låt oss installera gdb och relaterade program enligt
följande.
# apt-get install gdb gdb-doc build-essential devscripts
Bra handledning av gdb kan hittas:
"info gdb"
"Felsökning med GDB" i
/usr/share/doc/gdb-doc/html/gdb/index.html
Här följer ett enkelt exempel på hur du använder gdb(1)
på ett "program" som kompilerats med alternativet
"-g" för att ta fram felsökningsinformation.
$ 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
|
Tips |
|---|---|
|
Många |
Eftersom alla installerade binärfiler som standard bör vara strippade på
Debian-systemet, tas de flesta felsökningssymbolerna bort i det normala
paketet. För att kunna felsöka Debian-paket med gdb(1)
måste *-dbgsym-paket installeras
(t.ex. coreutils-dbgsym när det gäller
coreutils). Källpaketen genererar
*-dbgsym-paket automatiskt tillsammans med normala binära
paket och dessa felsökningspaket placeras separat i debian-debug-arkivet. Se artiklar på Debian Wiki för mer
information.
Om ett paket som ska felsökas inte tillhandahåller sitt
*-dbgsym-paket måste du installera det efter att ha byggt
upp det på följande sätt.
$ 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 ./
Åtgärda buggar om det behövs.
Förbättra paketversionen till en som inte kolliderar med officiella
Debian-versioner, t.ex. en som har tillägget "+debug1"
vid omkompilering av befintlig paketversion, eller en som har tillägget
"~pre1" vid kompilering av outgiven paketversion genom
följande.
$ dch -i
Kompilera och installera paket med debug-symboler med följande.
$ export DEB_BUILD_OPTIONS="nostrip noopt" $ debuild $ cd .. $ sudo debi package_name*.changes
Du måste kontrollera paketets byggskript och se till att du använder
"CFLAGS=-g -Wall" för att kompilera binärfiler.
När du stöter på programkrasch är det en bra idé att rapportera felrapport med klippt och klistrat backtrace-information.
Bakspårningen kan hämtas av gdb(1) med hjälp av något av
följande tillvägagångssätt:
Crash-in-GDB-metoden:
Kör programmet från GDB.
Krascha programmet.
Skriv "bt" i GDB-prompten.
Först till kvarn när olyckan är framme:
Uppdatera filen "/etc/security/limits.conf" så att den innehåller följande:
* soft core unlimited
Skriv "ulimit -c unlimited" i shellprompten.
Kör programmet från denna shell-prompt.
Krascha programmet för att producera en kärndumpfil.
Läs in minnesdumpfilen till GDB som
"gdb gdb ./program_binary core" .
Skriv "bt" i GDB-prompten.
Vid oändlig loop eller fruset tangentbord kan du tvinga programmet att
krascha genom att trycka på Ctrl\ eller
Ctrl-C eller köra "kill -ABRT
PID". (Se Avsnitt 9.4.12, ”Döda en process”)
|
Tips |
|---|---|
|
Ofta ser man en backtrace där en eller flera av de översta raderna är i
" $ MALLOC_CHECK_=2 gdb hello |
Tabell 12.14. Lista över avancerade gdb-kommandon
| kommando | beskrivning för ledningsmål |
|---|---|
(gdb) tråd tillämpa alla bt |
få en backtrace för alla trådar för flertrådade program |
(gdb) bt full |
hämta parametrar som kom på stacken i funktionsanrop |
(gdb) tråd gäller alla bt full |
få en backtrace och parametrar som en kombination av de föregående alternativen |
(gdb) tråd gäller alla bt full 10 |
få en backtrace och parametrar för topp 10-anrop för att skära bort irrelevanta utdata |
(gdb) ställa in loggning på |
skriva logg över gdb-utdata till en fil (standard är
"gdb.txt") |
Använd ldd(1) för att ta reda på hur beroende ett program
är av bibliotek enligt följande.
$ 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)
För att ls(1) ska fungera i en `chroot`-miljö måste
ovanstående bibliotek finnas tillgängliga i din `chroot`-miljö.
Det finns flera verktyg för dynamisk anropsspårning tillgängliga i Debian. Se Avsnitt 9.4, ”Övervakning, kontroll och start av programaktiviteter”.
Om ett GNOME-program preview1 har fått ett X-fel, bör du
se ett meddelande enligt följande.
The program 'preview1' received an X Window System error.
Om så är fallet kan du prova att köra programmet med
"--sync" och bryta på funktionen
"gdk_x_error" för att få en backtrace.
Det finns flera verktyg för att upptäcka minnesläckor i Debian.
Tabell 12.15. Lista över verktyg för detektering av minnesläckage
| paket | popcon | storlek | beskrivning |
|---|---|---|---|
libc6-dev
|
V:266, I:585 | 13574 | mtrace(1): malloc-felsökningsfunktionalitet i glibc |
valgrind
|
V:5, I:35 | 87847 | minnesfelsökare och profilerare |
electric-fence
|
V:0, I:2 | 69 | malloc(3) felsökare |
libdmalloc5
|
V:0, I:0 | 380 | bibliotek för minnesallokering för felsökning |
duma
|
V:0, I:0 | 297 | bibliotek för att upptäcka buffertöverskridanden och -underskridanden i C- och C++-program |
leaktracer
|
V:0, I:0 | 56 | minnesläcksökare för C++-program |
Tabell 12.16. Lista över byggverktygspaket
| paket | popcon | storlek | dokumentation |
|---|---|---|---|
make
|
V:126, I:566 | 1762 | "info make" tillhandahålls av make-doc |
autoconf
|
V:28, I:210 | 2197 | "info autoconf" tillhandahålls av
autoconf-doc |
automake
|
V:28, I:210 | 1933 | "info automake" tillhandahålls av
automake1.10-doc |
libtool
|
V:24, I:193 | 1245 | "info libtool" tillhandahålls av
libtool-doc |
cmake
|
V:18, I:119 | 41613 | cmake(1) make-system med öppen källkod och
plattformsoberoende |
ninja-build
|
V:7, I:51 | 456 | ninja(1) litet byggsystem närmast i anda till Make |
meson
|
V:6, I:28 | 4183 | meson(1) högproduktivt byggsystem på toppen av
ninja |
xutils-dev
|
V:0, I:7 | 1495 | imake(1), xmkmf(1), etc. |
Make är ett verktyg för att underhålla grupper
av program. Vid exekvering av make(1) läser
make regelfilen "Makefile" och
uppdaterar ett mål om det är beroende av förutsättningsfiler som har ändrats
sedan målet senast ändrades, eller om målet inte existerar. Exekveringen av
dessa uppdateringar kan ske samtidigt.
Syntaxen för regelfilen är följande.
target: [ prerequisites ... ] [TAB] command1 [TAB] -command2 # ignore errors [TAB] @command3 # suppress echoing
Här är "[TAB]" en TAB-kod. Varje rad tolkas av skalet
efter att variabeln har bytts ut. Använd "\" i slutet av
en rad för att fortsätta skriptet. Använd "$$" för att
ange "$" för miljövärden i ett skalskript.
Implicita regler för mål och förutsättningar kan skrivas till exempel enligt följande.
%.o: %.c header.h
Här innehåller målet tecknet "%" (exakt ett av
dem). "%" kan matcha alla icke-tomma delsträngar i de
faktiska målfilnamnen. Förutsättningarna använder också
"%" för att visa hur deras namn förhåller sig till det
faktiska målnamnet.
Tabell 12.17. Lista över make automatic-variabler
| automatisk variabel | värde |
|---|---|
$@ |
lokation |
$< |
första förutsättningen |
$? |
alla nyare förutsättningar |
$^ |
alla förkunskapskrav |
$* |
"%" matchad stam i målmönstret |
Tabell 12.18. Lista över utvidgningar av märkesvariabler
| variabel expansion | beskrivning |
|---|---|
foo1 := bar |
engångsexpansion |
foo2 = bar |
rekursiv expansion |
foo3 += bar |
bifoga |
Kör "make -p -f/dev/null" för att se automatiska interna
regler.
Autotools är en uppsättning programmeringsverktyg som är utformade för att hjälpa till att göra källkodspaket portabla till många Unix-liknande system.
Autoconf är ett verktyg för att producera
ett skalskript "configure" från
"configure.ac".
"configure" används senare för att producera
"Makefile" från "Makefile.in"-mallen.
Automake är ett verktyg för att producera
"Makefile.in" från "Makefile.am".
Libtool är ett skalskript för att lösa problemet med programvaruportabilitet när delade bibliotek kompileras från källkod.
|
Varning |
|---|---|
|
Skriv inte över systemfiler med dina kompilerade program när du installerar dem. |
Debian rör inte filer i "/usr/local/" eller
"/opt". Så om du kompilerar ett program från källkod,
installera det i "/usr/local/" så att det inte stör
Debian.
$ cd src $ ./configure --prefix=/usr/local $ make # this compiles program $ sudo make install # this installs the files in the system
Om du har originalkällan och om den använder
autoconf(1)/automake(1) och om du kan
komma ihåg hur du konfigurerade den, gör du så här för att avinstallera
programmet.
$ ./configure all-of-the-options-you-gave-it
$ sudo make uninstall
Alternativt, om du är helt säker på att installationsprocessen bara lägger
filer under "/usr/local/" och att det inte finns något
viktigt där, kan du radera allt innehåll på följande sätt.
# find /usr/local -type f -print0 | xargs -0 rm -f
Om du inte är säker på var filer är installerade bör du överväga att använda
checkinstall(8) från
checkinstall-paketet, vilket ger en ren sökväg för
avinstallationen. Det finns nu stöd för att skapa ett Debian-paket med
alternativet "-D".
Systemet för programvaruutveckling har utvecklats:
Autotools på toppen av Make har varit de facto-standarden för den portabla bygginfrastrukturen sedan 1990-talet. Detta är extremt långsamt.
CMake, som ursprungligen släpptes 2000, förbättrade hastigheten avsevärt men byggdes ursprungligen på toppen av den i sig långsamma Make. (Nu kan Ninja vara dess backend.)
Ninja, som ursprungligen släpptes 2012, är tänkt att ersätta Make för den ytterligare förbättrade bygghastigheten och är utformad för att få sina indatafiler genererade av ett byggsystem på högre nivå.
Meson, som ursprungligen släpptes 2013, är det nya populära och snabba byggsystemet på högre nivå som använder Ninja som backend.
Se dokument som finns på"The Meson Build system" och "The Ninja build system".
Enkla interaktiva dynamiska webbsidor kan skapas på följande sätt.
Frågorna presenteras för webbläsaren med hjälp av HTML-formulär.
Genom att fylla i och klicka på formulärposterna skickas en av följande URL-strängar med kodade parametrar från webbläsaren till webbservern.
"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" i URL ersätts med ett tecken med hexadecimalt
nn-värde.
Miljövariabeln är inställd som: "QUERY_STRING="VAR1=VAL1 VAR2=VAL2
VAR3=VAL3"".
CGI-program (vilket som helst av
"program.*") på webbservern kör sig själv med
miljövariabeln "$QUERY_STRING".
stdout från CGI-programmet skickas till webbläsaren och
presenteras som en interaktiv dynamisk webbsida.
Av säkerhetsskäl är det bättre att inte själv skapa nya hack för att tolka CGI-parametrar. Det finns etablerade moduler för dem i Perl och Python. PHP kommer med dessa funktioner. När lagring av klientdata behövs används HTTP-cookies. När databehandling på klientsidan behövs används ofta Javascript.
För mer information, se Common Gateway Interface, Apache Software Foundation och JavaScript.
Att söka på "CGI tutorial" på Google genom att skriva in den kodade URL:en https://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial direkt i webbläsarens adress är ett bra sätt att se CGI-skriptet i aktion på Googles server.
Det finns program för att konvertera källkoder.
Om du vill skapa ett Debian-paket ska du läsa följande.
Kapitel 2, Debians pakethantering för att förstå det grundläggande paketsystemet
Avsnitt 2.7.13, ”Portering av ett paket till det stabila systemet” att förstå den grundläggande portningsprocessen
Avsnitt 9.11.4, ”Chroot-system” för att förstå grundläggande chroot-tekniker
debuild(1) och sbuild(1)
Avsnitt 12.5.2, ”Felsökning av Debian-paketet” för omkompilering för felsökning
Guide för Debians
underhållsansvariga (paketet debmake-doc )
Debian Developer's
Reference (paketet med referenser för utvecklare
)
Debians policyhandbok (paketet
debian-policy )
Det finns paket som debmake, dh-make,
dh-make-perl etc. som hjälper till med paketering.