



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
Neste artigo do papo de botequim, publicado na edição 09 de junho de 2005 da linux magazine br, júlio cezar neves aborda as mensagens de erro e as perguntas feitas ao usuário no shell script. Ele explica como mostrar mensagens personalizadas na tela usando a função printf e as principais variáveis do shell. Além disso, o autor aborda o tema da expansão de parâmetros, mostrando como substituir subcadeias em uma cadeia e cortar partes de uma cadeia de acordo com expressões. O artigo também inclui exemplos práticos.
Tipologia: Notas de estudo
1 / 6
Esta página não é visível na pré-visualização
Não perca as partes importantes!




á bom, já sei que você vai querer chope antes de começar, mas tô tão a fi m de te mostrar o que fi z que já vou pedir a rodada enquanto isso. Aê Chico, manda dois! O dele é sem colarinho pra não deixar cheiro ruim nesse bigodão… Enquanto o chope não chega, deixa eu te lembrar o que você me pediu na edição passada: era para refazer o programa listartista com a tela formatada e exe- cução em loop, de forma que ele só termine quando receber um [ENTER] sozinho como nome do artista. Eventuais mensagens de erro e perguntas feitas ao usuário deveriam ser mostradas na antepenúltima linha da tela, utilizando para isso as rotinas externas mandamsg.func e pergunta.func que desenvolvemos durante nosso papo na edição passada. Primeiramente eu dei uma encolhida nas rotinas mandamsg.func e pergunta.func , que ficaram como na listagem 1. E na listagem 2 você tem o “grandão”, nossa versão refeita do listaartista.
Ufa! Agora você já sabe tudo sobre leitura de dados, mas quanto à escrita ainda está apenas engatinhando. Já sei que você vai me perguntar: “Ora, não é com o comando echo e com os redirecionamentos de saída que se escreve dados?”. Bom, a resposta é "mais ou menos". Com estes comandos você escreve 90% do que precisa, porém se precisar escrever algo formatado eles lhe darão muito trabalho. Para formatar a saída veremos agora uma instrução muito mais interessante, a printf. Sua sintaxe é a seguinte:
Dave Hamilton - www.sxc.hu Listagem 1: mandamsg.func e pergunta.func
01 # A função recebe somente um parâmetro 02 # com a mensagem que se deseja exibir. 03 # Para não obrigar o programador a passar 04 # a msg entre aspas, usaremos $ (todos 05 # os parâmetro, lembra?) e não $1. 06 Msg="$" 07 TamMsg=${#Msg} 08 Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha 09 tput cup $LinhaMesg $Col 10 read -n1 -p "$Msg "**
01 # A função recebe 3 parâmetros na seguinte ordem: 02 # $1 - Mensagem a ser mostrada na tela 03 # $2 - Valor a ser aceito com resposta padrão 04 # $3 - O outro valor aceito 05 # Supondo que $1=Aceita?, $2=s e $3=n, a linha 06 # abaixo colocaria em Msg o valor "Aceita? (S/n)" 07 Msg="$1 (echo $2 | tr a-z A-Z/echo $3 | tr A-Z a-z)" 08 TamMsg=${#Msg} 09 Col=$(((TotCols - TamMsg) / 2)) # Centraliza msg na linha 10 tput cup $LinhaMesg $Col 11 read -n1 -p "$Msg " SN 12 [! $SN ] && SN=$2 # Se vazia coloca default em SN 13 SN=$(echo $SN | tr A-Z a-z) # A saída de SN será em minúscula 14 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela
junho 2005 edição 09
printf formato [argumento...] Onde formato é uma cadeia de caracteres que contém três tipos de objeto: caracteres simples, caracteres para es- pecificação de formato (ou de controle ) e seqüência de esca- pe no padrão da linguagem C. argumento é a cadeia de caracteres a ser impressa sob o controle de formato. Cada um dos caracteres uti- lizados é precedido pelo ca- racter % e, logo a seguir, vem a especificação de formato de acordo com a tabela 1. As seqüências de escape padrão da linguagem C são sempre precedidas pelo ca- ractere contra-barra ( ** ). As reconhecidas pelo comando printf são as da tabela 2. Não acaba por aí não! Tem muito mais coisa sobre essa instrução, mas como esse é um assunto muito cheio de detalhes e, portanto, chato para explicar e pior ainda para ler ou estudar, vamos passar direto aos exemplos com co- mentários. Veja só: $ printf "%c" "1 caracter" 1$ Errado! Só listou 1 caractere e não saltou linha ao final $ printf "%c\n" "1 caracter" 1 Saltou linha mas ainda não listou a cadeia inteira $ printf "%c caractere\n" 1
**Listagem 2: listaartista $ cat listartista3.sh 01 #!/bin/bash 02 # Dado um artista, mostra as suas musicas 03 # versao 3 04 LinhaMesg=$((tput lines - 3)) # Linha onde as msgs serão mostradas 05 TotCols=$(tput cols) # Qtd de colunas na tela para enquadrar msgs 06 clear 07 echo " +–––––––––––––––––-----------------------------------+ | Lista Todas as Músicas de um Determinado Artista | | ===== ===== == ======= == == =========== ======= | | | | Informe o Artista: | +––––––––––––––––----------------------------------–-+" 08 while true 09 do 10 tput cup 5 51; tput ech 31 # ech=Erase chars (31 para não apagar barra vertical) 11 read Nome 12 if [! "$Nome" ] # $Nome esta vazio? 13 then
$ printf “EXEMPLO %x\n” 45232 EXEMPLO b0b Ele transformou o número 45232 para hexadecimal ( b0b0 ), mas os zeros não combinam com o resto. Experimente: $ printf “EXEMPLO %X\n” 45232 EXEMPLO B0B Assim disfarçou melhor! (repare no X maiúsculo). Pra terminar, que tal o co- mando abaixo: $ printf “%X %XL%X\n” 49354 192 10 C0CA C0LA Este aí não é marketing e é bastante completo, veja só como funciona: O primeiro %X converteu 49354 em he- xadecimal, resultando em C0CA (leia-se “cê”, “zero”, “cê” e “a”). Em seguida veio um espaço em branco seguido por outro %XL. O %X converteu o 192 dando como resultado C0 que com o L fez C0L. E final- mente o último parâmetro %X transformou o número 10 na letra A. Conforme vocês podem notar, a instru- ção é bastante completa e complexa. Ain- da bem que o echo resolve quase tudo... Acertei em cheio quando resolvi expli- car o printf através de exemplos, pois não saberia como enumerar tantas regri- nhas sem tornar a leitura enfadonha.
O Bash possui diversas variáveis que servem para dar informações sobre o ambiente ou alterá-lo. São muitas e não pretendo mostrar todas elas, mas uma pequena parte pode lhe ajudar na elaboração de scripts. Veja a seguir as principais delas: CDPATH » Contém os caminhos que serão pesquisados para tentar localizar um diretório especificado. Apesar dessa variável ser pouco conhecida, seu uso deve ser incentivado por poupar muito trabalho, principalmente em instalações com estrutura de diretórios em múltiplos níveis. Veja o exemplo a seguir: $ echo $CDPATH .:..:~:/usr/local $ pwd /home/jneves/LM $ cd bin $ pwd /usr/local/bin Como /usr/local estava na minha variável $CDPATH e não existia o diretório bin em nenhum dos seus antecessores (. , .. e ~ ), o comando cd foi executado tendo como destino /usr/local/bin. HISTSIZE » Limita o número de ins- truções que cabem dentro do arquivo de histórico de comandos (normalmente .bash_history , mas na verdade é o que está indicado na variável $HISTFILE ). Seu valor padrão é 500. HOSTNAME » O nome do host corrente (que também pode ser obtido com o co- mando uname -n ). LANG » Usada para determinar o idioma falado no país (mais especificamente ca- tegoria do locale ). Veja um exemplo: $ date Thu Apr 14 11:54:13 BRT 2005 $ LANG=pt_BR date Qui Abr 14 11:55:14 BRT 2005 LINENO » O número da linha do script ou função que está sendo executada. Seu uso principal é mostrar mensagens de erro juntamente com as variáveis $ (nome do programa) e $FUNCNAME (nome da função em execução). LOGNAME » Esta variável armazena o nome de login do usuário. MAILCHECK » Especifica, em segundos, a freqüência com que o Shell verifica a pre- sença de correspondência nos arquivos indicados pela variáveis $MAILPATH ou $MAIL. O tempo padrão é de 60 segundos (1 minuto). A cada intervalo o Shell fará a verificação antes de exibir o próximo prompt primário ( $PS1 ). Se essa variável estiver sem valor ou com um valor menor ou igual a zero, a busca por novas men- sagens não será efetuada. PATH » Caminhos que serão pesquisa- dos para tentar localizar um arquivo espe- cificado. Como cada script é um arquivo, caso use o diretório corrente (. ) na sua variável $PATH , você não necessitará usar o comando ./scrp para que o script scrp seja executado. Basta digitar scrp. Este é o modo que prefiro. PIPESTATUS » É uma variável do tipo vetor ( array ) que contém uma lista de valores de códigos de retorno do último pipeline executado, isto é, um array que abriga cada um dos $? de cada instrução do último pipeline. Para entender melhor, veja o exemplo a seguir: $ who jneves pts/0 Apr 11 16:26 (10.2.4.144) jneves pts/1 Apr 12 12:04 (10.2.4.144) $ who | grep ^botelho $ echo ${PIPESTATUS[]} 0 1 Neste exemplo mostramos que o usu- ário botelho não estava “logado”, em seguida executamos um pipeline que procurava por ele. Usa-se a notação [] em um array para listar todos os seus elementos; dessa forma, vimos que a pri- meira instrução ( who ) foi bem-sucedida (código de retorno 0 ) e a seguinte ( grep ) não (código de retorno 1 ). PROMPT_COMMAND » Se esta variável re- ceber o nome de um comando, toda vez que você teclar um [ENTER] sozinho no prompt principal ( $PS1 ), esse comando será executado. É muito útil quando você precisa repetindo constantemente uma determinada instrução. PS1 » É o prompt principal. No “Papo de Botequim” usamos os padrões $ para usuário comum e # para root, mas é mui-
to freqüente que ele esteja personalizado. Uma curiosidade é que existe até concurso de quem programa o $PS1 mais criativo. PS2 » Também chamado “prompt de continuação”, é aquele sinal de maior ( > ) que aparece após um [ENTER] sem o comando ter sido encerrado. PWD » Possui o caminho completo ( $PATH ) do diretório corrente. Tem o mesmo efeito do comando pwd. RANDOM » Cada vez que esta variável é acessada, devolve um inteiro aleatório en- tre 0 e 32767. Para gerar um inteiro entre 0 e 100, por exemplo, digitamos: $ echo $((RANDOM%101)) 73 Ou seja, pegamos o resto da divisão do número randômico gerado por 101 porque o resto da divisão de qualquer número por 101 varia entre 0 e 100. REPLY » Use esta variável para recuperar o último campo lido, caso ele não tenha nenhuma variável associada. Exemplo: $ read -p "Digite S ou N: " Digite S ou N: N $ echo $REPLY N SECONDS » Esta variável informa, em se- gundos, há quanto tempo o Shell corrente está “de pé”. Use-a para demonstrar a estabilidade do Linux e esnobar usuários daquela coisa com janelinhas coloridas que chamam de sistema operacional, mas que necessita de “reboots” freqüentes. TMOUT » Se esta variável contiver um valor maior do que zero, esse valor será considerado o timeout padrão do comando read. No prompt, esse valor é interpretado como o tempo de espera por uma ação antes de expirar a sessão. Supondo que a variável contenha o valor 30 , o Shell encerrará a sessão do usuário (ou seja, fará logout ) após 30 segundos sem nenhuma ação no prompt.
Bem, muito do que vimos até agora são comandos externos ao Shell. Eles quebram o maior galho, facilitam a visualização, manutenção e depuração do código, mas não são tão eficientes quanto os intrínse- cos ( built-ins ). Quando o nosso problema for performance, devemos dar preferência ao uso dos intrínsecos. A partir de agora vou te mostrar algumas técnicas para o seu programa pisar no acelerador. Na tabela 3 e nos exemplos a seguir, veremos uma série de construções cha- madas expansão (ou substituição) de parâmetros ( Parameter Expansion ), que substituem instruções como o cut , o expr , o tr , o sed e outras de forma mais ágil. Vamos ver alguns exemplos: se em uma pergunta o S é oferecido como valor de- fault (padrão) e a saída vai para a variável SN , após ler o valor podemos fazer: SN=$(SN:-S} Para saber o tamanho de uma cadeia : $ cadeia= $ echo ${#cadeia} 4 Para extrair dados de cadeia , da posi- ção um até o final fazemos: $ cadeia=abcdef $ echo ${cadeia:1} bcdef Repare que a origem é zero e não um. Vamos extrair 3 caracteres a partir da 2ª posição da mesma variável cadeia : $ echo ${cadeia:2:3} cde Repare que novamente a origem da con- tagem é zero e não um. Para suprimir tudo à esquerda da primeira ocorrência de uma cadeia, faça: $ cadeia="Papo de Botequim" $ echo ${cadeia#' '} de Botequim $ echo "Conversa "${cadeia#' '} Conversa de Botequim No exemplo anterior foi suprimido à esquerda tudo o que “casa” com a menor ocorrência da expressão ’ ‘ , ou seja, todos os caracteres até o primeiro espaço em branco. Esses exemplos também po- deriam ser escritos sem proteger o espaço da interpretação do Shell (mas prefiro protegê-lo para facilitar a legibilidade do código). Veja só: $ echo ${cadeia# } de Botequim $ echo "Conversa "${cadeia#* } Conversa de Botequim Repare que na construção de expr é permitido o uso de metacaracteres. Utilizando o mesmo valor da variável cadeia , observe como faríamos para ter somente Botequim : $ echo ${cadeia##' '} Botequim $ echo "Vamos 'Chopear' no "${cadeia##' '} Vamos 'Chopear' no Botequim Desta vez suprimimos à esquerda de cadeia a maior ocorrência da expressão expr. Assim como no caso anterior, o uso de metacaracteres é permitido. Outro exemplo mais útil: para que não apareça o caminho ( path ) completo do seu programa ( $0 ) em uma mensagem de erro, inicie o seu texto da seguinte forma: echo Uso: ${0##*/} texto da mensagem de erro Neste exemplo seria suprimido à es- querda tudo até a última barra ( / ) do caminho, restando somente o nome do programa. O caractere % é simétrico ao # , veja o exemplo:
junho 2005 edição 09