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.
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 um bashismo ou o
zshismo que parece assemelhar-se à sintaxe de
csh. Por exemplo, evite:
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):
[n]> arquivo Redireciona a saída padrão (ou n) para o arquivo.
[n]>> arquivo Adiciona a saída padrão (ou n) ao arquivo.
[n]< arquivo Redireciona a entrada padrão (ou n) a partir do arquivo.
[n1]>&n2 Redireciona a saída padrão (ou n1) para n2.
> arquivo >&2 Redireciona as saídas padrão e de erro para o arquivo.
| comando Faz um pipe da saída padrão para o comando.
>&2 | comando Faz um pipe das saídas padrão e de erro para o comando.
Cada comando retorna um estado de saída que pode ser usado para a expressão condicional :
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
command || se_insucesso_executa_esse_comando_também
if [ expressão_condicional ]; then
se_sucesso_executa_esse_comando
else
se_insucesso_executa_esse_comando
fi
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.
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.
gdbPreparaçã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 GNU
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á alguns 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)
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 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.
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
1.06-17, Sáb Jan 31 07:56:05 UTC 2004osamu@debian.orgpormenese@uol.com.br