Não use "test" como o nome de um arquivo de teste executável. O
test
é um comando interno de shell.
Referências:
/usr/share/doc/pacote
Unix / Informação sobre
Programação
Muitos documentos informativos longos podem ser obtidos como brochuras do
GNU
.
As próximas quatro seções contêm scripts de exemplo em diferentes linguagens
para criar um arquivo texto de informação de uma conta para ser adicionado no
/etc/passwd
usando um processador de arquivo de lote como o
programa newusers
. Cada script requer como entrada um arquivo com
linhas na forma prenome sobrenome senha. (Os diretórios home do
usuário real não serão criados através desses scripts.)
Ler scripts shell é a melhor maneira de entender como um
sistema similar ao Unix funciona. Aqui, dou alguns apontamentos e lembretes de
programação shell. Veja Erros de
Shell
para aprender a partir de erros.
Referências sobre o Bash:
bash(1)
BASH
Programming - Introduction HOWTO
do LDP como informção inicial.
(Instale o pacote bash-doc
para ver os arquivos de exemplo.)
Programa de exemplo curto (cria entradas de conta para o newusers
a partir da entrada padrão):
#!/bin/bash # (C) Osamu Aoki Sun Aug 26 16:53:55 UTC 2001 Public Domain pid=1000; while read n1 n2 n3 ; do if [ ${n1:0:1} != "#" ]; then let pid=$pid+1 echo ${n1}_${n2}:password:${pid}:${pid}:,,,/home/${n1}_${n2}:/bin/bash fi done
Vários pacotes fornecem um shell POSIX no Debian:
dash
(Sarge)
ash
(Woody)
bash
pdksh
Se você estiver escrevendo um script shell para portabilidade, é melhor
escrevê-lo como um script shell POSIX. Use o /bin/sh
ligado ao
ash
(ou dash
) para testar sua compatibilidade POSIX.
Evite escrever scripts com bashismo ou o
zshismo que parece assemelhar-se à sintaxe de
csh
. Por exemplo, evite:
A descrição para o shell nesse documento aplica-se somente aos shells tipo
POSIX e assim não se aplica aos shells tipo csh
incluindo
tcsh
.
Há vários parâmetros especiais a lembrar:
$0 = nome do shell ou do script shell $1 = primeiro(1) argumento do shell ... $9 = nono(9) argumento do shell $# = número de parâmetros posicionais "$*" = "$1 $2 $3 $4 ... $n" "$@" = "$1" "$2" "$3" "$4" ... "$n" $? = estado de saída do comando mais recente $$ = PID desse script shell $! = PID do trabalho em background iniciado mais recentemente
Expansões de parâmetros básicas a lembrar:
Forma Se var está def.(*) Se var não está def.(*) ${var:-string} $var string ${var:+string} string null ${var:=string} $var string (e executa var=string) ${var:?string} $var (echo string e então sai)
Aqui, os dois pontos `:' em todos esses operadores são atualmente opcionais.
Substituições de parâmetros básicas a lembrar:
Forma Resultado ${var%sufixo} Remove menor padrão sufixo ${var%%sufixo} Remove maior padrão sufixo ${var#prefixo} Remove menor padrão prefixo ${var##prefixo} Remove maior padrão prefixo
Redirecionamentos básicos a lembrar (aqui o [n] é um número opcional para especificar o descritor de arquivo):
[n]> arquivo Redireciona stdout (ou n) para o arquivo. [n]>> arquivo Adiciona a stdout (ou n) ao arquivo. [n]< arquivo Redireciona stdin (ou n) a partir do arquivo. [n1]>&n2 Redireciona stdout (ou n1) para n2. 2> arquivo >&2 Redireciona stdout e stderr para o arquivo. | comando Faz um pipe da stdout para o comando. 2>&1 | comando Faz um pipe da stderr e stdout para o comando.
Aqui,
O shell possibilita que você abra arquivos usando o comando interno
exec
com um descritor de arquivo arbitrário.
$ echo Olá >foo $ exec 3<foo 4>bar # abre arquivosopen files $ cat <&3 >&4 # redireciona stdin p/ 3, stdout p/ 4 $ exec 3<&- 4>&- # fecha arquivos $ cat bar Olá
Aqui, n<&- e n>&- significam fechar o descritor de arquivo n.
Cada comando retorna um estado de saída que pode ser usado para expressões condicionais:
Note que o uso do valor 0 aqui para significar "verdadeiro" difere da
convenção normal de outras áreas da computação. Além disso, `[' é o
equivalente do comando test
, que avalia seus argumentos até o `]'
como uma expressão condicional.
As sentenças condicionais básicas a lembrar são:
comando && se_sucesso_executa_esse_comando_também || true command || se_insucesso_ao_invés_executa_esse_comando if [ expressão_condicional ]; then se_sucesso_executa_esse_comando else se_insucesso_executa_esse_comando fi
Aqui o || true foi necessário para garantir que esse script shell não finalize nessa linha acidentalmente quando o shell for invocado usando com a opção -e.
Os operadores de comparação de arquivos nas expressões condicionais são:
-e arquivo Verdadeiro se o arquivo existe. -d arquivo Verdadeiro se o arquivo existe e é um diretório. -f arquivo Verdadeiro se o arquivo existe e é um arquivo regular. -w arquivo Verdadeiro se o arquivo existe e é gravável. -x arquivo Verdadeiro se o arquivo existe e é executável. arquivo1 -nt arquivo2 Verdadeiro se o arquivo1 é mais novo que o arquivo2. (modificação) arquivo1 -ot arquivo2 Verdadeiro se o arquivo1 é mais antigo que o arquivo2. (modificação) arquivo1 -ef arquivo2 Verdadeiro se eles são o mesmo dispositivo e número de inode.
Os operadores de comparação de cadeias de caracteres em expressões condicionais são:
-z str Verdadeiro se o comprimento de str é zero. -n str Verdadeiro se o comprimento de str não é zero. str1 == str2 Verdadeiro se as cadeias de caracteres são iguais. str1 = str2 Verdadeiro se as cadeias de caracteres são iguais. ( "=" deve ser usado no lugar de "==" para conformidade POSIX estrita ) str1 != str2 Verdadeiro se as cadeias de caracteres não são iguais. str1 < str2 Verdadeiro se str1 é ordenada antes de str2 (depende do locale). str1 > str2 Verdadeiro se str1 é ordenada depois de str2 (depende do locale).
Os operadores de comparação aritmética inteira nas expressões condicionais são -eq, -ne, -lt, -le, -gt, e -ge.
O shell processa um script como a seguir:
As aspas simples dentro de aspas duplas não têm efeito.
Executar set -x no shell ou invocá-lo com a opção -x faz com que o shell imprima todos os comandos executados. Isso é um tanto útil para depuração.
Referências sobre o Awk:
mawk(1)
e gawk(1)
Programa de exemplo curto (cria entrada para o comando newusers
):
#!/usr/bin/awk -f # Script para criar um arquivo adequado para usar no comando 'newusers', # a partir de um arquivo consistindo de identificações de usuários e senhas na forma: # Prenome Sobrenome senha # Copyright (c) KMSelf Sat Aug 25 20:47:38 PDT 2001 # Distribuído sob a GNU GPL v 2, ou sob sua opção, qualquer versão posterior. # Este programa é distribuído SEM QUALQUER GARANTIA. BEGIN { # Atribui UID, GID que está iniciando if ( ARGC > 2 ) { startuid = ARGV[1] delete ARGV[1] } else { printf( "Uso: newusers startUID arquivo\n" \ " onde:\n"\ " startUID é o ID do usuário a adicionar, e\n" \ " arquivo é um arquivo de entrada na forma:\n" \ " prenome sobrenome senha\n" \ ) exit } infile = ARGV[1] printf( "Iniciando UID: %s\n\n", startuid ) } /^#/ { next } { ++record first = $1 last = $2 passwd = $3 user= substr( tolower( first ), 1, 1 ) tolower( last ) uid = startuid + record - 1 gid = uid printf( "%s:%s:%d:%d:%s %s,,/home/%s:/bin/bash\n", \ user, passwd, uid, gid, first, last, user \ ) }
Há dois pacotes que fornecem um awk
POSIX no Debian:
mawk
gawk
Este é o interpretador em um sistema similar ao Unix.
Referências sobre o Perl:
perl(1)
Programa de exemplo curto (cria entrada para o comando newusers
):
#!/usr/bin/perl # (C) Osamu Aoki Sun Aug 26 16:53:55 UTC 2001 Public Domain $pid=1000; while (<STDIN>) { if (/^#/) { next;} chop; $pid++; ($n1, $n2, $n3) = split / /; print $n1,"_",$n2,":", $n3, ":",$pid, ":",$pid,",,,/home/",$n1,"_",$n2,":/bin/bash\n" }
Para instalar o módulo Perl nome_módulo:
# perl -MCPAN -e 'install nome_módulo'
Esse é um interpretador orientado a objeto muito bom.
Referências sobre o Python:
python(1)
Programa de exemplo curto (cria entrada para o comando newusers
):
#! /usr/bin/env python import sys, string # (C) Osamu Aoki Sun Aug 26 16:53:55 UTC 2001 Public Domain # Portado do script awk de KMSelf Sat Aug 25 20:47:38 PDT 2001 # Este programa é distribuído SEM QUALQUER GARANTIA. def usages(): print \ "Uso: ", sys.argv[0], " start_UID [nome_de_arquivo]\n" \ "\tstartUID é o ID de usuário iniciando a adicionar.\n" \ "\tnome_de_arquivo é o nome do arquivo de entrada. Se não especificado, entrada padrão.\n\n" \ "Formato do arquivo de entrada:\n"\ "\tprenome sobrenome senha\n" return 1 def parsefile(startuid): # # filtro principal # uid = startuid while 1: line = infile.readline() if not line: break if line[0] == '#': continue (first, last, passwd) = string.split(string.lower(line)) # acima falha com número errado de parâmetros :-) user = first[0] + last gid = uid lineout = "%s:%s:%d:%d:%s %s,,/home/%s:/bin/bash\n" % \ (user, passwd, uid, gid, first, last, user) sys.stdout.write(lineout) +uid if __name__ == '__main__': if len(sys.argv) == 1: usages() else: uid = int(sys.argv[1]) #print "# UID start from: %d\n" % uid if len(sys.argv) > 1: infilename = string.join(sys.argv[2:]) infile = open(infilename, 'r') #print "# Read file from: %s\n\n" % infilename else: infile = sys.stdin parsefile(uid)
Referências sobre o Make:
make(1)
Variáveis automáticas simples:
Sintaxe de regra:
alvo: [ pré-requisitos ... ] [TAB] comando1 [TAB] -comando2 # ignora erros [TAB] @comando3 # suprime o eco
Aqui, [TAB] é um código TAB. Cada linha é interpretada pelo shell depois de fazer a substituição de variável. Use \ no fim de uma linha para continuar o script. Use $$ para entrar $ para valores de ambiente para um script shell.
Regras implícitas para o alvo e pré-requisitos podem ser escritas, por exemplo, como:
%: %.c header.h
ou
%.o: %.c header.h
Aqui, o alvo contém o caracter % (exatamente um deles). O % pode corresponder a qualquer sub-cadeia de caracteres não vazia nos nomes de arquivo do alvo atual. Os pré-requisitos da mesma forma usam % para mostrar como seus nomes se relacionam com o nome do alvo atual.
Regras de sufixo são a forma obsoleta de
definir regras implícitas para o make
. Elas ainda são suportadas
no GNU make
por compatibilidade, mas use regras de padrão
equivalente, sempre que possível:
regra de sufixo antiga --> nova regra de padrão .c: --> % : %.c .c.o: --> %.o: %.c
Variáveis automáticas para a regra:
foo.o: new1.c new2.c old1.c new3.c $@ == foo.o (alvo) $< == new1.c (o primeiro) $? == new1.c new2.c new3.c (os mais novos) $^ == new1.c new2.c old1.c new3.c (todos) $* == `%' padrão correspondente no padrão alvo.
Referências variáveis:
foo1 := bar # Expansão única foo2 = bar # Expansão recursiva foo3 += bar # Adiciona SRCS := $(wildcard *.c) OBJS := $(foo:c=o) OBJS := $(foo:%.c=%.o) OBJS := $(patsubst %.c,%.o,$(foo)) DIRS = $(dir diretorio/nomearquivo.ext) # Extrai "diretorio" $(notdir NAMES...), $(basename NAMES...), $(suffix NAMES...) ...
Execute make -p -f/dev/null para ver as regras internas automáticas.
Preparação:
# apt-get install glibc-doc manpages-dev libc6-dev gcc
Referências para o C:
gcc(1)
nome_de_cada_função_da_biblioteca_C(3)
gcc
)
Um exemplo simples para compilar example.c
com uma biblioteca
libm
em um executável 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); /* evita buffer overflow */ y[10] = '\0'; /* preenche para ter certeza que string termina com '\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, a opção -lm é necessária para ligar a
biblioteca libm
para o sqrt()
. A
biblioteca real está no /lib/
com o nome de arquivo
libm.so.6
, que é um link simbólico para o
libm-2.1.3.so
.
Veja o último parâmetro no texto de saída. Há mais de 10 caracteres apesar de %10s ser especificado.
O uso de funções que realizam operações de apontadores sem verificações de
limite, como o sprintf
e o strcpy
, está ultrapassado
pois não elas evitam as vulnerabilidades causadas por buffer overflow que leva
aos efeitos acima. Ao invés disso, use snprintf
e
strncpy
.
gdb
Preparação:
# apt-get install gdb
Referências sobre o gdb
:
gdb(1)
http://www.unknownroad.com/rtfm/gdbtut/gdbtoc.html
Use o gdb
para depurar um programa compilado com a opção
-g. Muitos comandos podem ser abreviados. A expansão de tab
funciona como no shell.
$ gdb programa (gdb) b 1 # define ponto de parada na linha 1 (gdb) run arg1 arg2 arg3 # executa o programa (gdb) next # próxima linha ... (gdb) step # avança um passo ... (gdb) p parm # imprime parm ... (gdb) p parm=12 # define o valor para 12
Para depurar a partir do Emacs, consulte o Resumo de comandos do Editor (Emacs, Vim), Seção 11.3.4.
Use o ldd
para determinar as dependências de bibliotecas de um
programa:
$ 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)
Para o ls
funcionar em um ambiente usando chroot
, as
bibliotecas acima precisam estar disponíveis no ambiente chroot
.
Os seguintes comandos também serão úteis:
strace
: rastrea chamadas de sistema e sinais
ltrace
: rastrea chamadas de biblioteca
Há várias ferramentas de detecção de fuga de memória disponíveis no Debian.
njamd
valgrind
dmalloc
electric-fence
memprof
memwatch
(não empacotado, obtenha-o em memwatch
.)
mpatrol
leaktracer
libgc6
Parasoft
. (não livre, comercial)
Verifique também as Ferramentas
de Depuração para Alocação Dinâmica de Armazenamento e Gerenciamento de
Memória
.
O flex
é um gerador de analisador léxico rápido.
Referências sobre o flex
:
flex(1)
Você precisa fornecer suas próprias funções main()
e
yywrap()
, ou seu programa.l
deve parecer assim para
compilar sem uma biblioteca (yywrap
é um macro; %option
main ativa %option noyywrap implicitamente):
%option main %% .|\n ECHO ; %%
Alternativamente, você pode compilar com a opção -lfl do ligador
no fim da sua linha de comando cc
(como o AT&T-Lex com
-ll). Não é necessário %option nesse caso.
Há vários pacotes que fornecem um gerador de analisador LALR compatível com Yacc no Debian:
bison
: Gerador de analisador LALR GNU
byacc
: O gerador de analisador LALR Berkeley
byyacc
: Gerador de analisador reverso baseado no
byacc
Referências sobre o bison
:
bison(1)
Você precisa fornecer suas próprias funções main()
e
yyerror()
. A função main()
chama a
yyparse()
que chama a yylex()
, geralmente criada com
o FleX.
%% %%
O autoconf
é uma ferramenta para produzir scripts shell que
configuram automaticamente pacotes de código fonte de software para adaptá-lo
às muitas formas de sistemas similares ao UNIX usando o sistema de criação GNU
inteiro.
O autoconf
produz o script de configuração configure
.
O configure
cria automaticamente um Makefile
personalizado usando o modelo Makefile.in
.
O Debian não mexe em arquivos no /usr/local
(veja Suportando diversidades, Seção 2.5).
Então se você compilar um programa a partir da fonte, instale-o no
/usr/local
, assim ele não interferirá com o Debian.
$ cd src $ ./configure --prefix=/usr/local $ make $ make install # isso coloca os arquivos no sistema
Se você ainda tiver a fonte e o programa usar o
autoconf
/automake
e se você puder lembrar-se de como
o configurou:
$ ./configure todas-as-opções-que-você-deu # make uninstall
Por outro lado, se você tem certeza absoluta de que o processo de instalação
põe arquivos somente sob o /usr/local
e não há nada importante lá,
você pode apagar todo seu conteúdo com:
# find /usr/local -type f -print0 | xargs -0 rm -f
Se você não tiver certeza de onde os arquivos foram instalados, deve pensar em
usar o checkinstall
, que fornece uma maneira limpa para a
desinstalação.
Tradicionalmente, o roff é o principal sistema de processamento de texto do Unix.
Veja roff(7)
, groff(7)
, groff(1)
,
grotty(1)
, troff(1)
, groff_mdoc(7)
,
groff_man(7)
, groff_ms(7)
, groff_me(7)
,
groff_mm(7)
, e info groff.
Há um bom tutorial sobre macros -me
. Se você tiver o
groff
(1.18 ou mais novo), encontre o arquivo
/usr/share/doc/groff/meintro.me.gz
e faça o seguinte:
$ zcat /usr/share/doc/groff/meintro.me.gz | \ groff -Tascii -me - | less -R
O seguinte fará um arquivo texto completamente plano:
$ zcat /usr/share/doc/groff/meintro.me.gz | \ GROFF_NO_SGR=1 groff -Tascii -me - | col -b -x > meintro.txt
Para imprimir, use a saída PostScript.
$ groff -Tps meintro.txt | lpr $ groff -Tps meintro.txt | mpage -2 | lpr
Preparação:
# apt-get install debiandoc-sgml debiandoc-sgml-doc
Referências sobre o debiandoc-sgml
:
/usr/share/doc/debiandoc-sgml-doc
debiandoc-sgml(1)
DocBook:
The Definitive Guide
, por Walsh e Muellner (O'Reilly) (pacote
docbook-defguide
O SGML possibilita o gerenciamento de vários formatos de um documento. Um sistema SGML fácil é o Debiandoc, que é usado aqui. Ele requer pequenas adaptações dos arquivos texto originais para os seguintes caracteres:
Para marcar uma seção como um comentário não imprimível, entre:
<!-- Indique o problema aqui ... -->
Para marcar uma seção com um comentário alterável, entre:
<![ %FIXME; [ Indique o problema aqui ... ]]>
Em SGML, a primeira definição de uma entidade vence. Por exemplo:
<!entity % qref "INCLUDE"> <![ %qref; [ <!entity param "Dado 1"> ]]> <!entity param "Dado 2"> ¶m;
Isso finaliza como "Dado 1". Se a primeira linha tiver "IGNORE" ao invés de "INCLUDE", isso finaliza como "Dado 2" (a segunda linha é uma sentença condicional). Além disso, a repetição de frases pode ser definida antes separadamente do contexto.
<!entity quem-e-esse "meu"> Olá &quem-e-esse; amigo. Esse é &quem-e-esse; livro.
Isso resulta no seguinte:
Olá meu amigo. Esse é meu livro.
Veja o exemplo curto de SGML sample.sgml
nos exemplos
.
Quando os documentos SGML ficam maiores, algumas vezes o TeX que é usado como o processador de texto em plano de fundo (backend) pode causar erros. Veja TeX/LaTeX, Seção 13.8.3.
Preparação:
# tasksel # selecione Miscellaneous --> TeX/LaTeX environment
Referências para LaTeX:
The teTeX HOWTO: The
Linux-teTeX Local Guide
tex(1)
latex(1)
Esse é o ambiente de editoração mais poderoso. Muitos processadores SGML o
usam como seu processador de texto. O Lyx fornecido nos pacotes
lyx
, lyx-xforms
, ou lyx-qt
oferece um
agradável ambiente de edição WYSIWYG para LaTeX enquanto muitos usam o Emacs e
o Vim como alternativa para o editor de fonte.
Há muitos recursos online disponíveis.
teTeX - A Documentation
Guide
(pacote tetex-doc
)
The
Not So Short Introduction to LaTeX2e
A Quick Introduction
to LaTeX
A Simple
Guide to Latex/Lyx
Word
Processing Using LaTeX
Local
User Guide to teTeX/LaTeX
Quando os documentos ficam maiores, algumas vezes o TeX pode causar erros.
Você precisa aumentar o tamanho do pool no /etc/texmf/texmf.cnf
(ou mais apropriadamente, edite o /etc/texmf/texmf.d/95NonPath
e
execute update-texmf
) para resolver isso.
Ao invés de escrever código contendo documentação, o programador letrado escreve documentação contendo código. Essa abordagem garante uma boa documentação para um programa.
Para mais detalhes sobre programação letrada, veja Programação Letrada
.
Preparação:
# apt-get install nowebm
Referências para o Noweb:
Essa é uma ferramenta de programação letrada semelhante a WEB que é mais
simples mas fornece extensibilidade e independência de linguagem. [59] Quando o noweb
é invocado, ele escreve o código fonte do programa nos arquivos de saída
mencionados no arquivo noweb, e escreve um arquivo TeX para documentação
editorada.
O pacote Debian ifupdown
é um bom exemplo.
$ apt-get source ifupdown $ cd ifupdown* $ make ifupdown.pdf ifupdown.ps
Preparação:
# apt-get install doxygen doxygen-doc doxygen-gui
Referências para o Doxygen (criadas por doxygen
!):
Ele pode gerar documentação HTML, RTF, páginas de manual Unix, PostScript, e
PDF (usando LaTeX) para programas em C++, C, Java, IDL e até certo ponto PHP e
C#. O Doxygen é compatível com JavaDoc (1.1), Qt-Doc, KDOC e foi projetado
especificamente para ser usado para projetos que fazem uso do toolkit Qt
da Troll Tech. Ele cria
gráficos de dependência de include, diagramas de colaboração, e gráficos de
hierarquia de classe gráfica mesmo para programas não documentados. A saída é
similar à documentação da Qt.
Preparação:
# apt-get install debian-policy developers-reference \ maint-guide dh-make debhelper # apt-get install packaging-manual # se for Potato
Referências sobre empacotamento:
dh-make(1)
Método curto e grosso para empacotar um binário simples de Joey Hess.
# mkdir -p mypkg/usr/bin mypkg/DEBIAN # cp binary mypkg/usr/bin # cat > mypkg/DEBIAN/control Package: mypackage Version: 1 Architecture: i386 Maintainer: Joey Hess <joeyh@debian.org> Description: my little package Don't expect much. ^D # dpkg-deb -b mypkg
Use o dh_make
do pacote dh-make
para criar um pacote
inicial. Então, continue de acordo com as instruções de
dh-make(1)
. Ele usa o debhelper
no
debian/rules
.
Uma alternativa mais antiga é usar o deb-make
do pacote
debmake
. Ele não usa os scripts debhelper
e depende
apenas do shell.
Se quiser exemplos de pacotes de várias fontes, veja o "mc"
(dpkg-source -x mc_4.5.54.dsc), que usa o "sys-build.mk"
de Adam Heath (doogie@debian.org
), e a
"glibc" (dpkg-source -x glibc_2.2.4-1.dsc), que usa
outro sistema do falecido Joel Klecker (espy@debian.org
).
Referência Debian
CVS, Seg Abr 3 22:58:08 UTC 2005osamu@debian.org
pormenese@uol.com.br