* Historia
O sistema operacional UNIX nao foi feito como
algo comecial, mas como
uma ferramenta para hackers, feito POR programadores PARA
programadores.
So para ter uma ideia, os primeiros releases
eram chamados de PWB
(Programmer's Work Bench).
O primeiro UNIX foi escrito por Dennis Ritchie e
Ken Thompson, na AT&T
Bell Labs, para uso pr¢prio. Ultilit rios
foram escritos a medida que
eles tinham problemas a resolver.
Pelo simples motivo que o
Bell Labs nao era uma empresa
de
computadores, o source code foi
compartilhado para universidades.
Programadores brilhantes escreveram seus proprios programas e
adicionaram
ao UNIX.
Nestes 20 anos o UNIX foi ganhando cada
vez mais programas, cada vez
mais usuarios. Hoje em dia e praticamente impossivel falar
em Internet
sem falar em UNIX.
* O Shell
Talvez uma das razoes do poder do UNIX e que voce
nao "fala" com o
sistema diretamente. Ao contrario, voce "fala"
com um programa chamado
shell.
O que o shell faz e pegar tudo aquilo
que voce digita e interpretar,
tomando a acao desejada, como executando um programa ou coisa
parecida.
Por exemplo, quando voce digita um comando
para mostrar todos os
arquivos que comecam com a letra "m":
$ cat m???
O shell procura pelos arquivos, faz uma lista
deles, chama o programa
cat e pede para ele mostrar os arquivos da lista.
O comando cat chama o
kernel atraves das "system calls" para pegar cada
arquivo no disco e
mostrar seu conteudo na tela.
Por que isso e importante?
Primeiro, porque voce pode escolher entre
diferentes shells, cada um
com diferentes funcoes e regras. Segundo porque e importante
saber quais
as regras que o shell usa para interpretar
o que voce digita, para
obter-se o resultado desejado.
Por exemplo, a regra basica
que o shell usa para o espaco (" ") e
separar os argumentos da linha de comando.
Porem, as vezes, voce quer
que o shell interprete-os de forma diferente. O shell permite
que voce
pegue uma frase como um unico argumento. Voce pode
fazer isso usando as
aspas basicamente, como no exemplo abaixo:
$ grep "Isso e apenas um parametro" arquivo.txt
Se voce entender como o shell interpreta a
linha de comando isso pode
ser muito util em dezenas de casos, principalmente quando estiver
lidando
com asteriscos ("*").
Segue abaixo a relacao entre o kernel e os programas.
+--------------------------------------------------------------------+
| USUARIO
|
+---+----------------------------------------------------------------+
| dados e comandos
^
^
| do usuario
|
|
|
| saida
| saida
v
|
|
+-------------------+
|
|
| shell
+----+ transferencia +--+--+
| comandos internos +----------------------> | cat
|
+-------+---------- +
de controle +--+--+
|
|
|
| "system calls"
v
v
+-------------------------------------------------------------------+
| Kernel de UNIX e Drivers
|
+-------------------------------------------------------------------+
Vale lembrar que alguns comandos fazem a entrada
de dados diretamente
do usuario, sem a intervencao do shell.
Nestes casos o unico papel do
shell e chamar o programa. Um editor de texto, por exemplo,
quase sempre
inclue seu proprio interpretador de comandos e suas proprias
regras.
CURSO DE UNIX II por rodrigo feher <feher@ibm.net>
* Os Programas Funcionam Juntos
No UNIX a maioria dos programas
foram desenhados para justamente
trabalharem juntos. Isso e realmente maravilha
(como voce vai perceber
ao longo do curso) pois voce nunca vai ter
que reinventar a roda. :-)
Para a melhor interacao entre os programas, um ultilitario
deve seguir
os tres conceitos basicos:
* Dentro do possivel, a saida de um
programa deve ser usavel como a
entrada de outro.
* Toda a informacao que um programa necessitar
deve ser passada em um
unico "stream" ou especificada na linha de comando. Um
programa nao deve
perguntar dados ao usuario ou fazer uma formatacao desnecessaria
da saida.
* Se nenhum argumento for passado na linha
de comando, a entrada deve
ser feita pela stdio (entrada padrao, normalmente o teclado)
e a saida
deve ser feita pela stdout (saida padrao, normalmente a sua tela).
Os programas que forem escritos seguindo
as "regras" acima podem ser
facilmente usados como filtros.
A barra vertical "|" representa
o pipe, isso e, "pegue a saida do
programa da esquerda como entrada".
Com isso voce podera pegar
a saida de um comando de procura, jogar
para outro que colocara a saida em ordem alfabetica e este
entao jogar o
resultado para um arquivo.
Isso fica assim (veremos
isso mais tarde, nao se preocupe se nao
entender - o intuito e apenas demostrar o poder da linha de comando):
$ find -name "aula_unix*" -print | sort > indice.txt
Que tal? :-)
CURSO DE UNIX III por rodrigo feher
<feher@ibm.net>
nota: eu estava lendo as aulas I e II
e achei melhor antes de dar os
comandos basicos do UNIX apresentar rapidamente quais sao os
shells mais
populares.
* Os Diversos Shells
Como voce pode ver na aula I, existem
muitos shells disponiveis;
tambem e muito importante saber usa-lo, ja que isso e vital
para o total
aproveitamento do UNIX.
Na maioria dos sistemas operacioais,
o shell (ou interpretador de
comandos) e parte interna do sistema
operacional. No UNIX isso e
totalmente diferente. O shell e
apenas mais um programa, que vai
proteger voce do kernel - e o kernel de voce! :-)
Existem uma grande diversidade de shells disponiveis,
onde voce esta
livre para escolher aquele que mais se adapta a voce. Os mais
comuns sao:
* sh
O Bourne Shell
(tem esse nome por causa do seu criador - Steve
Bourne) e o mais antigo dos
shells atualmente disponiveis. Ele e
bastante primitivo.
E quase sempre usado
para a programacao de shell por alguns
motivos que irei provavelmente mostrar em
alguma outra aula.
* csh
O C Shell foi desenvolvido
em Berkeley (para quem nao sabe, quem
faz os "BSDs": FreeBSD, NetBSD, etc)
como parte da sua implementacao
do seu UNIX. E
de longe o mais popular e usado shell disponivel.
Ocasionalmente o csh nao e encontrado
em um System V UNIX, porem e
bastante raro.
Possui varias coisas que
o sh nao tem - e fazem bastante falta.
Sao elas o controle de tarefas
(jogar um programa para background,
foreground, etc) e o "history", entre outras.
Nao e aconselhavel se escrever
shell scripts para ele, pois possui
varios bugs. Entretanto para o uso normal,
voce nao percebera nada.
* jsh
Uma nova versao
do Bourne shell que possui a implementacao de
controle de tarefas. Disponivel
apenas para o System V Release 4
UNIX.
* ksh
O K>
* bash
Este e o Bourne-Again Shell.
Foi desenvolvido pela GNU. Possui a
maioria das funcoes do C shell
e do Korn shell e mais um comando de
ajuda interno.
Fora isso ainda existem shells como
o tcsh (Turbo C Shell), que e
apenas uma variacao do tradicional C Shell.
* Como Identificar O Shell Que Esta Usando
Basicamente voce pode identificar que
shell esta usando pelo prompt:
"%" para o csh e "$" para o sh. Porem como e possivel a
customizacao do
prompt, talvez isso nao funcione em casos de prompts redefinidos.
Para se certificar, use um dos comandos abaixo:
$ grep "seu nome de login" /dev/passwd
Caso esteja usando NIS, use:
$ ypcat passwd | grep "seu nome de login"
No meu caso a saida sera:
feher:x:501:100:Rodrigo Feher:/home/feher:/bin/bash
Note que o nome do shell e o ultimo parametro, onde
eles sao separados
por ":". Logo, o meu default
e o Bourne-Again Shell. Apenas por
curiosidade os campos sao login, senha (criptografada),
User ID, Group
ID, nome real, homedir e shell default.
CURSO DE UNIX IV por rodrigo feher <feher@ibm.net>
* Os Comandos Internos e Externos
A maioria dos comandos que voce
executa sao externos. Por exemplo,
quando voce quer listar os arquivos de um diretorio e digita
"ls" voce
esta usando um programa externo (/bin/ls).
Entretanto, quando usa o
comando "cd" para mudar de diretorio voce esta usando um comando
interno
do shell.
O shell nao cria um novo
processo para rodar comandos internos. A
grande vantagem dos internos sobre os externos e a velocidade:
comandos
externos precisam que o shell use as chamadas "fork" e "exec"
para criar
um subprocesso. Veremos mais tarde varios casos onde isso
e vital para o
nosso programa e/ou shell script.
Vejamos como o shell interpreta o que voce
digitou: se existir algum
comando interno com aquele nome, ele e executado.
Se o comando digitado
contiver o path absoluto (veremos mais tarde) como "/bin/ls"
entao esse e
executado mesmo se houver algum comando interno com
o mesmo nome. Caso
nao exista nenhum comando externo com aquele nome e voce
nao expecificou
o path absoluto entao o shell procurara no seu path pelo programa.
O path e apenas uma string, que expecifica onde o
shell deve procurar
pelos programas externos. Ele e
geralmente especificado nos seus
arquivos de configuracao (veremos mais tarde, tambem).
Normalmente programas de uso
geral sao localizados no diretorio
"/bin", alguns tambem ficam em "/etc",
porem sao normalmente apenas
usandos pelo administrador do sistema.
O path fica armazenado numa variavel ambiental
(veremos mais sobre
isso depois) chamada PATH. Provavelmente sera algo como:
PATH=/bin:/usr/bin:/usr/local/bin:/home/seulogin/bin:
Os varios lugares especificados, como voce pode ver,
sao separados por
":". O shell faz a procura dos
programas externos nos diretorios que
voce especificou na ordem em que sao declarados.
* Arquivos no UNIX
Como em todo sistema operacional,
os arquivos sob o UNIX possuem
nomes. Normalmente esses nomes nao tem
restricao quanto ao tamanho,
exeto em algumas versoes mais antigas onde o limite era 14 caracteres.
Teoricamente os arquivos sobre UNIX podem conter
qualquer caractere,
exeto a barra "/". Entretanto
e altamente recomendavel que voce use
apenas letras e evite a pontuacao,
pois isso podera causar alguns
problemas quando voce tiver que acessar um arquivo. Use
as regras abaixo
quando for nomear um:
* Maiusculas e Minusculas.
O UNIX e
sempre case-sensitive, ou seja, letras maiusculas sao
tratadas diferentemente das minusculas
(ao contrario do DOS, Windows
95, OS/2, etc). O que isso
significa? Voce pode ter no mesmo
diretorio simultaneamento os arquivos
"ABCD", "AbCd", "abcd" e assim
em diante.
* Underscore (_)
Underscores facilitam
a criacao de um arquivos com um nome
composto de varias palavras. Evite
usar o espaco para nao ter
problemas futuros.
Em vez de criar um
arquivo chamado
"planilhajan96" use "planilha_jan_96".
* Pontos (.)
Os pontos sao
usandos frequentemente para especificar o tipo do
arquivo. Por exemplo, arquivos como
"aaa.c" geralmente sao programas
escritos em C, enquanto um arquivo do
tipo "aaa.txt" geralmente sera
um texto. Fora o ponto evite usar outros
tipos de pontuacao.
Uma coisa muito importante
sobre delecao de arquivos: uma vez
deletado, o arquivo nao pode ser mais
recuperado. Logo tome muito
cuidado quando usar wildcards com o comando "rm" ou similar.
CURSO DE UNIX V por rodrigo feher <feher@ibm.net>
* Wildcards
[para os usuarios que estao migrando do DOS]
Antes de mais nada, precisa ficar
bem claro para os usuarios do DOS
que os wildcards no DOS funcionam de forma muito diferente
em relacao ao
UNIX: quem os interpreta e o shell. Como assim?
Se voce mandar um
programa no DOS mostrar todos os arquivos
de um diretorio, usamos por
exemplo "dir *.*", o shell passa o parametro "*.*" para o comando
"dir" e
este ira fazer a procura dos arquivos correspondentes,
mostrando-os na
tela.
No UNIX e diferente: quem faz a procura
e o shell. Por exemplo,
quando digitamos o comando "ls *", o shell primeiro pre-processa
a linha,
expandindo o "*" para todos os arquivos do diretorio e entao
executando o
"ls" usando como argumento os arquivos achados em uma lista
concatenada,
usando o espaco (" ") como separador de campos.
Se voce tiver acesso a
uma maquina que rode UNIX, experimente executar o
comando "echo *" e
entao entendera melhor o que eu estou dizendo.
[pronto, so isso... :-) Agora iniciamos a nossa aula.]
Como na maioria dos outros sistemas
operacionais, os shells do UNIX
tem a facilidade dos wildcards, porem
com muito mais poder. Veremos
agora algumas maneiras de se abreviar o nome de um ou mais arquivos.
Comecaremos a demonstrar o uso dos wildcards
pelo mais simples: o
ponto de interrogacao ("?").
O shell ira interpreta-lo como um unico caractere.
Por exemplo: voce
quer listar todos os arquivos que comecam com "curso_unix_"
e possuem
mais um caractere. Faremos a procura usando a string "curso_unix_?".
Com isso, o shell ira
expandir a string acima transformando-a no
resultado da busca. Se no diretorio houver os arquivos
"curso_unix_1" e
"curso_unix_2", o shell passara
como argumento ao programa:
"curso_unix_1 curso_unix_2".
Agora vamos ver o wildcard "*". Ele e praticamente
igual ao "?" com a
diferenca que ele significa "zero ou mais caracteres".
Se tivermos num
diretorio os arquivos "curso_unix_1", "curso_unix_2"
e "dummy.tar.gz",
usando-se "curso*" o shell
fala a expansao para "curso_unix_1
curso_unix_2".
As vezes voce precisara ser mais
restrito quando for especificar um
grupo de arquivos. Na pratica, para achar
todos os arquivos de um
diretorio que terminam com a letra "Z" ou "z", voce deve
usar o wildcard
"[]". Fica assim: "*[Zz]". Com
isso serao localizados arquivos como
"teste.Z", "abobora.z", "xyz", "xyZ", etc.
Em outras palavras, o wildcard "[]" sempre ira
corresponder-se a um
dos caracteres da lista que for especificada.
Vale lembrar que se voce
quiser, por exemplo, achar todos os arquivos que terminarem com
as letras
de "b" ate "l" voce pode usar: "*[b-l]".
Resumo pratico:
| Wildcard | Equivale a... |
| ? | Um unico e qualquer caractere |
| * | Zero ou mais caracteres |
| [ab] | Ou "a" ou "b" |
| [a-z] | Caracteres de "a" ate "z" |
Vale a pena lembrar que os wildcards apenas
sao expandidos para nomes
de arquivos que ja existam, logo, se voce quiser
criar dez arquivos, de
"carta_1" ate "carta_9" e usar "carta_[1-9]" voce
nao obtera sucesso.
Para isso voce deve usar o operador "{}",
que veremos brevemente numa
proxima aula.
Caso queira ir mais fundo nos wildcards, consulte
a manpage do seu
shell. Para o bash, fica "man bash", para o csh,
fica "man csh" e assim
por diante.
* Extensoes de Arquivos
Apenas para referencia, segue uma tabela
de como identificar qual o
tipo do arquivo usando-se como referencia a sua extensao.
Vale lembrar
que isso nao vale para 100% dos casos, ja que ninguem
e obrigado a usar
esta convencao.
Extensao
O arquivo e' um...
.c
Source code de um programa escrito em C.
.h
Header de um program escrito em C.
.f
Source code de um programa escrito em FORTRAN.
.o
Arquivo objeto (compilado).
.s
Source code de um programa escrito em assembly.
.Z
Arquivo comprimido pelo programa compress.
.[1-8]
Source code para uma "manpage".
.tar
Arquivo "tarado".
.gz
Arquivo comprimido pelo programa gzip.
.tgz
Arquivo "tarado" e comprimido pelo gzip.
.txt
Arquivo texto.
.shar
Arquivo shell.
.sh
Script para o Bourne shell.
.csh
Script para o C shell.
.ps
Arquivo fonte para postscript
| Extensao | O arquivo e' um... |
| .c | Source code de um programa escrito em C. |
| .h | Header de um program escrito em C. |
| .f | Source code de um programa escrito em FORTRAN. |
| .o | Arquivo objeto (compilado). |
| .s | Source code de um programa escrito em assembly. |
| .Z | Arquivo comprimido pelo programa compress. |
| .[1-8] | Source code para uma "manpage". |
| .tar | Arquivo "tarado". |
| .gz | Arquivo comprimido pelo programa gzip. |
| .tgz | Arquivo "tarado" e comprimido pelo gzip. |
| .txt | Arquivo texto. |
| .shar | Arquivo shell. |
| .sh | Script para o Bourne shell. |
| .csh | Script para o C shell. |
| .cs | Arquivo fonte para postscript |
CURSO DE UNIX VI por rodrigo feher <feher@ibm.net>
* Usando O Operador "{}"
Continuando a aula passada, vamos agora aprender
como usar as chaves.
Vale lembrar que elas nao
funcionam em qualquer shell, algumas
implementacoes nao possuem esta facilidade.
Vamos ao que interessa. As chaves
possuem uso semelhante ao dos
colchetes, com uma diferenca: elas podem
ser usadas em qualquer caso,
nao apenas quando o arquivo o qual voce quer se referenciar exista.
Digitando no shell:
$ echo "aula_unix_{um,dois}"
Voce obtera:
aula_unix_um aula_unix_dois
Uso pratico: voce quer extrair planilhas de
um arquivo .tar. Vejamos
como fica:
$ tar xvf planilhas_1995.tar planilha_{jan,fev,mar}
O shell ira expandir as chaves, passando para o tar
como parametros as
palavras formadas. Neste caso voce
nunca poderia ter usado qualquer
outro wildcard, ja que o shell nao conseguiria expandi-los
pela simples
causa da inexistencia dos arquivos no diretorio corrente.
* A Estrutura em Arvore do Disco
Antes de comecar a demonstrar os
comandos mais usados no UNIX, e
importante que voce saiba como e organizado o disco. Os
arquivos estao
todos dentro de diretorios (sao como gavetas), sendo
que sao permitidos
diretorios aninhados.
Para os usuários do DOS e bom lembrar que
as barras usadas sao ao
contrario. Por exemplo, se no DOS voce se referencia
a um arquivo como
"\tmp\abc" no UNIX voce usaria "/tmp/abc".
Segue abaixo como voce se
referenciaria a todos os diretorios
mostrados na arvore acima:
/
/bin/
/usr/
/home/
/etc/
/usr/bin/
/usr/X/
/home/feher/
/home/joao/
Ficou claro? Se voce
estiver no diretorio "/home/feher/", por
exemplo, e quiser se referenciar ao
"/home/joao/", voce pode usar
"../joao/". O ".." e sempre um link para o diretorio "de
baixo".
* O Home Directory
No UNIX, quase sempre todo usuario tem
seu home directory. E neste
local que voce ira guardar os seus seus arquivos em geral, salvas
algumas
exessoes.
Os homedirs originalmente foram
colocados em "/usr/", porem hoje em
dia e muito comum voce encontra-los em "/home/" ou
"/u/". Independente
de onde voce estiver no filesystem, digitando apenas
"cd", sem nenhum
argumento, voce ira automaticamente voltar ao seu homedir.
E muito interessante como
voce pode se referenciar a um homedir.
Assumindo-se que seu homedir esta em "/home/feher/", e
seu nome de login
e "feher" voce pode se referenciar ao diretorio "/home/feher/bin/"
usando
apenas "~/bin/".
Como voce deve ter percebido, o shell ira entender
o "~" como homedir.
E se voce quisesse se referir ao subdiretorio
"bin/" no homedir do
usuario "joao"? Basta voce usar "~joao/bin/".
Note que se voce digitar, por exemplo, "cd
~joao" o shell expandira o
til e entao chamara o comando
cd, que recebera como parametro
"/home/joao/".
* Paths Absolutos e Paths Relativos
A diferenciacao entre paths absolutos e relativos
e muito simples. Se
comecar com uma barra ("/"), o path
e absoluto. Caso contrario, e
relativo.
Se voce estiver no diretorio "/home/feher/" e digitar
"cd bin", voce
ira para o diretorio "/home/feher/bin/". Caso digite "cd
/bin" entao ira
para "/bin/" (estou assumindo que os diretorios
especificados existam.
Caso contrario voce recebera uma mensagem de "diretorio nao encontrado").
CURSO DE UNIX VII por rodrigo
feher <feher@ibm.net>
* Como Funciona Mais "Intimamente" o Filesystem do UNIX
Quando falamos no filesystem do UNIX,
nao podemos deixar de falar do
mais importante: a palavra chave e "inode".
O inode e a estrutura de
dados que mantem todas as informacoes
essenciais sobre os arquivos. Ele abriga:
* UID e GID do dono do arquivo.
* As permissoes do arquivo.
* O timestamp do arquivo (informacoes
sobre a ultima modificacao,
ultimo acesso, etc).
* O tipo do arquivo (arquivo de
dados, device, imagem da memoria,
etc).
O comando "ls -l" mostra quase todas as informacoes
acima, "ls -i"
mostra o inode.
Todos os filesystems
tem um numero pre-definido de inodes,
determinados na sua criacao; e isso que vai determinar o numero
maximo de
arquivos que o ele pode guardar. As vezes, mesmo
nao sendo muito comum,
voce tera ter bastante espaco livre entretanto nao
podera criar novos
arquivos. Este caso identifica o esgotamento de inodes
livres.
O numero de inodes nao
pode ser redefinido sem que haja perda de
dados, ou seja, o filesystem tem que ser recriado.
* As Diversas Permissoes de Acesso a um Arquivo
Como o UNIX e um sistema operacional
multiusuario, seria impossivel
administra-lo sem que se tivesse permissoes de arquivos.
As permissoes
sao baseadas em dois conceitos: o de usuario e grupo.
Todo usuario tem uma unica
conta, com um unico nome de login e um
unico UID (o numero de identificacao
do usuario - consulte as aulas
anteriores para informacoes de como achar seu numero atraves
do arquivo
passwd) (*).
Todo usuario tambem e membro de um ou mais grupos
(no BSD e em algumas
outras implementacoes do UNIX, voce e membro de todos os
grupos os quais
voce tem acesso, simultaneamente. Em outros sistemas, para
mudar o grupo
ativo voce devera usar o comando "newgrp").
O seu grupo primario e especificado no arquivo passwd
(normalmente em
"/etc/"). Caso o operador do
sistema deseje lhe dar acesso a mais
grupos, voce sera adicionado no arquivo
group (tambem normalmente em
"/etc/").
Quando voce cria um arquivo ele sera automaticamente
setado para o seu
grupo primario ou para o grupo do dono do diretorio em que ele
esta sendo
criado. Exeto em sistemas que
possuem quota, voce pode mudar o dono
(apenas o root) e o grupo (apenas para algum o qual voce
pertenca) com o
comando chown e/ou chgrp (veremos mais adiante).
Por exemplo, eu pertenco aos grupos "users
e "staff". Quero mudar o
grupo do arquivo "planilha_jan96", que esta em "users", para
"staff":
$ chgrp staff planilha_jan96
Agora vejamos como e formada
as permissoes de leitura, escrita e
execucao.
Todo arquivo possui tres diferentes sets de
permissoes: um para o
dono do arquivo, outro para o grupo o
qual o arquivo pertence e outro
para os outros (ou seja, todos exeto os usuarios
que nao se enquadrarem
em nenhuma das especificacoes anteriores). A
permissao de escrita e
simbolizada pela letra "w", a de leitura pela
letra "r" e de execussao
pela letra "x".
Usando a saida do comando "ls -l", temos abaixo:
-rw-r--r-- 1 feher users 0 Mar 29 17:12 planilha_dez94
O arquivo "planilha_dez94" possui um set de
permissoes de "rw-r----".
Desmembrando, temos:
* "rw-" para o dono do arquivo. Significa:
"tem acesso a escrita e
leitura, porem nao pode executar o arquivo".
* "r--" para os usuarios pertencentes ao grupo do
arquivo. Significa:
"tem acesso a leitura, porem nao pode escrever nem executar o
arquivo".
* "---" para os outros usuarios.
Significa: "Nao tem acesso nem a
leitura, nem a escrita e nem para a execucao do arquivo".
Agora que voce ja conhece
as permissoes, vejamos elas mais
intimamente, a nivel de bits (parcialmente):
execucao -----------+
escrita --------+ |
leitura ---+ |
|
| | |
| | |
+---+---+---+
| 0 | 0 | 0 |
+---+---+---+
Agora (totalmente), englobando os tres sets de permissoes:
dono do usuarios
outros
arquivo do grupo usuarios
+---+---+---++---+---+---++---+---+---+
| 0 | 0 | 0 | | 0
| 0 | 0 | | 0 | 0
| 0 |
+---+---+---++---+---+---++---+---+---+
Um bit setado ("1") significa "sim",
caso contrario ("0") significa
nao. Agora vejamos como vamos formar o set de permissoes
na forma de
numero em base octal: um bit setado para leitura
soma 4, um bit setado
para escrita soma 2 e um para execucao soma 1.
Por exemplo, tenho acesso a
leitura, para escrita mas nao para
execucao. Fica 4 +2 + 0 = 6.
Logo, concluimos a tabela abaixo:
| Octal | Permissao |
| 0 | "---" |
| 1 | "--x" |
| 2 | "-w-" |
| 3 | "-wx" |
| 4 | "r--" |
| 5 | "r-x" |
| 6 | "rw-" |
| 7 | "rwx" |
Sendo assim, um arquivo com permissao "rwxr-x--x"
tera permissao 651.
Ficou claro? A primeira vista
isso nao teria ultilidade, porem voce
ficara surpreso quando for usar o comando "chmod" (veremos brevemente).
CURSO DE UNIX VIII por rodrigo feher <feher@ibm.net>
* Os Atributos SUID e SGID
Os atributos SUID e SGID tem uma funcao muito especial
no UNIX: uma
vez executados o seu UID e/ou GID e alterado.
No caso do atributo SUID
estar presente, voce passa a ter a identidade do dono do arquivo;
no caso
do SGID voce passa a ser do mesmo grupo a qual o arquivo pertence.
Vale lembrar que a identidade
e apenas mantida naquele programa,
apenas durante a sua execucao.
Mas qual seria a ultilidade de um programa com esses atributos?
Por exemplo, voce quer que um usuario
possa fazer a impressao de um
documento. Para isso, ele precisara ter permissao de acesso
ao device da
impressora. Porem nao voce que quer
que esse usuario possa fazer
qualquer coisa com aquele device,
voce quer apenas que ele use-o pra
impressao.
Qual a saida? Setar atributos SUID ou SGID
ao programa que fara a
impressao. Assim voce limitara o seu acesso.
Seja muito cauteloso quando for criar
um programa SUID ou SGID: 90%
dos casos de buracos na seguranca sao causados
esses programas. Um
exemplo classico foi um worm (se
nao me engano foi em 1989) que
praticamente derrubou toda a Internet: ele
usava um bug de um programa
com SUID (o sendmail).
Outro exemplo recente e o webserver httpd,
da NCSA. Rodando com SUID
root, um bug nele comprometeu a seguranca de milhares de computadores.
* O Superuser (no caso do UNIX, o root)
Em um sistema multiusuario seria impossivel
fazer a administracao sem
algum "super" usuario. No UNIX ele e o root (UID 0).
Rapidamente: o root pode fazer
praticamente qualquer coisa: ler
arquivos (mesmo sem ter permissao), mudar permissoes,
matar e mudar a
prioridade qualquer processo, etc.
* Como Funcionam as Permissoes para Diretorios
Os diretorios no UNIX usam as mesmas permissoes que
os arquivos, porem
elas sao interpretadas diferentemente.
Para voce poder listar os arquivos de um diretorio,
voce precisa ter o
atributo "r" setado. Caso nao tenha, voce ainda pode acessar
arquivos do
mesmo, porem com uma restricao: voce tera que
saber previamente o nome
do arquivo que voce quer acessar.
Diretorios como "rwx--x--x" sao
muitas vezes chamados de "black
boxes".
O atributo de execucao (search bit) e
o mais importante: caso voce
nao tenha ele setado, nada podera ser feito, o diretorio esta
"fechado".
O atributo de escrita determina se voce tera permissao
de criacao e
modificacao de um arquivo. *NUNCA*, repito, *NUNCA* sete
isso para o seu
homedir. Algum ususario mal intencionado pode preparar
uma "surpresinha"
para voce.
Como sempre, o root e uma
excecao: ele passa por cima de todos os
atributos. Em outras palavras, ele pode escrever,
ler, etc em qualquer
diretorio (claro que em casos como volumes montados como "ro",
a escrita
nao e permitida; isso vale para os demais casos).
* Programas em Background: Como funciona
O UNIX sendo um sistema multitarefa,
permite que voce rode varios
programas simultaneamente. Fazendo uma compilacao em background:
% cc program.c &
[1] 1297
%
Como voce pode perceber,
o simbolo "&" significa: "execute em
background". O numero entre colchetes e chamado de
"job number" e o
numero que o segue e o PID (process ID).
* Mais Sobre Programas em Background
No C Shell, Korn Shell, Bash,
etc voce tem a facilidade do chamado
"job control". Com isso voce podera manipular
os processos com muito
mais facilidade. Veja como funciona:
* Para colocar um programa rodando em
background (se voce esqueceu o
"&", por exemplo:
% cc program.c
<Ctrl-Z>
Stopped
% bg
[1] cc program.c
Como voce pode perceber, depois que o Control-Z
foi pressionado no
teclado, o programa foi suspenso e voce
retornou para o shell. Neste
ponto o programa esta totalmente parado. Depois foi dado
o comando "bg".
Isso faz que o ultimo programa em
estado "stopped" seja colocado em
background.
Para jogar o ultimo programa parado de background
para foreground, use
o comando "fg". Caso tenha varios processos rodando em
background, voce
pode ter uma lista deles usando o comando "jobs".
Para colocar em background o job numero "3":
% bg %3
Para colocar em foreground o job numero "2":
% fg %2
CURSO DE UNIX IX por rodrigo feher <feher@ibm.net>
* Um Pouco Mais Sobre Processos em Background
No Bourne Shell, caso voce
queira colocar uma serie de comandos em
background, separados por ";", voce devera
usar os parenteses. Por
exemplo:
$ sleep 15; ls &
O "&" ira apenas afetar
o ls, ou seja, o resultado obtido sera uma
espera de 15 segundos em foreground e entao a execucao
do comando ls em
background.
Neste caso, voce devera usar:
$ (sleep 15; ls) &
Com o comando acima voce obtera o resultado desejado.
Outra coisa que acontece no Bourne Shell e
que quando voce da um
logout todos os seus programas
que foram colocados em background sao
terminados. Para evitar isso, use o comando "nohup".
Por exemplo, para
fazer uma compilacao em background, independentemente
se voce der um
logout:
$ nohup cc program.c &
[1] 3409
$ logout
* Passwords no UNIX
O UNIX sendo um sistema operacioal
multiusuario acaba implicando na
necessidade do usuario ter permissoes restritas.
Isso normalmente e
feito atraves de passwords.
Seja muito cauteloso quando
for escolher um password: uma escolha
errada pode se tornar numa grande dor de cabeca.
No UNIX os passwords estao
guardados (de modo criptografado) no
arquivo "/etc/passwd". Quando voce tenta logar no
sistema, o programa
"login" nao faz a descriptografia da sua senha e
compara com o que voce
entrou, mas sim criptografa o que voce entrou e compara com o
que esta no
"passwd". Se bater, ela esta correta.
Como voce pode perceber, uma
senha criptografada *NAO* pode ser
simplesmente descriptografada por um algoritimo reverso:
ele nao existe.
* O Algoritimo crypt
O algoritimo "crypt", baseado no DES, e usado pelo
UNIX para fazer a
criptografia dos passwords. Ele usa uma chave de
56bit (oito caracteres
low-ascii) para encriptar blocos de texto de 64bit.
Hoje em dia nao ha
nenhum metodo conhecido que consiga quebrar o algoritimo em pouco
tempo,
pelo fato dele ser "one way".
A criptografia dos passwords e feita da seguinte
maneira: pega-se o
password do usuario como chave de criptografia e criptografa-se
um bloco
de 64bit de zeros. Entao o processo e repetido,
num total de 25 vezes.
No final, adiciona-se o sal(*),
e entao 64bit criptografados sao
transformados em uma string de 11 caracteres,
que sao guardados em
"/etc/passwd".
Para se ter uma ideia, na epoca que este processo
foi idealizado o
processador PDP-11 demorava algo em torno de um segundo
para completar o
processo.
Mas nao para por ai. Para eliminar
a possibilidade de se usar algum
tipo hardware especializado em quebrar
senhas, Robert Morris e Ken
Thompson (os idealizadores) adicionaram o chamado "sal".
O sal e um numero de
12bit, ou seja, entre 0 e 4095, que muda o
resultado do que o DES retorna. Sendo
assim, cada password pode ser
criptografado de 4096 maneiras diferentes!
Quando voce muda seu
password, o programa "passwd" escolhe qual sal usar baseado no
relogio do
computador.
Vejamos abaixo uma tabela de passwords, sais, etc.
| password | sal | pass. criptografado |
| nutmeg | Mi | MiqkFWCm1fNJI |
| ellen1 | re | re79KNd7V6.Sk |
| Sharon | ./ | ./2aN7ysff3qM |
| norahs | am | amfIADT2iqjAf |
| norahs | 7a | 7azfT5tIdyhOI |
Note como o password "norahs"
foi criptografado de duas maneiras
diferentes por terem sais diferentes.
CURSO DE UNIX X por rodrigo feher
<feher@ibm.net>
* O Comando "ls"
Como em qualquer outro sistema operacional,
o UNIX tambem possui um
comando para listar arquivos. Ele e o "ls". Na sua
forma mais reduzida,
ou seja, sem nenhum parametro, voce obtera como saida
uma listagem em
formato horizontal com os arquivos do diretorio corrente:
$ ls
Documentos.tar.gz backup.tar.gz
bin/
planilha_fev96 planilha_jan96
Caso voce queira uma saida em formato longo, use o parametro "l".
$ ls -l
total 1
-rw-r--r-- 1 feher
users 0 Apr
13 10:14 Documentos.tar.gz
-rw-r--r-- 1 feher
users 0 Apr
13 10:14 backup.tar.gz
drwxr-xr-x 2 feher
users 1024 Apr 13 10:14 bin/
-rw-r--r-- 1 feher
users 0 Apr
13 10:13 planilha_fev96
-rw-r--r-- 1 feher
users 0 Apr
13 10:13 planilha_jan96
Vamos interpretar a saida
deste comando: (nao vale para todos os
UNIXes)
O primeiro bloco faz referencia
as permissoes do arquivo (sobre
permissoes, consulte a aula 7),
exeto o primeiro caractere. Ele
significa:
+-----------+----------------------------------+
| Caractere |
Significado
|
+-----------+----------------------------------+
| -
| arquivo normal
|
| d
| diretorio
|
| c
| dispositivo de caracteres
|
| b
| dispositivo de blocos
|
| l
| symbolic link
|
| s
| socket (apenas em alguns UNIXes) |
| p
| FIFO (apenas em alguns UNIXes) |
+-----------+----------------------------------+
O segundo bloco indica quantos hard links (veremos
mais tarde) ele
possue ou em caso de diretorios, quantos arquivos la existem.
O terceiro bloco indica o nome do dono do arquivo.
Caso voce obtenha
um numero, significa que o sistema nao pode associar o UID ao
nome do seu
dono (provavelmente foi deletado sua entrada no arquivo "passwd").
O quarto bloco indica a que
grupo o arquivo pertence. Vale o
comentario do paragrafo acima: caso voce obtenha um
numero, o sistema
nao pode assiciar o GID ao seu nome (so que neste caso
provavelmente nao
foi encontrado a sua entrada no arquivo "groups").
O quinto bloco indica o tamanho do arquivo.
O sexto, setimo e oitavo indicam
a data e hora da sua ultima
modificacao.
Finalmente, o nono bloco e o nome do arquivo.
No UNIX os arquivos que comecam
com um ponto (".") ficam ocultos na
listagem. Para mostra-los, use o parametro "a".
Veja como fica a saida
do comando "ls -la":
total 1
-rw-r--r-- 1 feher
users 0 Apr
13 10:14 Documentos.tar.gz
-rw-r--r-- 1 feher
users 0 Apr
13 10:14 backup.tar.gz
drwxr-xr-x 2 feher
users 1024 Apr 13 10:14 bin/
-rw-r--r-- 1 feher
users 0 Apr
13 10:13 planilha_fev96
-rw-r--r-- 1 feher
users 0 Apr
13 10:13 planilha_jan96
-rw-r--r-- 1 feher
users 0 Apr
13 10:13 .signature
Para mostrar um diretorio em vez de seu conteudo, use o parametro "d".
Para obter o inode de cada arquivo, adicione o parametro "i".
Usando-se o parametro "F", no final
do arquivo sera adicionado um
simbolo indicando qual e o seu tipo, para facilitar na sua identificacao.
Veja a tabela abaixo:
+---------+----------------+
| Simbolo | Significado
|
+---------+----------------+
| (nada) | arquivo normal |
| *
| executavel |
| /
| diretorio
|
| =
| socket
|
| @ | simbolic
link |
+---------+----------------+
Lembre-se sempre que voce pode especificar nomes
de arquivos (usando
wildcards ou nao) e diretorios ao comando ls.
Nao importanto onde voce
esteja, para listar os arquivos do diretorio "/usr"
basta voce usar "ls
/usr".
Vale lembrar que voce na maioria
dos casos voce pode usar varios
parametros simultaneamente.
Nota: o comando "ls"
e realmente muito completo, com dezenas de
parametros. Caso voce queira algo mais especifico, procure
consultar sua
manpage.
* O Comando "cd"
Como voce ja deve ter percebido lendo
as aulas anteriores, o comando
"cd" muda de diretorio. Sua sintaxe e
muito simples, bastando apenas
voce especificar como parametro o diretorio de destino.
Por exemplo, para mudar o
diretorio corrente para "/usr/local/bin"
usa-se "cd /usr/local/bin".
CURSO DE UNIX XI por rodrigo feher <feher@ibm.net>
* O Comando "rm"
Como no DOS existe o comando "del", no
UNIX o equivalente e o "rm".
Sua sintaxe e um tanto quanto
simples: para remover o arquivo
"misc.txt":
$ rm misc.txt
Para remover recursivamente use o parametro
"r". Por exemplo, para
remover os arquivos do diretorio "teste":
$ rm -r teste
Caso voce tente remover algum arquivo que seja
seu, mas nao tenha
setado o atributo de escrita "w", o programa
ira lhe perguntar se tem
certeza que deseja fazer aquilo. Para
passar por cima disso, use o
parametro "f" (force).
$ rm -f homework.tex
O parametro "f" tambem ignora arquivos
nao existentes e nunca faz
perguntas ao usuario.
Dica: para remover um diretorio e
tudo que ha dentro dele, use em
combinacao os parametros "f" e "r". Fica:
$ rm -fr teste
Isso ira eliminar todos os arquivos pertencentes
a teste e tambem a
propria entrada do diretorio. Portanto, tome *muito*
cuidado ao usar
este comando desta maneira.
Nota: sempre que for apagar algum arquivo,
pense duas vezes: uma vez
apagado, o arquivo muito dificilmente podera ser recuperado.
Nao existem
ferramentas como o "undelete" (DOS) para UNIX.
O parametro "i" e exatamente o inverso do "f":
ele causa uma execucao
interativa do programa. A cada arquivo que for processado
sera pedida
uma conformacao do usuario.
* O comando "mv"
O comando "mv" serve para
mover ou renomear (o que acaba dando na
mesma) arquivos e diretorios. Com
ele voce pode desde renomear um
simples arquivo ate mover toda uma arvore de diretorios para
outro lugar.
Para renomear o arquivo "teste.html" para "beta1.html":
$ mv teste.html beta1.html
Tome bastante cuidado ao tomar atitudes como
esta: caso o arquivo
beta1.html ja existir, ele sera destruido!
O parametro "i" causa a execucao do comando
"mv" no modo interativo:
para cada arquivo que sera destruido o programa pedira
a confirmacao por
parte do usuario.
Caso voce especifique mais que
dois arquivos, automaticamente o
programa percebera que voce quer mover um grupo
de arquivos para outro
diretorio. Neste caso o ultimo parametro
deve ser um diretorio; caso
contrario uma mensagem de erro sera emitida.
Para mover todos os arquivos que comecam com "a"
para "/usr/a" e todos
que comecam com "b" para "/usr/b":
$ mv a* /usr/a
$ mv b* /usr/b
* O comando "cp"
O comando "cp" serve para fazermos copias de arquivos.
Na sua forma
reduzida, remos:
$ cp sent-mail-jan96 backup
O comando acima ira fazer uma copia do arquivo "sent-mail-jan96"
para
o arquivo "backup". Use tambem com cautela
este comando: voce podera
facilmente destruir arquivos importantes se
o alvo da copia for um
arquivo ja existente!
Para evitar problemas, use o parametro "i":
ele executa o programa em
modo interativo. Como no comando "mv", sera pedida uma
confirmacao antes
que o arquivo seja destruido.
Algumas versoes do programa "cp" possuem o parametro
"r". Ele e usado
para fazer copias de arvores completas. Por exemplo:
$ cp -p /usr/X11 /backup
O comando acima ira fazer uma copia recursiva
do diretorio "/usr/X11"
para "/backup".