Índice
Disponibilizo algumas dicas para as pessoas aprenderem programação no sistema Debian o suficiente para rastrear o código fonte do pacote. Aqui estão pacotes notáveis e pacotes de documentação correspondentes para programação.
Estão disponíveis referências online ao escrever "man
nome
" após instalar os pacotes manpages
e
manpages-dev
. As referências online ás ferramentas GNU
está disponíveis ao escrever "info nome_do_programa
" após
instalar os pacotes de documentação pertinentes. Poderá ter de incluir os
arquivos contrib
e non-free
adicionalmente ao arquivo main
pois algumas documentações
GFDL não são consideradas compatíveis com DFSG.
Please consider to use version control system tools. See Secção 10.5, “Git”.
Atenção | |
---|---|
Não use " |
Cuidado | |
---|---|
Deve instalar os programas compilados directamente a partir da fonte em
" |
Dica | |
---|---|
Os Exemplos de código da criação de "Song 99 Bottles of Beer" devem dar-lhe uma boa ideia de praticamente todas as linguagens de programação. |
O script de shell é um ficheiro de texto com o bit de execução definido e contém os comandos no seguinte formato.
#!/bin/sh ... command lines
A primeira linha especifica o interpretador shell que lê e executa o conteúdo deste ficheiro.
Reading shell scripts is the best way to understand how a Unix-like system works. Here, I give some pointers and reminders for shell programming. See "Shell Mistakes" (https://www.greenend.org.uk/rjk/2001/04/shell.html) to learn from mistakes.
Ao contrário do modo interativo de shell (veja Secção 1.5, “O comando simples da shell” e Secção 1.6, “Processamento de texto estilo Unix”), os scripts de shell usam frequentemente parâmetros, condicionais e ciclos.
Many system scripts may be interpreted by any one of POSIX shells (see Tabela 1.13, “Lista de programas da shell”).
The default non-interactive POSIX shell "/usr/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
.
Evite escrever um script de shell com bashisms ou zshisms para fazê-loportável entre todas as shells
do POSIX. Pode verificar isto a usar o checkbashisms
(1).
Tabela 12.1. Lista dos 'bashisms' típicos
Bom: POSIX | Evitar: 'bashism' |
---|---|
if [ "$foo" = "$bar" ] ; then … |
if [ "$foo" == "$bar" ] ; then … |
diff -u file.c.orig file.c |
diff -u file.c{.orig,} |
mkdir /foobar /foobaz |
mkdir /foo{bar,baz} |
funcname() { … } |
function funcname() { … } |
formato octal: "\377 " |
formato hexadecimal: "\xff " |
O comando "echo
" tem de ser usado com os seguintes
cuidados porque a implementação dele difere entre o integrado na shell e os
comandos externos.
Evite usar quaisquer opções de comando excepto "-n
".
Evite usar sequências de escape na cadeia porque o manuseamento dele varia.
Nota | |
---|---|
Apesar da opção " |
Dica | |
---|---|
Use o comando " |
Parâmetros de shell especiais são frequentemente usados no script shell.
Tabela 12.2. Lista de parâmetros da shell
parâmetro da shell | valor |
---|---|
$0 |
nome da shell ou script de shell |
$1 |
primeiro(1) argumento shell |
$9 |
nono(9) argumento shell |
$# |
quantidade de parâmetros de posição |
"$*" |
"$1 $2 $3 $4 … " |
"$@" |
"$1" "$2" "$3" "$4" … |
$? |
estado de saída do comando mais recente |
$$ |
PID deste script shell |
$! |
PID da tarefa de fundo iniciada mais recentemente |
As expansões de parâmetro básicas a lembrar são as seguintes.
Tabela 12.3. Lista de expansões de parâmetros de shell
formato da expressão do parâmetro | valor se var estiver definido |
valor se var não estiver definido |
---|---|---|
${var:-cadeia} |
"$var " |
"cadeia " |
${var:+cadeia} |
"cadeia " |
"null " |
${var:=cadeia} |
"$var " |
"cadeia " (e corra "var=cadeia ") |
${var:?cadeia} |
"$var " |
echo "cadeia " para stderr (e termina com erro) |
Aqui, o símbolo ortográfico dois pontos ":
" em todas
estas operações é na realidade opcional.
com ":
" = teste de
operador para existe e não nulo
sem ":
" = teste de
operador para apenas existe
Tabela 12.4. Lista de substituições de parâmetros de shell chave
formato de substituição de parâmetro | resultado |
---|---|
${var%suffix} |
remover o modelo de sufixo menor |
${var%%suffix} |
remover o modelo de sufixo maior |
${var#prefix} |
remover o modelo de prefixo menor |
${var##prefix} |
remover o modelo de prefixo maior |
Cada comando retorna um estado de saída que pode ser usado para expressões condicionais.
Sucesso: 0 ("True")
Erro: não 0 ("False")
Nota | |
---|---|
"0" no contexto condicional da shell significa "Verdadeiro", enquanto "0" no contexto condicional de C significa "Falso". |
Nota | |
---|---|
" |
Os idiomas condicionais básicos a lembrar são os seguintes.
"comando &&
se_sucesso_corre_também_este_comando || true
"
"comando ||
se_não_sucesso_corre_também_este_comando ||
true
"
Um fragmento de script de multi-linhas como o seguinte
if [ conditional_expression ]; then if_success_run_this_command else if_not_success_run_this_command fi
Aqui o "|| true
" final foi necessário para assegurar que
estes script de shell não termina acidentalmente nesta linha quando a shell
é invocada com a flag "-e
".
Tabela 12.5. Lista de operadores de comparação de ficheiros na expressão condicional
equação | condição para retornar o verdadeiro lógico |
---|---|
-e ficheiro |
ficheiro existe |
-d ficheiro |
ficheiro existe e é um diretório |
-f ficheiro |
ficheiro existe e é um ficheiro normal |
-w ficheiro |
ficheiro existe e pode-se escrever nele |
-x ficheiro |
ficheiro existe e é executável |
ficheiro1 -nt
ficheiro2 |
ficheiro1 é mais recente que ficheiro2 (modificação) |
ficheiro1 -ot
ficheiro2 |
ficheiro1 é mais antigo que ficheiro2 (modificação) |
ficheiro1 -ef
ficheiro2 |
ficheiro1 e ficheiro2 estão no mesmo aparelho e no mesmo número de inode |
Tabela 12.6. Lista de operadores de comparação de cadeias na expressão condicional
equação | condição para retornar o verdadeiro lógico |
---|---|
-z str |
o comprimento de str é zero |
-n str |
o comprimento de str não é zero |
str1 = str2 |
str1 and str2 são iguais |
str1 != str2 |
str1 and str2 não são iguais |
str1 < str2 |
str1 ordena antes de str2 (dependente do locale) |
str1 > str2 |
str1 ordena após str2 (dependente do locale) |
Os operadores de comparação Aritmética de
inteiros na expressão regular são "-eq
",
"-ne
", "-lt
",
"-le
", "-gt
" e
"-ge
".
Existem vários idiomas de ciclo para usar na shell POSIX.
"for x in foo1 foo2 … ; do command ; done
" faz ciclos ao
atribuir itens da lista "foo1 foo2 …
" à variável
"x
" e a executar o "comando
".
"while condition ; do command ; done
" repete o
"comando
" enquanto a "condição
" for
verdadeira.
"until condition ; do command ; done
" repete o
"comando
" enquanto a "condição
" não
for verdadeira.
"break
" permite sair do ciclo.
"continue
" permite resumir a próxima interacção do ciclo.
Dica | |
---|---|
A interacção numérica tipo linguagem C pode ser
realizada a usar |
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 Secção 4.5.2, “O moderno sistema de gestão centralizado”)
A shell processa um script rudemente como a seguinte sequência.
A shell lê uma linha.
A shell agrupa uma parte de uma linha como um
testemunho se estiver dentro de "…"
ou
'…'
.
A shell divide a outra parte de uma linha em testemunhos como o seguinte.
Espaços em branco: espaço
tab nova-linha
Meta-caracteres: < > | ; & ( )
A shell verifica a palavra reservada para
cada testemunho para ajustar o comportamento dele se não dentro de
"…"
ou '…'
.
palavra reservada: if then elif
else fi for in while unless do done case esac
A shell expande o alias se não estiver
dentro de "…"
ou '…'
.
A shell expande o til se não dentro de
"…"
ou '…'
.
"~
" → diretório home do utilizador atual
"~utilizador
" → diretório home do
utilizador
A shell expande o parâmetro ao seu valor
se não dentro de '…'
.
parâmetro:
"$PARAMETER
" ou "${PARAMETER}
"
A shell expande a substituição do comando
se não dentro de '…'
.
"$( comando )
" → o resultado do
"comando
"
"` comando `
" → o resultado do
"comando
"
A shell expande o glob nome_de-caminho
aos nomes de ficheiros correspondentes se não dentro de
"…"
ou '…'
.
*
→ quaisquer caracteres
?
→ um caractere
[…]
→ qualquer um dos caracteres em
"…
"
A shell procura o comando a partir do seguinte e executa-o.
definição de função
comando builtin
ficheiro executável em
"$PATH
"
A shell vai à próxima linha e repete este processo outra vez a partir do topo desta sequência.
Citações singulares (') dentro de aspas não têm efeito.
Executar "set -x
" na shell ou invocar a shell com a opção
"-x
" faz a shell escrever todos os comandos
executados. Isto é muito útil para depuração.
De modo a tornar o seu programa de shell o mais portável possível entre os sistemas Debian, é uma boa ideia limitar os programas utilitários àqueles disponibilizados pelos pacotes essenciais.
"aptitude search ~E
" lista os pacotes essenciais.
"dpkg -L nome_do-pacote |grep
'/man/man.*/'
" lista as manpages (manuais) para comandos
oferecidos pelo pacote
nome_do_pacote
.
Tabela 12.7. Lista de pacotes que contém programas utilitários pequenos para scripts de shell
pacote | popcon | tamanho | descrição |
---|---|---|---|
dash
|
V:884, I:997 | 191 | small and fast POSIX-compliant shell for sh |
coreutils
|
V:880, I:999 | 18307 | utilitários de núcleo GNU |
grep
|
V:782, I:999 | 1266 | GNU grep , egrep and
fgrep |
sed
|
V:790, I:999 | 987 | GNU sed |
mawk
|
V:442, I:997 | 285 | small and fast awk |
debianutils
|
V:907, I:999 | 224 | utilitários variados específicos do Debian |
bsdutils
|
V:519, I:999 | 356 | utilitários básicos do 4.4BSD-Lite |
bsdextrautils
|
V:596, I:713 | 339 | extra utilities from 4.4BSD-Lite |
moreutils
|
V:15, I:38 | 231 | utilitários Unix adicionais |
Dica | |
---|---|
Although |
See Secção 1.6, “Processamento de texto estilo Unix” for examples.
Tabela 12.8. List of interpreter related packages
pacote | popcon | tamanho | documentação |
---|---|---|---|
dash
|
V:884, I:997 | 191 | sh: small and fast POSIX-compliant shell for
sh |
bash
|
V:838, I:999 | 7175 | sh: "info bash " provided by
bash-doc |
mawk
|
V:442, I:997 | 285 | AWK: small and fast awk |
gawk
|
V:285, I:349 | 2906 | AWK: "info gawk " provided by
gawk-doc |
perl
|
V:707, I:989 | 673 | 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 | 171 | REPL for Perl: reply (1) |
libdevel-repl-perl
|
V:0, I:0 | 237 | REPL for Perl: re.pl (1) |
python3
|
V:718, I:953 | 81 | Python: python3 (1) and html
pages provided by python3-doc |
tcl
|
V:25, I:218 | 21 | Tcl: tcl (3) and detail manual
pages provided by tcl-doc |
tk
|
V:20, I:211 | 21 | Tk: tk (3) and detail manual
pages provided by tk-doc |
ruby
|
V:86, I:208 | 29 | 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 Secção 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.
Tabela 12.9. List of dialog programs
pacote | popcon | tamanho | descrição |
---|---|---|---|
x11-utils
|
V:192, I:566 | 651 | xmessage (1): mostra uma mensagem ou questão numa janela
(X) |
whiptail
|
V:284, I:996 | 56 | mostra caixas de diálogo amigas do utilizador a partir de scripts de shell (newt) |
dialog
|
V:11, I:99 | 1227 | mostra caixas de diálogo amigas do utilizador a partir de scripts de shell (ncurses) |
zenity
|
V:76, I:363 | 183 | display graphical dialog boxes from shell scripts (GTK) |
ssft
|
V:0, I:0 | 75 | Ferramenta Frontend de Scripts de Shell (wrapper para o zenity, kdialog e dialog com o gettext) |
gettext
|
V:56, I:259 | 5818 | "/usr/bin/gettext.sh ": traduz mensagem |
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 Secção 9.4.10, “Arrancar um programa a partir da 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.
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 }' |
Isto é equivalente a qualquer uma das seguintes linhas.
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' |
Este último é um enigma. Aproveitei-me das seguintes funcionalidades do Perl.
O espaço em branco é opcional.
Existe a conversão automática de números para cadeia.
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.
Tabela 12.10. List of compiler related packages
pacote | popcon | tamanho | descrição |
---|---|---|---|
gcc
|
V:167, I:550 | 36 | GNU C compiler |
libc6-dev
|
V:248, I:567 | 12053 | GNU C Library: Development Libraries and Header Files |
g++
|
V:56, I:501 | 13 | GNU C++ compiler |
libstdc++-10-dev
|
V:14, I:165 | 17537 | GNU Standard C++ Library v3 (development files) |
cpp
|
V:334, I:727 | 18 | GNU C preprocessor |
gettext
|
V:56, I:259 | 5818 | GNU Internationalization utilities |
glade
|
V:0, I:5 | 1204 | GTK User Interface Builder |
valac
|
V:0, I:4 | 725 | C# like language for the GObject system |
flex
|
V:7, I:73 | 1243 | LEX-compatible fast lexical analyzer generator |
bison
|
V:7, I:80 | 3116 | YACC-compatible parser generator |
susv2
|
I:0 | 16 | buscar "The Single UNIX Specifications v2" |
susv3
|
I:0 | 16 | buscar "The Single UNIX Specifications v3" |
susv4
|
I:0 | 16 | fetch "The Single UNIX Specifications v4" |
golang
|
I:20 | 11 | Go programming language compiler |
rustc
|
V:3, I:14 | 8860 | Rust systems programming language |
haskell-platform
|
I:1 | 12 | Standard Haskell libraries and tools |
gfortran
|
V:6, I:62 | 15 | GNU Fortran 95 compiler |
fpc
|
I:2 | 103 | Free Pascal |
Here, Secção 12.3.3, “Flex — um Lex melhor” and Secção 12.3.4, “Bison — um Yacc melhor” are included to indicate how compiler-like program can be written in C language by compiling higher level description into C language.
Pode configurar um ambiente apropriado para compilar programas escritos na linguagem de programação C com o seguinte.
# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential
O pacote libc6-dev
, isto é, a biblioteca C GNU,
disponibiliza uma biblioteca standard
C a qual é uma colecção de ficheiros cabeçalho e rotinas de
biblioteca usadas pela linguagem de programação C.
Veja referências para C nos seguintes.
"info libc
" (Referência de funções da biblioteca C)
gcc
(1) e "info gcc
"
cada-nome_de_função_da_biblioteca_C
(3)
Kernighan & Ritchie, "A Linguagem de Programação C", 2ª edição (Prentice Hall)
Um simples exemplo, "example.c
" pode ser compilado com
uma biblioteca "libm
" num executável
"run_example
" com o seguinte.
$ 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
Aqui, o "-lm
" é necessário para ligar a biblioteca
"/usr/lib/libm.so
" do pacote libc6
para o sqrt
(3). A biblioteca real está em
"/lib/
" com o nome de ficheiro
"libm.so.6
", o qual é uma ligação simbólica para
"libm-2.7.so
".
Olhe ao último parâmetro no texto resultante. Existem mais de 10 caracteres
mesmo com "%10s
" especificado.
O uso de funções de operação de memória de ponteiro sem verificações de
limites como em sprintf
(3) e
strcpy
(3), está descontinuado para prevenir exploits de
sobrelotação do buffer que influenciam os efeitos de transbordo em cima. Em
vez disso, use snprintf
(3) e
strncpy
(3).
O Flex é um gerador rápido de análise léxica compatível com o Lex.
O tutorial do flex
(1) encontra-se em "info
flex
".
Many simple examples can be found under
"/usr/share/doc/flex/examples/
". [7]
Vários pacotes disponibilizam um gerador LR parser ou LALR parser compatível em frente com o Yacc em Debian.
O tutorial para o bison
(1) encontra-se em "info
bison
".
Tem de disponibilizar as suas próprias chamadas "main()
"
e "yyerror()
". "main()
" chama
"yyparse()
" que chama "yylex()
",
geralmente criada com Flex.
Here is an example to create a simple terminal calculator program.
Let's create example.y
:
/* calculator source for bison */ %{ #include <stdio.h> extern int yylex(void); extern int yyerror(char *); %} /* declare tokens */ %token NUMBER %token OP_ADD OP_SUB OP_MUL OP_RGT OP_LFT OP_EQU %% calc: | calc exp OP_EQU { printf("Y: RESULT = %d\n", $2); } ; exp: factor | exp OP_ADD factor { $$ = $1 + $3; } | exp OP_SUB factor { $$ = $1 - $3; } ; factor: term | factor OP_MUL term { $$ = $1 * $3; } ; term: NUMBER | OP_LFT exp OP_RGT { $$ = $2; } ; %% int main(int argc, char **argv) { yyparse(); } int yyerror(char *s) { fprintf(stderr, "error: '%s'\n", s); }
Let's create, example.l
:
/* calculator source for flex */ %{ #include "example.tab.h" %} %% [0-9]+ { printf("L: NUMBER = %s\n", yytext); yylval = atoi(yytext); return NUMBER; } "+" { printf("L: OP_ADD\n"); return OP_ADD; } "-" { printf("L: OP_SUB\n"); return OP_SUB; } "*" { printf("L: OP_MUL\n"); return OP_MUL; } "(" { printf("L: OP_LFT\n"); return OP_LFT; } ")" { printf("L: OP_RGT\n"); return OP_RGT; } "=" { printf("L: OP_EQU\n"); return OP_EQU; } "exit" { printf("L: exit\n"); return YYEOF; } /* YYEOF = 0 */ . { /* ignore all other */ } %%
Then execute as follows from the shell prompt to try this:
$ 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 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.
Dica | |
---|---|
Configuring your favorite editor ( |
Tabela 12.12. Lista de ferramentas para análise de código estático
pacote | popcon | tamanho | descrição |
---|---|---|---|
vim-ale
|
I:0 | 2591 | Asynchronous Lint Engine for Vim 8 and NeoVim |
vim-syntastic
|
I:3 | 1379 | Syntax checking hacks for vim |
elpa-flycheck
|
V:0, I:1 | 808 | modern on-the-fly syntax checking for Emacs |
elpa-relint
|
V:0, I:0 | 147 | Emacs Lisp regexp mistake finder |
cppcheck-gui
|
V:0, I:1 | 7224 | tool for static C/C++ code analysis (GUI) |
shellcheck
|
V:2, I:13 | 18987 | lint tool for shell scripts |
pyflakes3
|
V:2, I:15 | 20 | passive checker of Python 3 programs |
pylint
|
V:4, I:20 | 2018 | Verificador estático de código Python |
perl
|
V:707, I:989 | 673 | interpretador com verificador de código estático interno:
B::Lint (3perl) |
rubocop
|
V:0, I:0 | 3247 | Ruby static code analyzer |
clang-tidy
|
V:2, I:11 | 21 | clang-based C++ linter tool |
splint
|
V:0, I:2 | 2320 | ferramenta para verificação estática de programas C por bugs |
flawfinder
|
V:0, I:0 | 205 | ferramenta para examinar código fonte C/C++ e procurar por fraquezas na segurança |
black
|
V:3, I:13 | 660 | uncompromising Python code formatter |
perltidy
|
V:0, I:4 | 2493 | Perl script indenter and reformatter |
indent
|
V:0, I:7 | 431 | C language source code formatting program |
astyle
|
V:0, I:2 | 785 | Source code indenter for C, C++, Objective-C, C#, and Java |
bcpp
|
V:0, I:0 | 111 | C(++) beautifier |
xmlindent
|
V:0, I:1 | 53 | XML stream reformatter |
global
|
V:0, I:2 | 1908 | Source code search and browse tools |
exuberant-ctags
|
V:2, I:20 | 341 | build tag file indexes of source code definitions |
universal-ctags
|
V:1, I:11 | 3386 | 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.
O depurador principal em Debian é o
gdb
(1) que lhe permite inspeccionar um programa enquanto
ele é executado.
Vamos instalar o gdb
e programas relacionados com o
seguinte.
# 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
Dica | |
---|---|
Muitos comandos do |
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 ./
Corrigir bugs se necessário.
Mude a versão de pacote para uma que não colida com as versões oficiais de
Debian, por exemplo, uma adicionada com "+debug1
" quando
se recompila uma versão de pacote existente, ou uma adicionada com
"~pre1
" quando se compila uma versão de pacote ainda não
lançada com o seguinte.
$ dch -i
Compilar e instalar pacotes com símbolos de depuração com o seguinte.
$ export DEB_BUILD_OPTIONS="nostrip noopt" $ debuild $ cd .. $ sudo debi package_name*.changes
Necessita verificar os scripts de construção do pacote e assegurar o uso de
"CFLAGS=-g -Wall
" para compilar binários.
Quando encontrar um crash num programa, é uma boa ideia enviar um relatório de bug com informação de backtrace copiada-e-colada.
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
Secção 9.4.12, “Matar um processo”)
Dica | |
---|---|
Muitas vezes, vê um backtrace onde uma ou mais linhas do topo estão em
" $ MALLOC_CHECK_=2 gdb hello |
Tabela 12.14. Lista de comandos gdb avançados
comando | descrição dos objetivos do comando |
---|---|
(gdb) thread apply all bt |
obter um backtrace para todos os processos de um programa de multi-processo |
(gdb) bt full |
obter parâmetros que vêm na pilha das chamadas de função |
(gdb) thread apply all bt full |
obtém um backtrace e parâmetros como a combinação das opções precedentes |
(gdb) thread apply all bt full 10 |
obter um backtrace e parâmetros para as 10 chamadas do topo para cortar resultados irrelevantes |
(gdb) set logging on |
escreve um relatório dos resultados do gdb para um
ficheiro (a predefinição é "gdb.txt ") |
Use o ldd
(1) para encontrar uma dependência de um
programa em bibliotecas com o seguinte.
$ ldd /usr/bin/ls librt.so.1 => /lib/librt.so.1 (0x4001e000) libc.so.6 => /lib/libc.so.6 (0x40030000) libpthread.so.0 => /lib/libpthread.so.0 (0x40153000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Para que o ls
(1) funcione num ambiente 'chroot', as
bibliotecas em cima têm de estar disponíveis no seu ambiente 'chroot'.
There are several dynamic call tracing tools available in Debian. See Secção 9.4, “Monitorizar, controlar e iniciar as atividades de programas”.
Se o programa do GNOME preview1
recebeu um erro do X,
deverá ver a mensagem que a seguir.
The program 'preview1' received an X Window System error.
Neste caso, pode tentar correr o programa com "--sync
" e
quebrar a função "gdk_x_error
" de modo a obter um
backtrace.
Aqui estão várias ferramentas de detecção de fugas de memória em Debian.
Tabela 12.15. Lista de ferramentas de detecção de fugas de memória
pacote | popcon | tamanho | descrição |
---|---|---|---|
libc6-dev
|
V:248, I:567 | 12053 | mtrace (1): funcionalidades de depuração do malloc em
glibc |
valgrind
|
V:6, I:37 | 78191 | depurador e perfilador de memória |
electric-fence
|
V:0, I:3 | 73 | o depurador malloc (3) |
libdmalloc5
|
V:0, I:2 | 390 | biblioteca de depuração de alocação de memória |
duma
|
V:0, I:0 | 296 | library to detect buffer overruns and under-runs in C and C++ programs |
leaktracer
|
V:0, I:1 | 56 | rastreador de fugas de memória para programas C++ |
Tabela 12.16. List of build tool packages
pacote | popcon | tamanho | documentação |
---|---|---|---|
make
|
V:151, I:555 | 1592 | "info make " disponibilizado por
make-doc |
autoconf
|
V:31, I:230 | 2025 | "info autoconf " disponibilizado por
autoconf-doc |
automake
|
V:30, I:228 | 1837 | "info automake " disponibilizado por
automake1.10-doc |
libtool
|
V:25, I:212 | 1213 | "info libtool " provided by libtool-doc |
cmake
|
V:17, I:115 | 36607 | cmake (1) cross-platform, open-source make system |
ninja-build
|
V:6, I:41 | 428 | ninja (1) small build system closest in spirit to Make |
meson
|
V:3, I:22 | 3759 | meson (1) high productivity build system on top of
ninja |
xutils-dev
|
V:0, I:9 | 1484 | imake (1), xmkmf (1), etc. |
O Make é um utilitário para manutenção de grupos
de programas Após a execução do make
(1), o
make
lê o ficheiro de regras,
"Makefile
" e atualiza um alvo se depender de ficheiros
pré-requisitados que foram modificados desde que o alvo foi modificado por
último, ou se o alvo não existir. A execução destas atualizações pode
ocorrer concorrentemente.
A regra de sintaxe do ficheiro é a seguinte.
target: [ prerequisites ... ] [TAB] command1 [TAB] -command2 # ignore errors [TAB] @command3 # suppress echoing
Aqui "[TAB]
" é um código TAB. Cada linha é interpretada
pela shell após fazer a substituição da variável. Utilize
"\
" no final de uma linha para continuar o script. Use
"$$
" para inserir "$
" para valores de
ambiente para um script de shell.
Podem ser escritas regras implícitas para o destino e pré-requisitos, por exemplo, com o seguinte.
%.o: %.c header.h
Aqui, o alvo contém o caractere "%
" (exatamente um
deles). O "%
" pode corresponder a qualquer subcadeia não
vazia nos nomes de ficheiros do próprio alvo. Os pré-requisitos usam
igualmente "%
" para mostrar como os seus nomes estão
relacionados ao próprio nome do alvo.
Tabela 12.17. Lista de variáveis automáticas do make
variável automática | valor |
---|---|
$@ |
alvo |
$< |
primeiro pré-requisito |
$? |
todos os novos pré-requisitos |
$^ |
todos os pré-requisitos |
$* |
"% " estaminal correspondente no modelo de destino |
Tabela 12.18. Lista de expansões da variável do make
expansão da variável | descrição |
---|---|
foo1 := bar |
expansão de uma vez |
foo2 = bar |
expansão recursiva |
foo3 += bar |
acrescentar |
Corra "make -p -f/dev/null
" para ver as regras internas
automáticas.
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.
Atenção | |
---|---|
Não substitua ficheiros do sistema com os seus programas compilados quando os instalar. |
Debian não toca nos ficheiros em "/usr/local/
" ou em
"/opt
". Portanto se compilar um programa a partir do
código-fonte, instale-o em "/usr/local/
" para que não
interfira com o Debian.
$ cd src $ ./configure --prefix=/usr/local $ make # this compiles program $ sudo make install # this installs the files in the system
Se tiver o código original, se ele utiliza
autoconf
(1)/automake
(1) e se você
lembrar como o configurou, execute como segue para desinstalar o programa.
$ ./configure all-of-the-options-you-gave-it
$ sudo make uninstall
Em alternativa, se tiver a absoluta certeza que o processo de instalação
apenas coloca ficheiros sob "/usr/local/
" e não há lá
nada importante, pode apagar todos os seus conteúdos com o seguinte.
# 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 originally built on the top of inherently slow Make. (Now Ninja can be its backend.)
Ninja initially released in 2012 is meant to replace Make for the further improved build speed and is 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".
Páginas web dinâmicas interactivas podem ser feitas conforme a seguir.
As questões são apresentadas ao explorador do utilizador a usar formulários HTML.
Preencher e clicar nas entradas do formulário envia uma das seguintes cadeias de URL com parâmetros codificados do explorador para o servidor web.
"https://www.foo.dom/cgi-bin/program.pl?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
"https://www.foo.dom/cgi-bin/program.py?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
"https://www.foo.dom/program.php?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
O "%nn
" no URL é substituído por um caractere com valor
hexadecimal nn
.
A variável de ambiente está definida como: "QUERY_STRING="VAR1=VAL1
VAR2=VAL2 VAR3=VAL3"
".
O programa CGI (qualquer um de
"program.*
") no servidor web executa-se a si próprio com
a variável de ambiente "$QUERY_STRING
".
O stdout
do programa CGI é enviado ao explorador web e é
apresentado como uma página web dinâmica e interactiva.
Por razões de segurança é melhor não embarcar em novos hacks para analisar parâmetros CGI. Existem módulos definidos para eles em Perl e Python. O PHP vem com estas funcionalidades. Quando é necessário o armazenamento de dados no cliente, usam-se cookies HTTP. Quando é necessário o processamento de dados no lado do cliente, usa-se frequentemente Javascript.
Para mais, veja Common Gateway Interface, The Apache Software Foundation e JavaScript.
Procurar "CGI tutorial" no Google ao escrever directamente o URL codificado https://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial no endereço do explorador é uma boa maneira de ver o script CGI em acção no servidor da Google.
Existem programas para converter código-fonte.
Se desejar criar um pacote Debian, leia o seguinte.
Capítulo 2, Gestão de pacotes Debian para compreender o sistema básico de pacotes
Secção 2.7.13, “Portar um pacote ao sistema stable” para compreender o processo básico de portar
Secção 9.11.4, “Sistema chroot” para compreender as técnicas de chroot básicas
debuild
(1), and sbuild
(1)
Secção 12.5.2, “Depurar o pacote Debian” para recompilar para depuração
Guia dos Novos Maintainers da
Debian (o pacote debmake-doc
)
Referência de Programadores da
Debian (o pacote developers-reference
)
Manual de Políticas Debian (o
pacote debian-policy
)
Existem pacotes como os debmake
,
dh-make
, dh-make-perl
, etc., que
auxiliam no processo em empacotamento.