



Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Encontra documentos específicos para os exames da tua universidade
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Você não agüenta mais aquele seu amigo usuário de Linux enchendo o seu saco com aquela história de que o sistema é fantástico e o Shell é uma ferramenta maravilhosa? A partir desta edição vai ficar mais fácil entender o porquê deste entusiasmo... POR JULIO CEZAR NEVES
Tipologia: Notas de estudo
1 / 5
Esta página não é visível na pré-visualização
Não perca as partes importantes!




Papo de Botequim LINUX USER
www.linuxmagazine.com.br Outubro 2004 85
arçon! traga dois chopes por favor que hoje eu vou ter que falar muito. Primeiro quero mostrar uns programinhas simples de usar e muito úteis, como o cut , que é usado para cortar um determinado pedaço de um arquivo. A sintaxe e alguns exemplos de uso podem ser vis- tos no Quadro 1: Como dá para ver, existem quatro sintaxes distintas: na primeira ( -c 1-5 ) especifiquei uma faixa, na segunda ( -c -6 ) especifiquei todo o texto até uma posição, na terceira ( -c 4- ) tudo de uma determinada posição em diante e na quarta ( -c 1,3,5,7,9 ), só as posições determinadas. A última possibilidade ( -c -3,5,8- ) foi só para mostrar que pode- mos misturar tudo. Mas não pense que acabou por aí! Como você deve ter percebido, esta forma de cut é muito útil para lidar com arquivos com campos de tamanho fi xo, mas atualmente o que mais existe são arquivos com campos de tamanho vari- ável, onde cada campo termina com um delimitador. Vamos dar uma olhada no arquivo musicas que começamos a pre- parar na última vez que viemos aqui no botequim. Veja o Quadro 2. Então, recapitulando, o layout do arquivo é o seguinte: nome do álbum^intérprete1~nome da música1:...: intérpreten~nome da músican , isto é, o nome do álbum será separado por um circunflexo (^) do resto do registro, que é formado por diversos grupos compos- tos pelo intérprete de cada música do CD e a respectiva música interpretada. Estes grupos são separados entre si por dois-pontos (:) e o intérprete será sepa- rado do nome da música por um til (~). Então, para pegar os dados referentes a todas as segundas músicas do arquivo musicas, devemos digitar: $ cut -f2 -d: musicas Artista2~Musica Artista4~Musica Artista6~Musica Artista8~Musica8@10_L: Ou seja, cortamos o segundo campo z( -f de field , campo em inglês) delimi- tado ( -d ) por dois-pontos ( : ). Mas, se quisermos somente os intérpretes, deve- mos digitar: $ cut -f2 -d: musicas | cut U -f1 -d~ Artista Artista Artista Artista Para entender melhor isso, vamos anali- sar a primeira linha de musicas: $ head -1 musicas album 1^Artista1~Musica1: U Artista2~Musica Então observe o que foi feito: album 1^Artista1~Musica1: U Artista2~Musica Desta forma, no primeiro cut o primeiro campo do delimitador ( -d ) dois-pon- tos ( : ) é album 1^Artista1~Musica1 e o segundo, que é o que nos interessa, é Artista2~Musica2. Vamos então ver o que aconteceu no segundo cut: Artista2~Musica Agora, primeiro campo do delimitador ( -d ) til (~), que é o que nos interessa, é Artista2 e o segundo é Musica2. Se o raciocínio que fizemos para a pri- Um chopinho, um aperitivo e o papo continua. Desta vez vamos aprender alguns comandos de manipulação de cadeias de caracteres, que serão muito úteis na hora de incrementar nossa “CDteca”. POR JULIO CEZAR NEVES Curso de Shell Script
botequim III
������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
��������������������������������������������������
��������������������������������������������������
86 Outubro 2004 www.linuxmagazine.com.br LINUX USER^ Papo de Botequim meira linha for aplicado ao restante do arquivo, chegaremos à resposta ante- riormente dada. Outro comando muito interessante é o tr que serve para subs- tituir, comprimir ou remover caracteres. Sua sintaxe segue o seguinte padrão: tr [opções] cadeia1 [cadeia2] O comando copia o texto da entrada padrão ( stdin ), troca as ocorrência dos caracteres de cadeia1 pelo seu corres- pondente na cadeia2 ou troca múltiplas ocorrências dos caracteres de cadeia por somente um caracter, ou ainda caracteres da cadeia1. As principais opções do comando são mostradas na Tabela 1. Primeiro veja um exemplo bem bobo: $ echo bobo | tr o a baba Isto é, troquei todas as ocorrências da letra o pela letra a. Suponha que em determinado ponto do meu script eu peça ao operador para digitar s ou n (sim ou não), e guardo sua resposta na variável $Resp. Ora, o conteúdo de $Resp pode conter letras maiúsculas ou minúsculas, e desta forma eu teria que fazer diversos testes para saber se a resposta dada foi S, s, N ou n. Então o melhor é fazer: $ Resp=$(echo $Resp | tr SN sn) e após este comando eu teria certeza de que o conteúdo de $Resp seria um s ou um n. Se o meu arquivo ArqEnt está todo em letras maiúsculas e desejo passá-las para minúsculas eu faço: $ tr A-Z a-z < ArqEnt > / tmp/$$ $ mv -f /tmp/$$ ArqEnt Note que neste caso usei a notação A- Z para não escrever ABCD…YZ. Outro tipo de notação que pode ser usada são as escape sequences (como eu traduzi- ria? Seqüências de escape? Meio sem sentido, né? Mas vá lá…) que também são reconhecidas por outros comandos e também na linguagem C, e cujo signi- ficado você verá na Tabela 2: Deixa eu te contar um “causo”: um aluno que estava danado comigo resol- veu complicar minha vida e como res- posta a um exercício prático, valendo nota, que passei ele me entregou um script com todos os comandos sepa- rados por ponto-e-vírgula (lembre-se que o ponto-e-vírgula serve para sepa- rar diversos comandos em uma mesma linha). Vou dar um exemplo simplifi- cado, e idiota, de um script assim: $ cat confuso echo leia Programação Shell U Linux do Julio Cezar Neves U > livro;cat livro;pwd;ls;rm U -f livro2>/dev/null;cd ~ Eu executei o programa e ele funcionou: $ confuso leia Programação Shell Linux U do Julio Cezar Neves /home/jneves/LM confuso livro musexc musicas musinc muslist numeros Mas nota de prova é coisa séria (e nota de dólar é mais ainda) então, para entender o que o aluno havia feito, o chamei e em sua frente digitei: $ tr ”;” ”\n” < confuso echo leia Programação Shell U Linux do Julio Cezar Neves pwd cd ~ ls -l rm -f lixo 2>/dev/null O cara ficou muito desapontado, porque em dois ou três segundos eu desfi z a gozação que ele perdeu horas para fazer. Mas preste atenção! Se eu estivesse em uma máquina Unix, eu teria digitado: $ tr ”;” ”\012” < confuso Agora veja a diferença entre o resultado de um comando date executado hoje e outro executado há duas semanas: Sun Sep 19 14:59:54 2004 Sun Sep 5 10:12:33 2004 Notou o espaço extra após o “Sep” na segunda linha? Para pegar a hora eu deveria digitar: $ date | cut -f 4 -d ’ ’ 14:59: A sintaxe do cut é: cut -c PosIni-PosFim [arquivo] , onde PosIni é a posição inicial, e PosFim a posição final. Veja os exemplos: $ cat numeros 1234567890 0987654321 1234554321 9876556789 $ cut -c1-5 numeros 12345 09876 12345 98765 $ cut -c-6 numeros 123456 098765 123455 987655 $ cut -c4- numeros 4567890 7654321 4554321 6556789 $ cut -c1,3,5,7,9 numeros 13579 08642 13542 97568 $ cut -c -3,5,8- numeros 1235890 0986321 1235321 9875789 Quadro 1 – O comando cut $ cat musicas album 1^Artista1~Musica1:U Artista2~Musica album 2^Artista3~Musica3:U Artista4~Musica album 3^Artista5~Musica5:U Artista6~Musica album 4^Artista7~Musica7:U Artista8~Musica Quadro 2 – O arquivo musicas
������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
��������������������������������������������������
��������������������������������������������������
88 Outubro 2004 www.linuxmagazine.com.br LINUX USER^ Papo de Botequim $ ls musicas musicas $ echo $? 0 $ ls ArqInexistente ls: ArqInexistente: No such U fi le or directory $ echo $? 1 $ who | grep jneves jneves pts/1 Sep 18 U 13:40 (10.2.4.144) $ echo $? 0 $ who | grep juliana $ echo $? 1 O que é que esse $? faz aí? Algo come- çado por cifrão ($) parece ser uma vari- ável, certo? Sim é uma variável que contém o código de retorno da última instrução executada. Posso te garan- tir que se esta instrução foi bem suce- dida, $? terá o valor zero, caso contrário seu valor será diferente de zero. O que nosso comando condicional (if) faz é testar esta variável. Então vamos ver a sua sintaxe: if cmd then cmd cmd cmdn else cmd cmd cmdm fi Ou seja, caso comando cmd tenha sido executado com sucesso, os comandos do bloco do then ( cmd1, cmd2 e cmdn ) serão executados, caso contrário, os comandos do bloco opcional do else ( cmd3, cmd4 e cmdm ) serão executados. O bloco do if é terminando com um fi. Vamos ver na prática como isso fun- ciona, usando um script que inclui usu- ários no arquivo /etc/passwd : $ cat incusu #!/bin/bash
if grep ^$1 /etc/passwd then echo Usuario \’$1\’U já existe else if useradd $ then echo Usuário \’$1\’ U incluído em /etc/passwd else echo ”Problemas no U cadastramento. Você é root?” fi fi Repare que o if está testando direto o comando grep e esta é a sua fi nalidade. Caso o if seja bem sucedido, ou seja, o usuário (cujo nome está em $1 ) foi encontrado em /etc/passwd , os coman- dos do bloco do then serão executados (neste exemplo, apenas o echo). Caso contrário, as instruções do bloco do else serão executadas, quando um novo if testa se o comando useradd foi execu- tado a contento, criando o registro do usuário em /etc/passwd , ou exibindo uma mensagem de erro, caso contrário. Executar o programa e passe como parâmetro um usuário já cadastrado: $ incusu jneves jneves:x:54002:1001:Julio Neves:U /home/jneves:/bin/U bash Usuario ’jneves’ ja existe No exemplo dado, surgiu uma linha indesejada, ela é a saída do comando grep. Para evitar que isso aconteça, devemos desviar a saída para /dev/null. O programa fica assim: $ cat incusu #!/bin/bash
if grep ^$1 /etc/passwd > U /dev/null then echo Usuario \’$1\’ já U existe else if useradd $ then echo Usuário \’$1\’ U incluído em /etc/passwd else echo ”Problemas no U cadastramento. Você é root?” fi fi Vamos testá-lo como um usuário normal : $ incusu ZeNinguem ./incusu[6]: useradd: not found Problemas no cadastramento. U Você é root? Aquela mensagem de erro não deveria aparecer! Para evitar isso, devemos redirecionar a saída de erro ( stderr ) do comando useradd para /dev/null. A ver- são fi nal fica assim: $ cat incusu #!/bin/bash
if grep ^$1 /etc/passwd > U /dev/null then echo Usuario \’$1\’ já U existe else if useradd $1 2> /dev/null then echo Usuário \’$1\’ U incluído em /etc/passwd else echo ”Problemas no U cadastramento. Você é root?” fi fi Depois disso, vejamos o comportamento do programa, se executado pelo root: $ incusu botelho Usuário ’botelho’ incluido em U /etc/passwd E novamente: $ incusu botelho Usuário ’botelho’ já existe Seqüência Significado Octal \t Tabulação \n Nova linha
\v Tabulação Vertical \f Nova Página \r Início da linha <^M> \ Uma barra invertida Tabela 2
��������������������������������������������������
���������������������������������������������������
��������������������������������������������������
���������������������������������������������������
Papo de Botequim LINUX USER ���������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ www.linuxmagazine.com.br Outubro 2004 89 Lembra que eu falei que ao longo dos nossos papos e chopes os nossos pro- gramas iriam se aprimorando? Então vejamos agora como podemos melhorar o nosso programa para incluir músicas na "CDTeca": $ cat musinc #!/bin/bash
if grep ”^$1$” musicas > U /dev/null then echo Este álbum já está U cadastrado else echo $1 >> musicas sort musicas -o musicas fi Como você viu, é uma pequena evolu- ção em relação à versão anterior. Antes de incluir um registro (que na versão anterior poderia ser duplicado), testa- mos se o registro começa (^) e termina ($) de forma idêntica ao parâmetro álbum passado ($1). O circunflexo (^) no início da cadeia e cifrão ($) no fi m, servem para testar se o parâmetro (o álbum e seus dados) é exatamente igual a algum registro já existente. Vamos executar nosso programa novamente, mas desta vez passamos como parâme- tro um álbum já cadastrado, pra ver o que acontece: $ musinc ”album 4^Artista7~U Musica7:Artista8~Musica8” Este álbum já está cadastrado E agora um não cadastrado: $ musinc ”album 5^Artista9~U Musica9:Artista10~Musica10” $ cat musicas album 1^Artista1~Musica1:U Artista2~Musica album 2^Artista3~Musica3:U Artista4~Musica album 3^Artista5~Musica5:U Artista6~Musica album 4^Artista7~Musica7:U Artista8~Musica album 5^Artista9~Musica9:U Artista10~Musica Como você viu, o programa melho- rou um pouquinho, mas ainda não está pronto. À medida que eu te ensinar a programar em shell, nossa CDteca vai ficar cada vez melhor.
mas ainda não sei como fazer um if para testar condições, ou seja o uso normal do comando.
testa condições. O comando if testa o comando test. Como já falei muito, preciso de uns chopes para molhar a palavra. Vamos parar por aqui e na próxima vez te explico direitinho o uso do test e de diversas outras sinta- xes do if.
também já tô ficando zonzo e assim tenho tempo para praticar esse monte de coisas que você me falou hoje. Para fi xar o que você aprendeu, tente fazer um scriptizinho para informar se um determinado usuário, cujo nome será passado como parâmetro, está “logado” no sistema ou não.
mim por favor… ■