Difference: TWikiBarChiacchiere002 (1 vs. 7)

Revision 719 Feb 2013 - AlbertoTaddei

Line: 1 to 1
 
META TOPICPARENT name="BatePapos"

Chiacchiere da Bar Parte II

Line: 10 to 10
     - Calma, calma, quello di cui ti ho parlato finora è la base di ciò che arriverà dopo. Useremo questi strumenti per costruire programmi strutturati, cosa che la Shell permette di fare. Allora capirai perché in TV hanno trasmesso il programma "La Shell è il Limite".
    - Inizieremo parlando dei comandi della famiglia grep.
    - grep? Non conosco nessuna parola del genere in inglese...
Changed:
<
<
    - Certo, grep è l'acronimo di Global Regular Expression Print, che usa espressioni regolari per la ricerca di stringhe di caratteri in un input definito (c'è una leggenda sul perché questo comando ha quel nome: nell'editor di testi "ed", il nonno di "vim", il comando di ricerca usato era g/_espressione regolare_/p o, in inglese, g/_re_/p.). Dato che parliamo di espressioni regolari (o regexp), Aurélio Marinho Jargas dà tutte le indicazioni necessarie (tutorial inclusi) nella sua pagina web. Se vuoi imparare a programmare in Shell, Perl, Python, ... ti consiglio di leggerteli per non avere difficoltà più avanti.
>
>
    - CI credo, grep è l'acronimo di Global Regular Expression Print e usa espressioni regolari per la ricerca di stringhe di caratteri nell'input definito (c'è una leggenda sul perché questo comando ha quel nome: nell'editor di testi "ed", il nonno di "vim", il comando di ricerca usato era g/_espressione regolare_/p o, in inglese, g/_re_/p.). Dato che parliamo di espressioni regolari (o regexp), Aurélio Marinho Jargas dà tutte le indicazioni necessarie (tutorial inclusi) nella sua pagina web. Se vuoi imparare a programmare in Shell, Perl, Python, ... ti consiglio di leggerteli per non avere difficoltà più avanti.
 

Io mi tengo grep, per te un groppo in gola

Changed:
<
<
Quello del groppo non è altro che uno scherzo! È solo un pretesto per ordinare qualche caipirinha. Tornando a bomba, poco fa ti ho detto che grep ricerca stringhe di caratteri in un input definito, ma che cos'è un "input definito"? Esistono diversi modi di definire l'input del comando grep. Vediamo:
>
>
Quello del groppo non è altro che uno scherzo! È solo un pretesto per ordinare qualche caipirinha. Tornando a bomba, poco fa ti ho detto che grep ricerca stringhe di caratteri nell'input definito, ma che cos'è l'"input definito"? Esistono diversi modi di definire l'input del comando grep. Vediamo:
  Ricerca all'interno di un file:
Line: 40 to 40
 $ grep '^rafael' /etc/passwd
Changed:
<
<
Di certo mi chiederai a cosa servono l'accento circonflesso e gli apostrofi. Se tu avessi letto le indicazioni sulle espressioni regolari di cui ti ho parlato prima, sapresti che l'accento circonflesso serve a limitare la ricerca all'inizio di ogni riga, mentre gli apostrofi (') fanno in modo che la Shell non interpreti l'accento circonflesso così che questi attraversi incolume il comando grep.
>
>
Di certo mi chiederai a cosa servono l'accento circonflesso e gli apostrofi. Se tu avessi letto le indicazioni sulle espressioni regolari di cui ti ho parlato prima, sapresti che l'accento circonflesso (^) serve a limitare la ricerca all'inizio di ogni riga, mentre gli apostrofi (') fanno in modo che la Shell non interpreti l'accento circonflesso così che questi attraversi incolume il comando grep.
 
Changed:
<
<
Guarda che figata! Il comando grep accetta come input l'output di un altro comando redirezionato da una pipe (questa cosa è molto comune nell'ambiente Shell e rende molto più rapida l'esecuzione di un comando: è come se l'output di un programma fosse salvato sul disco rigido e il secondo programma leggesse il file così generato). In questo modo, nel terzo esempio, il comando who ha generato l'elenco degli utenti "loggati" sulla tua stessa macchina (non dimenticarlo mai: Linux è multiutente) e grep è stato usato per verificare se Pelegrino lavorava o "si grattava".
>
>
Guarda che figata! Il comando grep accetta come input l'output di un altro comando redirezionato da una pipe (ciò è molto comune nell'ambiente Shell e rende molto più rapida l'esecuzione di un comando: è come se l'output di un programma fosse salvato sul disco rigido e il secondo programma leggesse il file così generato). In questo modo, nel terzo esempio, il comando who ha generato l'elenco degli utenti "loggati" sulla tua stessa macchina (non dimenticarlo mai: Linux è multiutente) e grep è stato usato per verificare se Pelegrino lavorava o "si grattava".
 

La famiglia grep

Line: 62 to 62
      - Adesso che conosci le differenze tra i membri della famiglia, dimmi: cosa pensi degli esempi che ti ho fatto prima delle spiegazioni?
    - Penso che fgrep avrebbe risolto il tuo problema più rapidamente di grep.
Changed:
<
<
    - Perfetto! Vedo che stai attento e che capisci tutto quello che ti ho spiegato! Allora diamo un'occhiata a qualche altro esempio per rendere più chiare una volta per tutte le differenze d'uso tra i membri della famiglia.
>
>
    - Perfetto! Vedo che stai attento e che hai capito tutto ciò che ti ho spiegato! Allora diamo un'occhiata a qualche altro esempio per rendere più chiare una volta per tutte le differenze d'uso tra i membri della famiglia.
  Esempi
Line: 72 to 72
 $ egrep (Linux | linux) file.txt
Changed:
<
<
ou
>
>
oppure
 
$ grep [Ll]inux file.txt
Line: 80 to 80
  Nel primo caso, l'espressione regolare complessa "(Linux | linux)" fa uso delle parentesi per raggruppare le opzioni e della barra verticale (|) come di un "o" logico,cioè cerco Linux o linux.
Changed:
<
<
Nel secondo, l'espressione regolare [Ll]inux significa: inizia per L o l ed è seguito da inux. Poiché questa espressione è più semplice, grep riesce a risolverla, per cui ritengo migliore usare la seconda forma visto che egrep renderebbe la ricerca più lenta.
>
>
Nel secondo, l'espressione regolare [Ll]inux significa: inizia per L o l ed è seguito da inux. Poiché questa espressione è più semplice, grep riesce a risolverla, per cui ritengo sia meglio usare la seconda forma visto che egrep renderebbe la ricerca più lenta.
  Un altro esempio. Per avere l'elenco delle sottodirectory della directory corrente è sufficiente digitare:
Line: 190 to 190
 3o. parm -> prova
Changed:
<
<
Le virgolette hanno impedito alla Shell di vedere lo spazio tra le parole le quali sono state considerate come un unico parametro.
>
>
Le virgolette hanno impedito alla Shell di vedere lo spazio tra le parole, le quali sono state considerate come un unico parametro.
 

Gruppi parametrici

Line: 261 to 261
 
  1. Per far vedere che i nomi dei parametri variano da $1 a $9 ho eseguito un echo $11 e cos'è accaduto? La Shell lo ha interpretato come se fosse $1 seguito dal numero 1 e ha mostrato inserimento1;
  2. Il comando shift, la cui sintassi è shift n con n che può assumere un qualunque valore numerico (di default è 1 come nell'esempio), scarta i primi n parametri trasformando il parametro n+1 nel primo, cioè $1.
Changed:
<
<
Bene, ora che di immissione di parametri ne sai più di me, torniamo alla nostra "cdteca" per realizzare o script per inserire i CD nella mia banca dati chiamata canzoni. il programma è molto semplice (come, del resto, ogni cosa nella Shell) e li elencherò per farteli vedere:
>
>
Bene, ora che di immissione di parametri ne sai più di me, torniamo alla nostra "cdteca" per realizzare lo script per inserire i CD nella mia banca dati chiamata canzoni. il programma è molto semplice (come, del resto, ogni cosa nella Shell) e lo commenterò per fartelo vedere:
  Esempi
Line: 290 to 290
 disco 2^Artista3~Canzone3:Artista4~Canzone4
Changed:
<
<
Non è funzionale come pensavo... avrebbe potuto venire meglio. I dischi non sono in ordine e ciò rende difficile la ricerca. Modifichiamo il nostro script e vediamo come funziona:
>
>
Non è funzionale come pensavo... avrebbe potuto venire meglio. I dischi non sono in ordine e ciò rende difficile la ricerca. Modifichiamo il nostro script e vediamo come gira:
 
$ cat insercanz
Line: 319 to 319
  Ho semplicemente inserito una riga che riordina il contenuto del file canzoni e redirige il risultato nel file stesso (a questo serve l'opzione -o) dopo l'inserimento di ogni disco.
Changed:
<
<
Evvai! Ora è davvero a posto e quasi funzionale. Ma stai attento, non disperare! Questa non è la versione finale. Il programma sarà migliore e più usabile nella nuova versione che scriveremo dopo aver capito come acquisire i dati dallo schermo e a formattare l'input.
>
>
Evvai! Ora è davvero a posto e quasi funzionale. Ma sta' attento, non disperare! Questa non è la versione finale. Il programma sarà migliore e più usabile nella nuova versione che scriveremo dopo aver capito come acquisire i dati dallo schermo e a formattare l'input.
  Esempi
Line: 364 to 364
 Se la stringa di caratteri da passare al comando comando grep contiene spazi o TAB anche all'interno di variabili, mettila sempre tra virgolette per evitare che le parole dopo il primo spazio o TAB siano interpretate come nomi di file.
Changed:
<
<
D'altro canto, nella ricerca è meglio ingorare maiuscole e minuscole. Risolveremmo entrambi i problemi se il programma fosse così:
>
>
D'altro canto, nella ricerca è meglio ignorare maiuscole e minuscole. Risolveremmo entrambi i problemi se il programma fosse così:
 
$ cat listcanz
Line: 374 to 374
 grep -i "$1" canzoni
Changed:
<
<
In questo caso, usiamo l'opzione -i di grep che, come già abbiamo visto, serve a ignorare maiuscole e minuscole, e abbiamo messo $1 tra virgolette affinché grep continuasse a vedere la stringa di caratteri risultante dall'espansione della riga effettuata dalla Shell come un unico argomento di ricerca.
>
>
In questo caso, abbiamo usato l'opzione -i di grep che, come già abbiamo visto, serve a ignorare maiuscole e minuscole, e abbiamo messo $1 tra virgolette affinché grep continuasse a vedere la stringa di caratteri risultante dall'espansione della riga effettuata dalla Shell come un unico argomento di ricerca.
 
$ listcanz "disco 2"
Line: 428 to 428
  Nella prima riga ho inviato in /tmp/canz$$ il file canzoni, senza i record relativi alla ricerca fatta dal comando grep. Poi ho spostato (cioè ho rinominato) /tmp/canz$$ sul vecchio canzoni.
Changed:
<
<
Ho usato il file /tmp/canz$$ come file di lavoro perché, come ho detto nella prima parte, il $$ conttiene il PID (Process Identification o identificativo del processo) e in questo modo chiunque modifichi il file canzoni lo farà su un file diverso, evitando possibili collisioni nell'uso.
>
>
Ho usato il file /tmp/canz$$ come file di lavoro perché, come ho detto nella prima parte, il $$ conttiene il PID (Process Identification o identificativo del processo) e in questo modo chiunque modifichi il file canzoni lo farà su un file diverso, evitando possibili conflitti nell'uso.
      - Beh, i programmi che abbiamo scritto finora sono piuttosto rudimentali perché ci mancano alcuni strumenti. Ma va bene così. Ora, mentre io mi scolo un'altra birretta, tu te ne vai a casa a fare pratica con gli esempi perché in breve svilupperemo un bel programmino per tenere in ordine i tuoi CD.
Changed:
<
<
    - Quando ci rivedremo ti insegnerò come funzionano i comandi condizionali e perfezioneremo quegli scripts.
>
>
    - Quando ci rivedremo ti insegnerò come funzionano i comandi condizionali e perfezioneremo quegli script.
      - Per oggi basta! Ho già chiacchierato troppo e ho bisogno di bagnarmi l'ugola, ho la gola secca!
    - Cameriere! Una birra alla spina senza schiuma!

Revision 630 Jan 2013 - AlbertoTaddei

Line: 1 to 1
 
META TOPICPARENT name="BatePapos"

Chiacchiere da Bar Parte II

Line: 434 to 434
      - Quando ci rivedremo ti insegnerò come funzionano i comandi condizionali e perfezioneremo quegli scripts.
    - Per oggi basta! Ho già chiacchierato troppo e ho bisogno di bagnarmi l'ugola, ho la gola secca!
    - Cameriere! Una birra alla spina senza schiuma!
Deleted:
<
<
Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.

Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para mim.

 \ No newline at end of file

Revision 502 May 2012 - JulioNeves

Line: 1 to 1
 
META TOPICPARENT name="BatePapos"

Chiacchiere da Bar Parte II

Line: 57 to 57
 
  • egrep (la "e" sta per extended, esteso) è molto potente se si usano le espressioni regolari. Poiché è il più lento della famiglia, è meglio usarlo solo quando è necessario elaborare un'espressione regolare non accettata da grep;
  • fgrep (la "f" sta per "fast", veloce, o per "file") è il più svelto della famiglia e, come dice il nome stesso, esegue il compito in modo molto rapido (a volte è circa il 30% più veloce di grep e il 50% più veloce di egrep), tuttavia non accetta come input le espressioni regolari nelle ricerche.
Changed:
<
<
Pinguim com placa de atenção
>
>
Penguin con un piatto di attenzione
 Quanto detto sulla velocità si applica soltanto alla famiglia di comandi grep di Unix. In Linux grep è sempre il più rapido visto che gli altri due (fgrep e egrep) sono scripts della Shell che richiamano il primo e, mi preme dirlo, questa soluzione non mi piace proprio per niente.
Changed:
<
<
>
>
      - Adesso che conosci le differenze tra i membri della famiglia, dimmi: cosa pensi degli esempi che ti ho fatto prima delle spiegazioni?
    - Penso che fgrep avrebbe risolto il tuo problema più rapidamente di grep.
    - Perfetto! Vedo che stai attento e che capisci tutto quello che ti ho spiegato! Allora diamo un'occhiata a qualche altro esempio per rendere più chiare una volta per tutte le differenze d'uso tra i membri della famiglia.

Revision 428 Apr 2012 - AlbertoTaddei

Line: 1 to 1
 
META TOPICPARENT name="BatePapos"

Chiacchiere da Bar Parte II

Line: 12 to 12
     - grep? Non conosco nessuna parola del genere in inglese...
    - Certo, grep è l'acronimo di Global Regular Expression Print, che usa espressioni regolari per la ricerca di stringhe di caratteri in un input definito (c'è una leggenda sul perché questo comando ha quel nome: nell'editor di testi "ed", il nonno di "vim", il comando di ricerca usato era g/_espressione regolare_/p o, in inglese, g/_re_/p.). Dato che parliamo di espressioni regolari (o regexp), Aurélio Marinho Jargas dà tutte le indicazioni necessarie (tutorial inclusi) nella sua pagina web. Se vuoi imparare a programmare in Shell, Perl, Python, ... ti consiglio di leggerteli per non avere difficoltà più avanti.
Changed:
<
<

Io mi tengo grep, per te niente grappa

>
>

Io mi tengo grep, per te un groppo in gola

 
Changed:
<
<
Quello della grappa non è altro che uno scherzo! È solo un pretesto per ordinare qualche caipirinha. Tornando a bomba, poco fa ti ho detto che grep ricerca stringhe di caratteri in un input definito, ma che cos'è un "input definito"? Esistono diversi modi di definire l'input del comando grep. Vediamo:
>
>
Quello del groppo non è altro che uno scherzo! È solo un pretesto per ordinare qualche caipirinha. Tornando a bomba, poco fa ti ho detto che grep ricerca stringhe di caratteri in un input definito, ma che cos'è un "input definito"? Esistono diversi modi di definire l'input del comando grep. Vediamo:
  Ricerca all'interno di un file:

Revision 318 Apr 2012 - AlbertoTaddei

Line: 1 to 1
 
META TOPICPARENT name="BatePapos"

Chiacchiere da Bar Parte II

Line: 14 to 14
 

Io mi tengo grep, per te niente grappa

Changed:
<
<
Quello della grappa è solo uno scherzo! È un pretesto per ordinare qualche caipirinha. Tornando a bomba, poco fa ti ho detto che grep ricerca stringhe di caratteri in un input definito, ma che cos'è un "input definito"? Esistono diversi modi di definire l'input del comando grep. Vediamo:
>
>
Quello della grappa non è altro che uno scherzo! È solo un pretesto per ordinare qualche caipirinha. Tornando a bomba, poco fa ti ho detto che grep ricerca stringhe di caratteri in un input definito, ma che cos'è un "input definito"? Esistono diversi modi di definire l'input del comando grep. Vediamo:
  Ricerca all'interno di un file:
Line: 42 to 42
  Di certo mi chiederai a cosa servono l'accento circonflesso e gli apostrofi. Se tu avessi letto le indicazioni sulle espressioni regolari di cui ti ho parlato prima, sapresti che l'accento circonflesso serve a limitare la ricerca all'inizio di ogni riga, mentre gli apostrofi (') fanno in modo che la Shell non interpreti l'accento circonflesso così che questi attraversi incolume il comando grep.
Changed:
<
<
Guarda che forza! Il comando grep accetta come input l'output di un altro comando redirezionato da una pipe (questa cosa è molto comune nell'ambiente Shell e rende molto più rapida l'esecuzione di un comando: è come se l'output di un programma fosse salvato sul disco rigido e il secondo programma leggesse il file così generato). In questo modo, nel terzo esempio, il comando who ha generato l'elenco degli utenti "loggati" sulla tua stessa macchina (non dimenticarlo mai: Linux è multiutente) e grep è stato usato per verificare se Pelegrino lavorava o "si grattava".
>
>
Guarda che figata! Il comando grep accetta come input l'output di un altro comando redirezionato da una pipe (questa cosa è molto comune nell'ambiente Shell e rende molto più rapida l'esecuzione di un comando: è come se l'output di un programma fosse salvato sul disco rigido e il secondo programma leggesse il file così generato). In questo modo, nel terzo esempio, il comando who ha generato l'elenco degli utenti "loggati" sulla tua stessa macchina (non dimenticarlo mai: Linux è multiutente) e grep è stato usato per verificare se Pelegrino lavorava o "si grattava".
 

La famiglia grep

Line: 58 to 58
 
  • fgrep (la "f" sta per "fast", veloce, o per "file") è il più svelto della famiglia e, come dice il nome stesso, esegue il compito in modo molto rapido (a volte è circa il 30% più veloce di grep e il 50% più veloce di egrep), tuttavia non accetta come input le espressioni regolari nelle ricerche.

Pinguim com placa de atenção
Changed:
<
<
Tudo que foi dito acima sobre velocidade, só se aplica à família de comandos grep do Unix. No Linux o grep é sempre mais veloz, já que os outros dois (fgrep e egrep) são scripts em Shell que chamam o primeiro e, já vou adiantando, não gosto nem um pouquinho desta solução.
>
>
Quanto detto sulla velocità si applica soltanto alla famiglia di comandi grep di Unix. In Linux grep è sempre il più rapido visto che gli altri due (fgrep e egrep) sono scripts della Shell che richiamano il primo e, mi preme dirlo, questa soluzione non mi piace proprio per niente.
 
Changed:
<
<
    - Agora que você já conhece as diferenças entre os membros da família, me diga: o que você acha dos três exemplos que eu dei antes das explicações?
    - Eu achei que o fgrep resolveria o teu problema de forma mais veloz do que o grep.
    - Perfeito! Tô vendo que você está atento! Está entendendo tudo que estou te explicando! Então vamos ver mais exemplos para clarear de vez as diferenças de uso dos membros da família.
>
>
    - Adesso che conosci le differenze tra i membri della famiglia, dimmi: cosa pensi degli esempi che ti ho fatto prima delle spiegazioni?
    - Penso che fgrep avrebbe risolto il tuo problema più rapidamente di grep.
    - Perfetto! Vedo che stai attento e che capisci tutto quello che ti ho spiegato! Allora diamo un'occhiata a qualche altro esempio per rendere più chiare una volta per tutte le differenze d'uso tra i membri della famiglia.
 
Changed:
<
<
Exemplos
>
>
Esempi
 
Changed:
<
<
Eu sei que em um arquivo existe um texto falando sobre Linux só não tenho certeza se está escrito com L maiúsculo ou l minúsculo. Posso fazer de duas formas:
>
>
So che in un file c'è un testo che parla di=Linux= ma non sono sicuro se inizia con la L maiuscula o la l minuscula. Posso impostare la ricerca in due modi:
 
Changed:
<
<
$ egrep (Linux | linux) arquivo.txt
>
>
$ egrep (Linux | linux) file.txt
 

ou

Changed:
<
<
$ grep [Ll]inux arquivo.txt
>
>
$ grep [Ll]inux file.txt
 
Changed:
<
<
No primeiro caso, a expressão regular complexa "(Linux | linux)" usa os parênteses para agrupar as opções e a barra vertical (|) como um "ou" lógico, isto é, estou procurando Linux ou linux.
>
>
Nel primo caso, l'espressione regolare complessa "(Linux | linux)" fa uso delle parentesi per raggruppare le opzioni e della barra verticale (|) come di un "o" logico,cioè cerco Linux o linux.
 
Changed:
<
<
No segundo, a expressão regular [Ll]inux significa: começado por L ou l seguido de inux. Por esta expressão ser mais simples, o grep consegue resolvê-la, portanto acho melhor usar a segunda forma, já que o egrep tornaria a pesquisa mais lenta.
>
>
Nel secondo, l'espressione regolare [Ll]inux significa: inizia per L o l ed è seguito da inux. Poiché questa espressione è più semplice, grep riesce a risolverla, per cui ritengo migliore usare la seconda forma visto che egrep renderebbe la ricerca più lenta.
 
Changed:
<
<
Outro exemplo. Para listar todos os subdiretórios do diretório corrente, basta:
>
>
Un altro esempio. Per avere l'elenco delle sottodirectory della directory corrente è sufficiente digitare:
 
$ ls -l | grep '^d'
Line: 99 to 99
 drwxr-xr-x 3 root root 4096 Dec 18 2000 xine
Changed:
<
<
No exemplo que acabamos de ver, o circunflexo (^) serviu para limitar a pesquisa à primeira posição da saída do ls longo. Os apóstrofos foram colocados para o Shell não "ver" o circunflexo (^).
>
>
Nell'esempio appena visto, l'accento circonflesso (^) serve per limitare la ricerca alla prima posizione dell'output esteso di ls. Gli apostrofi sono stati messi affinché la Shell non "vedesse" l'accento circonflesso (^).
 
Changed:
<
<
Vamos ver mais um. Sabemos que as quatro primeiras posições possíveis de um ls -l de um arquivo comum (arquivo comum! Não é diretório, nem link, nem ...) devem ser:
>
>
Vediamo ancora un esempio. Sappiamo che le prime quattro posizioni possibili dell'output di ls -l per un file comune (un file comune, non una directory, un link o altro) devono essere:
 
Changed:
<
<
Posição  1ª   2ª   3ª   4ª 
 Valores Possíveis  - r w x
>
>
Posizione  1ª   2ª   3ª   4ª 
 Valori Possibili  - r w x
 
  - -   s (suid) 
      -
Changed:
<
<
Assim sendo, para descobrir todos os arquivos executáveis em um determinado diretório eu deveria fazer:
>
>
Per scoprire tutti i file eseguibili presenti in una determinata directory dovrei digitare:
 
$ ls -la | egrep '^-..(x|s)'
Line: 120 to 120
 -rwxr-xr-x 1 root root 18453 Jul 6 17:28 rc.sysinit
Changed:
<
<
Onde novamente usamos o circunflexo (^) para limitar a pesquisa ao início de cada linha, então as linhas listadas serão as que começam por um traço (-), seguido de qualquer coisa (o ponto quando usado como uma expressão regular significa qualquer coisa), novamente seguido de qualquer coisa, vindo a seguir um x ou um s.
>
>
Il comando utilizza nuovamente l'accento circonflesso (^) per limitare la ricerca all'inizio di ogni riga, quindi le righe elencate saranno quelle che iniziano con un trattino (-) seguito da qualsiasi cosa (nelle espressioni regolari il punto significa qualsiasi cosa), ancora seguito da qualsiasi cosa , poi da x o da s.
 
Changed:
<
<
Obteríamos o mesmo resultado se fizéssemos:
>
>
Otterremmo lo stesso risultato se digitassimo:
 
$ ls -la | grep '^-..[xs]'
Changed:
<
<
e agilizaríamos a pesquisa.
>
>
e avremmo reso la ricerca più veloce.
 
Changed:
<
<

Vamos Montar uma "cdteca"

>
>

Costruiamo una "cdteca"

 
Changed:
<
<
Vamos começar a desenvolver programas, acho que a montagem de um banco de dados de músicas é bacana para efeito didático (e útil nesses tempos de downloads de mp3 e "queimadores" de CDs). Não se esqueça que, da mesma forma que vamos desenvolver um monte de programas para organizar os seus CDs de música, com pequenas adaptações, você pode fazer o mesmo com os CDs de software que vêm com a Linux Magazine e outros que você compra ou queima, disponibilizando este banco de software para todos que trabalham com você (o Linux é multiusuário, e como tal deve ser explorado), desta forma ganhando muitos pontos com seu adorado chefe.
>
>
Iniziamo a scrivere qualche programma. Penso che costruire una banca dati musicale sia una figata per imparare (ed è anche utile in questi tempi di download di mp3 e "masterizzatori" di CD). Non dimenticare che, così come sviluppiamo dei programmi per catalogare i tuoi CD musicali, con piccoli adattamenti puoi fare la stessa cosa con i CD di software allegati a Linux Magazine e con tutti quelli che acquisti o masterizzi, rendendo disponibile questa banca dati a tutti quelli che lavorano con te (Linux è multiutente e così deve essere usato) e guadagnando dei punti nei confronti del tuo adorato capo.
 
Changed:
<
<
    - Péra ai! De onde eu vou receber os dados dos CDs?
    - Inicialmente, vou lhe mostrar como o seu programa pode receber parâmetros de quem o estiver executando e em breve, ensinarei a ler os dados pela tela ou de um arquivo.
>
>
    - Fermati un attimo! Da dove recupero i dati dei CD?
    - Per iniziare ti mostrerò come il programma può ottenere parametri da chi lo sta utilizzando e in breve ti insegnerò a leggere i dati dallo schermo o da un file.
 
Changed:
<
<

Passando parâmetros

>
>

Inserimento dei parametri

 
Changed:
<
<
O layout do arquivo musicas será o seguinte:
>
>
Il layout del file canzoni sarà il seguente:
 
Changed:
<
<
     nome do álbum^intérprete1~nome da música1:..:intérprete~nome da música
>
>
     titolo del disco^interprete1~titolo della canzone1:..:interpreten~titolo della canzonen
 
Changed:
<
<
isto é, o nome do álbum será separado por um circunflexo (^) do resto do registro, que é formado por diversos grupos compostos 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 internamente, o intérprete será separado por um til (~) do nome da música.
>
>
cioè il titolo del disco sarà separato con un accento circonflesso (^) dal resto del record che è formato da diversi gruppi composti dall'interprete di ogni canzone del CD e dalle rispettive canzoni. Questi gruppi sono separati dai due-punti (:) e, al loro interno, l'interprete sarà separato con una tilde (~) dal titolo della canzone.
 
Changed:
<
<
Eu quero escrever um programa que chamado musinc, que incluirá registros no meu arquivo musicas. Eu passarei o conteúdo de cada álbum como parâmetro na chamada do programa fazendo assim:
>
>
Voglio scrivere un programma chiamato insercanz che inserirà dei record nel file canzoni. Immetterò il contenuto di ogni disco come parametro nella chiamata del programma in questo modo:
 
Changed:
<
<
$ musinc "álbum^interprete~musica:interprete~musica:..."
>
>
$ insercanz "disco^interprete~canzone:interprete~canzone:..."
 
Changed:
<
<
Desta forma o programa musinc estará recebendo os dados de cada álbum como se fosse uma variável. A única diferença entre um parâmetro recebido e uma variável é que os primeiros recebem nomes numéricos (nome numérico fica muito esquisito, né? O que quis dizer é que seus nomes são formados por um e somente um algarismo), isto é $1, $2, $3, ..., $9. Vamos, antes de tudo, fazer um teste:
>
>
In questo modo il programma insercanz riceverà i dati di ogni disco come se fossero una variabile. L'unica differenza tra un parametro e una variabile è che i primi ricevono nomi numerici (nome numerico suona strano, vero? Significa che i nomi sono costituiti solo e soltanto da un numero), cioè $1, $2, $3, ..., $9. Prima di tutto facciamo una prova:
 
Changed:
<
<
Exemplos
>
>
Esempi
 
Changed:
<
<
$ cat teste
>
>
$ cat test
 #!/bin/bash
Changed:
<
<
# Programa para testar passagem de parametros
>
>
# Programma per testare l'immissione di parametri
 echo "1o. parm -> $1" echo "2o. parm -> $2" echo "3o. parm -> $3"
Changed:
<
<
Vamos executá-lo:
>
>
Proviamo a eseguirlo:
 
Changed:
<
<
$ teste passando parametros para testar bash: teste: cannot execute
>
>
$ test inserimento parametri per prova bash: test: cannot execute
 
Changed:
<
<
Ops! Esqueci-me de torná-lo executável. Vou fazê-lo de forma a permitir que todos possam executá-lo e em seguida vou testá-lo:
>
>
Ops! Ho dimenticato di renderlo eseguibile. Lo farò in modo che tutti possano eseguirlo e poi lo proverò:
 
Changed:
<
<
$ chmod 755 teste $ teste passando parametros para testar 1o. parm -> passando 2o. parm -> parametros 3o. parm -> para
>
>
$ chmod 755 test $ test inserimento parametri per prova 1o. parm -> inserimento 2o. parm -> parametri 3o. parm -> per
 
Changed:
<
<
Repare que a palavra testar, que seria o quarto parâmetro, não foi listada. Isto deu-se justamente porque o programa teste só listava os três primeiros parâmetros. Vamos executá-lo de outra forma:
>
>
Nota che la parola prova, cioè il quarto parametro, non è stata elencata. Ciò è accaduto perché il programma elenca soltanto i primi tre parametri. Proviamo a eseguirlo in un altro modo:
 
Changed:
<
<
$ teste "passando parametros" para testar 1o. parm -> passando parametros 2o. parm -> para 3o. parm -> testar
>
>
$ test "inserimento parametri" per prova 1o. parm -> inserimento parametri 2o. parm -> per 3o. parm -> prova
 
Changed:
<
<
As aspas não deixaram o Shell ver o espaço em branco entre as palavras e considerou-as um único parâmetro.
>
>
Le virgolette hanno impedito alla Shell di vedere lo spazio tra le parole le quali sono state considerate come un unico parametro.
 
Changed:
<
<

Macetes paramétricos

>
>

Gruppi parametrici

 
Changed:
<
<
Já que estamos falando em passagem de parâmetros deixa eu te dar mais umas dicas:
>
>
Dato che parliamo di inserimento di parametri, permettimi di darti qualche dritta:
 
Changed:
<
<
Significado das Principais Variáveis Referentes aos Parâmetros
$*   Contém o conjunto de todos os parâmetros (muito parecido com $@)  
  Variável     Significado  
$0   Contém o nome do programa  
$#   Contém a quantidade de parâmetros passados  
>
>
Significato delle Principali Variabili Riferite ai Parametri
$*   Contiene l'insieme di tutti i parametri (molto simile a $@)  
  Variabile     Significato  
$0   Contiene il nome del programma  
$#   Contiene il numero dei parametri immessi  
 
Changed:
<
<
Exemplos
>
>
Esempi
 
Changed:
<
<
Vamos alterar o programa teste para usar as variáveis que acabamos de ver. Vamos fazê-lo assim:
>
>
Modifichiamo il programma test per usare le variabili che abbiamo appena visto. Digitiamo:
 
Changed:
<
<
$ cat teste
>
>
$ cat test
 #!/bin/bash
Changed:
<
<
# Programa para testar passagem de parametros (2a. Versao) echo O programa $0 recebeu $# parametros
>
>
# Programma per testare l'immissione di parametri (2a. Versione) echo Il programma $0 ha ricevuto $# parametri
 echo "1o. parm -> $1" echo "2o. parm -> $2" echo "3o. parm -> $3"
Changed:
<
<
echo Todos de uma só \"tacada\": $*
>
>
echo Tutti in un solo \"colpo\": $*
 
Changed:
<
<
Repare que antes das aspas eu usei uma barra invertida para o escondê-las da interpretação do Shell (se não usasse as contrabarras as aspas não apareceriam). Vamos executá-lo:
>
>
Nota che prima delle virgolette ho usato una barra rovesciata per impedire alla Shell di interpretarla (se non usassi le barre rovesciate le virgolette non apparirebbero). Proviamo a eseguirlo:
 
Changed:
<
<
$ teste passando parametros para testar O programa teste recebeu 4 parametros 1o. parm -> passando 2o. parm -> parametros 3o. parm -> para Todos de uma só "tacada": passando parametros para testar
>
>
$ test inserimento parametri per prova Il programma test ha ricevuto 4 parametri 1o. parm -> inserimento 2o. parm -> parametri 3o. parm -> per Tutti in un solo "colpo": inserimento parametri per prova
 
Changed:
<
<
Conforme eu disse, os parâmetros recebem números de 1 a 9, mas isso não significa que não posso usar mais de 9 parâmetros significa somente que só posso endereçar 9. Vamos testar isso:
>
>
In base a quel che ti ho detto, i parametri ricevono un numero da 1 a 9: ciò non significa che non posso usare più di nove parametri, ma solo che posso indirizzarne al massimo nove. Vediamo:
 
Changed:
<
<
Exemplo:
>
>
Esempio:
 
Changed:
<
<
$ cat teste
>
>
$ cat test
 #!/bin/bash
Changed:
<
<
# Programa para testar passagem de parametros (3a. Versao) echo O programa $0 recebeu $# parametros
>
>
# Programma per testare l'immissione di parametri (3a. versione) echo Il programma $0 ha ricevuto $# parametri
 echo "11o. parm -> $11" shift echo "2o. parm -> $1"
Line: 247 to 247
 echo "4o. Parm -> $1"
Changed:
<
<
Vamos executá-lo:
>
>
Eseguiamolo:
 
Changed:
<
<
$ teste passando parametros para testar O programa teste recebeu 4 parametros que são: 11o. parm -> passando1 2o. parm -> parametros 4o. parm -> testar
>
>
$ test inserimento parametri per prova Il programma test ha ricevuto 4 parametri: 11o. parm -> inserimento1 2o. parm -> parametri 4o. parm -> prova
 
Changed:
<
<
Duas coisas muito interessantes neste script:
  1. Para mostrar que os nomes dos parâmetros variam de $1 a $9 eu fiz um echo $11 e o que aconteceu? O Shell interpretou como sendo $1 seguido do algarismo 1 e listou passando1;
  2. O comando shift cuja sintaxe é shift n, podendo o n assumir qualquer valor numérico (porém seu default é 1 como no exemplo dado), despreza os n primeiros parâmetros, tornando o parâmetro de ordem n+1, o primeiro ou seja, o $1.
>
>
In questo script ci sono due cose interessanti:
  1. Per far vedere che i nomi dei parametri variano da $1 a $9 ho eseguito un echo $11 e cos'è accaduto? La Shell lo ha interpretato come se fosse $1 seguito dal numero 1 e ha mostrato inserimento1;
  2. Il comando shift, la cui sintassi è shift n con n che può assumere un qualunque valore numerico (di default è 1 come nell'esempio), scarta i primi n parametri trasformando il parametro n+1 nel primo, cioè $1.
 
Changed:
<
<
Bem, agora que você já sabe mais sobre passagem de parâmetros do que eu, vamos voltar à nossa "cdteca" para fazer o script de inclusão de CDs no meu banco chamado musicas. O programa é muito simples (como tudo em Shell) e vou listá-lo para você ver:
>
>
Bene, ora che di immissione di parametri ne sai più di me, torniamo alla nostra "cdteca" per realizzare o script per inserire i CD nella mia banca dati chiamata canzoni. il programma è molto semplice (come, del resto, ogni cosa nella Shell) e li elencherò per farteli vedere:
 
Changed:
<
<
Exemplos
>
>
Esempi
 
Changed:
<
<
$ cat musinc
>
>
$ cat insercanz
 #!/bin/bash
Changed:
<
<
# Cadastra CDs (versao 1)
>
>
# Registra CD (versione 1)
 #
Changed:
<
<
echo $1 >> musicas
>
>
echo $1 >> canzoni
 
Changed:
<
<
O script é fácil e funcional, limito-me a anexar ao fim do arquivo musicas o parâmetro recebido. Vamos cadastrar 3 álbuns para ver se funciona (para não ficar "enchendo lingüiça", vou supor que em cada CD só existem 2 músicas):
>
>
Lo script è semplice e funzionale: mi limito ad aggiungere in coda al file canzoni il parametro ricevuto. Registriamo tre dischi per vedere se funziona (per non tirarla per le lunghe facciamo conto che ogni CD contenga solo due canzoni):
 
Changed:
<
<
$ musinc "album 3^Artista5~Musica5:Artista6~Musica5" $ musinc "album 1^Artista1~Musica1:Artista2~Musica2" $ musinc "album 2^Artista3~Musica3:Artista4~Musica4"
>
>
$ insercanz "disco 3^Artista5~Canzone5:Artista6~Canzone6" $ insercanz "disco 1^Artista1~Canzone1:Artista2~Canzone2" $ insercanz "disco 2^Artista3~Canzone3:Artista4~Canzone4"
 
Changed:
<
<
Listando o conteúdo de musicas.
>
>
Elenchiamo il contenuto di canzoni.
 
Changed:
<
<
$ cat musicas album 3^Artista5~Musica5:Artista6~Musica6 album 1^Artista1~Musica1:Artista2~Musica2 album 2^Artista3~Musica3:Artista4~Musica4
>
>
$ cat canzoni disco 3^Artista5~Canzone5:Artista6~Canzone6 disco 1^Artista1~Canzone1:Artista2~Canzone2 disco 2^Artista3~Canzone3:Artista4~Canzone4
 
Changed:
<
<
Não está funcional como achava que deveria ficar... podia ter ficado melhor. Os álbuns estão fora de ordem, dificultando a pesquisa. Vamos alterar nosso script e depois testá-lo novamente:
>
>
Non è funzionale come pensavo... avrebbe potuto venire meglio. I dischi non sono in ordine e ciò rende difficile la ricerca. Modifichiamo il nostro script e vediamo come funziona:
 
Changed:
<
<
$ cat musinc
>
>
$ cat insercanz
 #!/bin/bash
Changed:
<
<
# Cadastra CDs (versao 2)
>
>
# Registra CD (versione 2)
 #
Changed:
<
<
echo $1 >> musicas sort musicas -o musicas
>
>
echo $1 >> canzoni sort canzoni -o canzoni
 
Changed:
<
<
Vamos cadastrar mais um:
>
>
Registriamo ancora un CD:
 
Changed:
<
<
$ musinc "album 4^Artista7~Musica7:Artista8~Musica8"
>
>
$ insercanz "disco 4^Artista7~Canzone7:Artista8~Canzone8"
 
Changed:
<
<
Agora vamos ver o que aconteceu com o arquivo musicas:
>
>
Vediamo cosa succede al file canzoni:
 
Changed:
<
<
$ cat musicas album 1^Artista1~Musica1:Artista2~Musica2 album 2^Artista3~Musica3:Artista4~Musica4 album 3^Artista5~Musica5:Artista6~Musica5 album 4^Artista7~Musica7:Artista8~Musica8
>
>
$ cat canzoni disco 1^Artista1~Canzone1:Artista2~Canzone2 disco 2^Artista3~Canzone3:Artista4~Canzone4 disco 3^Artista5~Canzone5:Artista6~Canzone5 disco 4^Artista7~Canzone7:Artista8~Canzone8
 
Changed:
<
<
Simplesmente inseri uma linha que classifica o arquivo musicas dando a saída nele mesmo (para isso serve a opção -o), após cada álbum ser anexado.
>
>
Ho semplicemente inserito una riga che riordina il contenuto del file canzoni e redirige il risultato nel file stesso (a questo serve l'opzione -o) dopo l'inserimento di ogni disco.
 
Changed:
<
<
Oba! Agora está legal e quase funcional. Mas atenção, não se desespere! Esta não é a versão final. O programa ficará muito melhor e mais amigável, em uma nova versão que desenvolveremos após aprendermos a adquirir os dados da tela e formatar a entrada.
>
>
Evvai! Ora è davvero a posto e quasi funzionale. Ma stai attento, non disperare! Questa non è la versione finale. Il programma sarà migliore e più usabile nella nuova versione che scriveremo dopo aver capito come acquisire i dati dallo schermo e a formattare l'input.
 
Changed:
<
<
Exemplos
>
>
Esempi
 
Changed:
<
<
Ficar listando com o comando cat não está com nada, vamos então fazer um programa chamado muslist para listar um álbum cujo nome será passado como parâmetro:
>
>
Fare un elenco con il comando cat non va bene, perciò scriveremo un programma chiamato listcanz per ottenere l'elenco delle canzoni di un disco il cui titolo sarà immesso come parametro:
 
Changed:
<
<
$ cat muslist
>
>
$ cat listcanz
 #!/bin/bash
Changed:
<
<
# Consulta CDs (versao 1)
>
>
# Sfoglia CD (versione 1)
 #
Changed:
<
<
grep $1 musicas
>
>
grep $1 canzoni
 
Changed:
<
<
Vamos executá-lo, procurando pelo album 2. Como já vimos antes, para passar a cadeia album 2 é necessário protegê-la da interpretação do Shell, para que ele não a interprete como dois parâmetros. Vamos fazer assim:
>
>
Eseguiamolo cercando il disco 2. Come abbiamo visto prima, per inserire la stringa disco 2 è necessario fare in modo che la Shell non la interpreti come due parametri. Digitiamo:
 
Changed:
<
<
$ muslist "álbum 2"
>
>
$ listcanz "disco 2"
 grep: can't open 2
Changed:
<
<
musicas: album 1^Artista1~Musica1:Artista2~Musica2 musicas: album 2^Artista3~Musica3:Artista4~Musica4 musicas: album 3^Artista5~Musica5:Artista6~Musica6 musicas: album 4^Artista7~Musica7:Artista8~Musica8
>
>
canzoni: disco 1^Artista1~Canzone1:Artista2~Canzone2 canzoni: disco 2^Artista3~Canzone3:Artista4~Canzone4 canzoni: disco 3^Artista5~Canzone5:Artista6~Canzone6 canzoni: disco 4^Artista7~Canzone7:Artista8~Canzone8
 
Changed:
<
<
Que lambança! Onde está o erro? Eu tive o cuidado de colocar o parâmetro passado entre aspas, para o Shell não dividi-lo em dois!
>
>
Che schifezza! E l'errore dov'è? Mi sono anche assicurato di aver messo il parametro tra virgolette affinché la Shell non lo spezzasse in due!
 
Changed:
<
<
É, mas repare como está o grep executado:
>
>
Certo, ma guarda come viene eseguito grep:
 
Changed:
<
<
     grep $1 musicas
>
>
     grep $1 canzoni
 
Changed:
<
<
Mesmo colocando álbum 2 entre aspas, para que fosse encarado como um único parâmetro, quando o $1 foi passado pelo Shell para o comando grep, transformou-se em dois argumentos. Desta forma o conteúdo final da linha, que o comando grep executou foi o seguinte:
>
>
Anche mettendo disco 2 tra virgolette per farlo vedere come un unico parametro, quando $1 passa dalla Shell al comando grep si è ormai trasformato in due argomenti. In questo modo, il contenuto finale della riga che il comando grep ha eseguito è:
 
Changed:
<
<
     grep album 2 musicas
>
>
     grep disco 2 canzoni
 
Changed:
<
<
Como a sintaxe do grep é:
>
>
Poiché la sintassi di grep è:
 
Changed:
<
<
    =grep [arq1, arq2, ..., arqn]=
>
>
    =grep [file1, file2, ..., filen]=
 
Changed:
<
<
o grep entendeu que deveria procurar a cadeia de caracteres album nos arquivos 2 e musicas. Por não existir nenhum arquivo chamado 2 gerou o erro, e por encontrar a palavra album em todos os registros de musicas, listou a todos.
>
>
grep ha capito di dover cercare la stringa di caratteri disco nei file 2 e canzoni. Dato che non esiste alcun file chiamato 2, ha generato l'errore e, poiché ha trovato la parola disco in tutti i record di canzoni, li ha elencati tutti.
 
Changed:
<
<
Pinguim com placa de dica Sempre que a cadeia de caracteres a ser passada para o comando grep possuir brancos ou TAB, mesmo que dentro de variáveis, coloque-a sempre entre aspas para evitar que as palavras após o primeiro espaço em branco ou TAB sejam interpretadas como nomes de arquivos.
>
>
Pinguim com placa de dica (em inglês) Se la stringa di caratteri da passare al comando comando grep contiene spazi o TAB anche all'interno di variabili, mettila sempre tra virgolette per evitare che le parole dopo il primo spazio o TAB siano interpretate come nomi di file.
 
Changed:
<
<
Por outro lado, é melhor ignorarmos maiúsculas e minúsculas na pesquisa. Resolveríamos os dois problemas se o programa tivesse a seguinte forma:
>
>
D'altro canto, nella ricerca è meglio ingorare maiuscole e minuscole. Risolveremmo entrambi i problemi se il programma fosse così:
 
Changed:
<
<
$ cat muslist
>
>
$ cat listcanz
 #!/bin/bash
Changed:
<
<
# Consulta CDs (versao 2)
>
>
# Sfoglia CD (versione 2)
 #
Changed:
<
<
grep -i "$1" musicas
>
>
grep -i "$1" canzoni
 
Changed:
<
<
Neste caso, usamos a opção -i do grep, que como já vimos, serve para ignorar maiúsculas e minúsculas, e colocamos o $1 entre aspas, para que o grep continuasse a ver a cadeia de caracteres resultante da expansão da linha pelo Shell como um único argumento de pesquisa.
>
>
In questo caso, usiamo l'opzione -i di grep che, come già abbiamo visto, serve a ignorare maiuscole e minuscole, e abbiamo messo $1 tra virgolette affinché grep continuasse a vedere la stringa di caratteri risultante dall'espansione della riga effettuata dalla Shell come un unico argomento di ricerca.
 
Changed:
<
<
$ muslist "album 2" album2^Artista3~Musica3:Artista4~Musica4
>
>
$ listcanz "disco 2" disco2^Artista3~Canzone3:Artista4~Canzone4
 
Changed:
<
<
Agora repare que o grep localiza a cadeia pesquisada em qualquer lugar do registro, então da forma que estamos fazendo, podemos pesquisar por álbum, por música, por intérprete ou até por um pedaço de qualquer um destes. Quando conhecermos os comandos condicionais, montaremos uma nova versão de muslist que permitirá especificar por qual campo pesquisar.
>
>
Nota che grep localizza la stringa da cercare in qualunque parte del record, per cui possiamo fare ricerche per disco, canzone, interprete o anche per una parte di essi. Quando apprenderemo i comandi condizionali realizzeremo una nuova versione di listcanz che permetterà di specificare in quale campo fare la ricerca.
 
Changed:
<
<
Aí você vai me dizer:
>
>
A questo punto mi dirai:
 
Changed:
<
<
    - Poxa, mas é um saco ter que colocar o argumento de pesquisa entre aspas na hora de passar o nome do álbum. Esta forma não é nem um pouco amigável!
    - Tem razão, e por isso vou te mostrar uma outra forma de fazer o que você pediu:
>
>
    - Cavolo, ma è una vera noia dover mettere l'argomento della ricerca tra virgolette quando cerchiamo il titolo del disco. Non è una cosa simpatica!
    - Hai ragione, e proprio per questo ti farò vedere un altro modo di fare quello che chiedi:
 
Changed:
<
<
$ cat muslist
>
>
$ cat listcanz
 #!/bin/bash
Changed:
<
<
# Consulta CDs (versao 3)
>
>
# Sfoglia CD (versione 3)
 #
Changed:
<
<
grep -i "$*" musicas $ muslist album 2 album 2^Artista3~Musica3:Artista4~Musica4
>
>
grep -i "$*" canzoni $ listcanz disco 2 disco 2^Artista3~Canzone3:Artista4~Canzone4
 
Changed:
<
<
Desta forma, o $*, que significa todos os parâmetros, será substituído pela cadeia album 2 (de acordo com o exemplo anterior, fazendo o que você queria.
>
>
In questo modo, $*, che significa tutti i parametri, sarà sostituito dalla stringa disco 2 (vedi l'esempio precedente) proprio come volevi tu.
 
Changed:
<
<
Não se esqueça o problema do Shell não é se você pode ou não fazer uma determinada coisa. O problema é decidir qual é a melhor forma de fazê-la, já que para desempenhar qualquer tarefa, a quantidade de opções é enorme.
>
>
Non dimenticare che il problema della Shell non è se puoi o non puoi fare una certa cosa. Il problema è decidere qual'è il modo migliore di farla, visto che per svolgere un compito qualsiasi la quantità di opzioni è enorme.
 
Changed:
<
<
Ah! Em um dia de verão você foi à praia, esqueceu o CD no carro, aquele "solzinho" de 40 graus empenou o seu CD e agora você precisa de uma ferramenta para removê-lo do banco de dados? Não tem problema, vamos desenvolver um script chamado musexc, para excluir estes CDs.
>
>
Ah! Un bel giorno d'estate te ne sei andato in spiaggia, hai dimenticato il CD in macchina, il sole a 40 gradi ha rovinato il tuo CD e ora hai bisogno di uno strumento per rimuoverlo dalla banca dati? Nessun problema, buttiamo giù uno script chiamato elimcanz per cancellare il CD.
 
Changed:
<
<
Antes de desenvolver o "bacalho", quero te apresentar a uma opção bastante útil da família de comandos grep. É a opção -v, que quando usada lista todos os registros da entrada, exceto o(s) localizado(s) pelo comando. Vejamos:
>
>
Prima di farlo, voglio mostrarti un'opzione piuttosto utile della famiglia di comandi grep. È l'opzione -v, la quale elenca tutti i record dell'input, tranne quelli localizzati dal programma. Vediamo:
 
Changed:
<
<
Exemplos
>
>
Esempi
 
Changed:
<
<
$ grep -v "album 2" musicas album 1^Artista1~Musica1:Artista2~Musica2 album 3^Artista5~Musica5:Artista6~Musica6 album 4^Artista7~Musica7:Artista8~Musica8
>
>
$ grep -v "disco 2" canzoni disco 1^Artista1~Canzone1:Artista2~Canzone2 disco 3^Artista5~Canzone5:Artista6~Canzone6 disco 4^Artista7~Canzone:Artista8~Canzone8
 
Changed:
<
<
Conforme eu expliquei antes, o grep do exemplo listou todos os registros de musicas exceto o referente a album 2, porque atendia ao argumento do comando. Estamos então prontos para desenvolver o script para remover aquele CD empenado da sua "CDteca". Ele tem a seguinte cara:
>
>
Secondo quel che ti ho detto prima, il grep dell'esempio ha elencato tutti i record di canzoni tranne quelli relativi a disco 2 perché riguardava l'argomento del comando. Adesso siamo pronti a realizzare lo script per rimuovere il CD rovinato dalla tua "CDteca". Eccolo qua:
 
Changed:
<
<
$ cat musexc
>
>
$ cat elimcanz
 #!/bin/bash
Changed:
<
<
# Exclui CDs (versao 1)
>
>
# Elimina CD (versione 1)
 #
Changed:
<
<
grep -v "$1" musicas > /tmp/mus$$ mv -f /tmp/mus$$ musicas
>
>
grep -v "$1" canzoni > /tmp/canz$$ mv -f /tmp/canz$$ canzoni
 
Changed:
<
<
Na primeira linha mandei para /tmp/mus$$ o arquivo musicas, sem os registros que atendessem a consulta feita pelo comando grep. Em seguida, movi (que, no duro, equivale a renomear) /tmp/mus$$ por cima do antigo musicas.
>
>
Nella prima riga ho inviato in /tmp/canz$$ il file canzoni, senza i record relativi alla ricerca fatta dal comando grep. Poi ho spostato (cioè ho rinominato) /tmp/canz$$ sul vecchio canzoni.
 
Changed:
<
<
Usei o arquivo /tmp/mus$$ como arquivo de trabalho, porque como já havia citado no artigo anterior, o $$ contém o PID (Process Identification ou identificação do processo) e desta forma cada um que editar o arquivo musicas o fará em um arquivo de trabalho diferente, desta forma evitando colisões no uso.
>
>
Ho usato il file /tmp/canz$$ come file di lavoro perché, come ho detto nella prima parte, il $$ conttiene il PID (Process Identification o identificativo del processo) e in questo modo chiunque modifichi il file canzoni lo farà su un file diverso, evitando possibili collisioni nell'uso.
 
Changed:
<
<
    - Aê cara, estes programas que fizemos até aqui estão muito primários em virtude da falta de ferramentas que ainda temos. Mas é bom, enquanto eu tomo mais um chope, você ir para casa praticar em cima dos exemplos dados porque, eu prometo, chegaremos a desenvolver um sistema bacana para controle dos seus CDs.
    - Quando nos encontrarmos da próxima vez, vou te ensinar como funcionam os comandos condicionais e aprimoraremos mais um pouco estes scripts.
    - Por hoje chega! Já falei demais e preciso molhar a palavra porque estou de goela seca!
    - Garçom! Mais um sem colarinho!
>
>
    - Beh, i programmi che abbiamo scritto finora sono piuttosto rudimentali perché ci mancano alcuni strumenti. Ma va bene così. Ora, mentre io mi scolo un'altra birretta, tu te ne vai a casa a fare pratica con gli esempi perché in breve svilupperemo un bel programmino per tenere in ordine i tuoi CD.
    - Quando ci rivedremo ti insegnerò come funzionano i comandi condizionali e perfezioneremo quegli scripts.
    - Per oggi basta! Ho già chiacchierato troppo e ho bisogno di bagnarmi l'ugola, ho la gola secca!
    - Cameriere! Una birra alla spina senza schiuma!
  Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.

Revision 216 Apr 2012 - AlbertoTaddei

Line: 1 to 1
 
META TOPICPARENT name="BatePapos"

Chiacchiere da Bar Parte II

Changed:
<
<
    - Garçom! Traz um "chops" e dois "pastel". O meu amigo hoje não vai beber por que ele finalmente está sendo apresentado a um verdadeiro sistema operacional e ainda tem muita coisa a aprender!
    - E então, amigo, tá entendendo tudo que te expliquei até agora?
    - Entendendo eu tô, mas não vi nada prático nisso...
    - Calma rapaz, o que te falei até agora, serve como base ao que há de vir daqui pra frente. Vamos usar estas ferramentas que vimos para montar programas estruturados, que o Shell permite. Você verá porque até na TV já teve programa chamado "O Shell é o Limite".
    - Para começar vamos falar dos comandos da família grep.
    - grep? Não conheço nenhum termo em inglês com este nome...
    - É claro, grep é um acrônimo Global Regular Expression Print, que usa expressões regulares para pesquisar a ocorrência de cadeias de caracteres na entrada definida (se bem que há uma lenda sobre como este comando foi nomeado: no editor de textos "ed", o avô do "vim", o comando usado para buscas era g/_expressao regular_/p, ou no inglês g/_re_/p.). Por falar em expressões regulares (ou regexp), o Aurélio Marinho Jargas tem todas as dicas em sua página (inclusive tutorias) que abordam o tema. Se você está mesmo a fim de aprender a programar em Shell, Perl, Python, ... Acho bom você ler estes artigos para te ajudar no que está para vir.
>
>
    - Cameriere! Una birra alla spina e due "pasteis". Oggi il mio amico non beve perché finalmente farà la conoscenza di un vero sistema operativo e ha ancora tanto da imparare!
    - Allora, amico mio, hai capito tutto quello che ti ho spiegato finora?
    - Per capire ho capito, ma non ci vedo niente di pratico...
    - Calma, calma, quello di cui ti ho parlato finora è la base di ciò che arriverà dopo. Useremo questi strumenti per costruire programmi strutturati, cosa che la Shell permette di fare. Allora capirai perché in TV hanno trasmesso il programma "La Shell è il Limite".
    - Inizieremo parlando dei comandi della famiglia grep.
    - grep? Non conosco nessuna parola del genere in inglese...
    - Certo, grep è l'acronimo di Global Regular Expression Print, che usa espressioni regolari per la ricerca di stringhe di caratteri in un input definito (c'è una leggenda sul perché questo comando ha quel nome: nell'editor di testi "ed", il nonno di "vim", il comando di ricerca usato era g/_espressione regolare_/p o, in inglese, g/_re_/p.). Dato che parliamo di espressioni regolari (o regexp), Aurélio Marinho Jargas dà tutte le indicazioni necessarie (tutorial inclusi) nella sua pagina web. Se vuoi imparare a programmare in Shell, Perl, Python, ... ti consiglio di leggerteli per non avere difficoltà più avanti.
 
Changed:
<
<

Eu fico com o grep, você com a gripe

>
>

Io mi tengo grep, per te niente grappa

 
Changed:
<
<
Esse negócio de gripe é brincadeira! É só um pretexto para pedir umas caipirinhas. Mas voltando à vaca fria, eu te falei que o grep procura cadeia de caracteres dentro de uma entrada definida, mas o que vem a ser uma "entrada definida"? Bem, existem várias formas de definir a entrada do comando grep. Vejamos: Pesquisando em um arquivo:
>
>
Quello della grappa è solo uno scherzo! È un pretesto per ordinare qualche caipirinha. Tornando a bomba, poco fa ti ho detto che grep ricerca stringhe di caratteri in un input definito, ma che cos'è un "input definito"? Esistono diversi modi di definire l'input del comando grep. Vediamo:

Ricerca all'interno di un file:

 
$ grep rafael /etc/passwd
Changed:
<
<
Pesquisando em vários arquivos:
>
>
Ricerca all'interno di più file:
 
$ grep grep *.sh
Changed:
<
<
Pesquisando na saida de comando:
>
>
Ricerca nell'output di un comando:
 
$ who | grep Pelegrino
Changed:
<
<
No 1º exemplo, o mais simples, procurei a palavra rafael em qualquer lugar do arquivo /etc/passwd. Se quisesse procurá-la como um login name, isto é, somente no início dos registros deste arquivo, eu deveria fazer:
>
>
Nel primo esempio, il più semplice, ho cercato la parola rafael all'interno del file /etc/passwd. Se avessi voluto cercarla come un nome utente, cioè solo all'inizio dei registri del file, avrei dovuto digitare:
 
$ grep '^rafael' /etc/passwd
Changed:
<
<
E para que serve este circunflexo e os apóstrofos, você vai me perguntar. O circunflexo (^), se você tivesse lido os artigos anteriores sobre expressões regulares que te falei, saberia que servem para limitar a pesquisa ao início de cada linha, e os apóstrofos (') servem para o Shell não interpretar este circunflexo, deixando-o passar incólume para o comando grep.
>
>
Di certo mi chiederai a cosa servono l'accento circonflesso e gli apostrofi. Se tu avessi letto le indicazioni sulle espressioni regolari di cui ti ho parlato prima, sapresti che l'accento circonflesso serve a limitare la ricerca all'inizio di ogni riga, mentre gli apostrofi (') fanno in modo che la Shell non interpreti l'accento circonflesso così che questi attraversi incolume il comando grep.
 
Changed:
<
<
Olha que legal! O grep aceita como entrada, a saída de outro comando redirecionado por um pipe (isto é muito comum em Shell e é um tremendo acelerador de execução de comando já que atua como se a saída de um programa fosse guardada em disco e o segundo programa lesse este arquivo gerado), desta forma, no 3º exemplo, o comando who listou as pessoas "logadas" na mesma máquina que você (não se esqueça jamais: o Linux é multiusuário) e o grep foi usado para verificar se o Pelegrino estava trabalhando ou "coçando".
>
>
Guarda che forza! Il comando grep accetta come input l'output di un altro comando redirezionato da una pipe (questa cosa è molto comune nell'ambiente Shell e rende molto più rapida l'esecuzione di un comando: è come se l'output di un programma fosse salvato sul disco rigido e il secondo programma leggesse il file così generato). In questo modo, nel terzo esempio, il comando who ha generato l'elenco degli utenti "loggati" sulla tua stessa macchina (non dimenticarlo mai: Linux è multiutente) e grep è stato usato per verificare se Pelegrino lavorava o "si grattava".
 
Changed:
<
<

A família grep

>
>

La famiglia grep

 
Changed:
<
<
Este comando grep é muito conhecido, pois é usado com muita freqüência, o que muitas pessoas desconhecem é que existem três comandos na família grep, que são:
>
>
Il comando grep è molto conosciuto, per cui è anche usato spessissimo. Ciò che molti non sanno è che esistono tre comandi nella famiglia grep, ossia:
 
  • grep
  • egrep
  • fgrep
Changed:
<
<
A principais características diferenciais entre os 3 são:
  • O grep pode ou não usar expressões regulares simples, porém no caso de não usá-las, o fgrep é melhor, por ser mais rápido;
  • O egrep ("e" de extended, extendido) é muito poderoso no uso de expressões regulares. Por ser o mais lento da família, só deve ser usado quando for necessária a elaboração de uma expressão regular não aceita pelo grep;
  • O fgrep ("f" de fast, rápido, ou de "file", arquivo) como o nome diz é o rapidinho da família, executa o serviço de forma muito veloz (por vezes é cerca de 30% mais veloz que o grep e 50% mais que o egrep), porém não permite o uso de expressões regulares na pesquisa.
>
>
Le principali differenze fra i tre sono le seguenti:
  • grep accetta come input anche espressioni regolari, ma se non le usiamo è meglio affidarci a fgrep perché è più veloce;
  • egrep (la "e" sta per extended, esteso) è molto potente se si usano le espressioni regolari. Poiché è il più lento della famiglia, è meglio usarlo solo quando è necessario elaborare un'espressione regolare non accettata da grep;
  • fgrep (la "f" sta per "fast", veloce, o per "file") è il più svelto della famiglia e, come dice il nome stesso, esegue il compito in modo molto rapido (a volte è circa il 30% più veloce di grep e il 50% più veloce di egrep), tuttavia non accetta come input le espressioni regolari nelle ricerche.
 
Pinguim com placa de atenção Tudo que foi dito acima sobre velocidade, só se aplica à família de comandos grep do Unix. No Linux o grep é sempre mais veloz, já que os outros dois (fgrep e egrep) são scripts em Shell que chamam o primeiro e, já vou adiantando, não gosto nem um pouquinho desta solução.

Revision 109 Apr 2012 - AlbertoTaddei

Line: 1 to 1
Added:
>
>
META TOPICPARENT name="BatePapos"

Chiacchiere da Bar Parte II

    - Garçom! Traz um "chops" e dois "pastel". O meu amigo hoje não vai beber por que ele finalmente está sendo apresentado a um verdadeiro sistema operacional e ainda tem muita coisa a aprender!
    - E então, amigo, tá entendendo tudo que te expliquei até agora?
    - Entendendo eu tô, mas não vi nada prático nisso...
    - Calma rapaz, o que te falei até agora, serve como base ao que há de vir daqui pra frente. Vamos usar estas ferramentas que vimos para montar programas estruturados, que o Shell permite. Você verá porque até na TV já teve programa chamado "O Shell é o Limite".
    - Para começar vamos falar dos comandos da família grep.
    - grep? Não conheço nenhum termo em inglês com este nome...
    - É claro, grep é um acrônimo Global Regular Expression Print, que usa expressões regulares para pesquisar a ocorrência de cadeias de caracteres na entrada definida (se bem que há uma lenda sobre como este comando foi nomeado: no editor de textos "ed", o avô do "vim", o comando usado para buscas era g/_expressao regular_/p, ou no inglês g/_re_/p.). Por falar em expressões regulares (ou regexp), o Aurélio Marinho Jargas tem todas as dicas em sua página (inclusive tutorias) que abordam o tema. Se você está mesmo a fim de aprender a programar em Shell, Perl, Python, ... Acho bom você ler estes artigos para te ajudar no que está para vir.

Eu fico com o grep, você com a gripe

Esse negócio de gripe é brincadeira! É só um pretexto para pedir umas caipirinhas. Mas voltando à vaca fria, eu te falei que o grep procura cadeia de caracteres dentro de uma entrada definida, mas o que vem a ser uma "entrada definida"? Bem, existem várias formas de definir a entrada do comando grep. Vejamos: Pesquisando em um arquivo:

$ grep rafael /etc/passwd

Pesquisando em vários arquivos:

$ grep grep *.sh

Pesquisando na saida de comando:

$ who | grep Pelegrino

No 1º exemplo, o mais simples, procurei a palavra rafael em qualquer lugar do arquivo /etc/passwd. Se quisesse procurá-la como um login name, isto é, somente no início dos registros deste arquivo, eu deveria fazer:

$ grep '^rafael' /etc/passwd

E para que serve este circunflexo e os apóstrofos, você vai me perguntar. O circunflexo (^), se você tivesse lido os artigos anteriores sobre expressões regulares que te falei, saberia que servem para limitar a pesquisa ao início de cada linha, e os apóstrofos (') servem para o Shell não interpretar este circunflexo, deixando-o passar incólume para o comando grep.

Olha que legal! O grep aceita como entrada, a saída de outro comando redirecionado por um pipe (isto é muito comum em Shell e é um tremendo acelerador de execução de comando já que atua como se a saída de um programa fosse guardada em disco e o segundo programa lesse este arquivo gerado), desta forma, no 3º exemplo, o comando who listou as pessoas "logadas" na mesma máquina que você (não se esqueça jamais: o Linux é multiusuário) e o grep foi usado para verificar se o Pelegrino estava trabalhando ou "coçando".

A família grep

Este comando grep é muito conhecido, pois é usado com muita freqüência, o que muitas pessoas desconhecem é que existem três comandos na família grep, que são:

  • grep
  • egrep
  • fgrep

A principais características diferenciais entre os 3 são:

  • O grep pode ou não usar expressões regulares simples, porém no caso de não usá-las, o fgrep é melhor, por ser mais rápido;
  • O egrep ("e" de extended, extendido) é muito poderoso no uso de expressões regulares. Por ser o mais lento da família, só deve ser usado quando for necessária a elaboração de uma expressão regular não aceita pelo grep;
  • O fgrep ("f" de fast, rápido, ou de "file", arquivo) como o nome diz é o rapidinho da família, executa o serviço de forma muito veloz (por vezes é cerca de 30% mais veloz que o grep e 50% mais que o egrep), porém não permite o uso de expressões regulares na pesquisa.

Pinguim com placa de atenção Tudo que foi dito acima sobre velocidade, só se aplica à família de comandos grep do Unix. No Linux o grep é sempre mais veloz, já que os outros dois (fgrep e egrep) são scripts em Shell que chamam o primeiro e, já vou adiantando, não gosto nem um pouquinho desta solução.
    - Agora que você já conhece as diferenças entre os membros da família, me diga: o que você acha dos três exemplos que eu dei antes das explicações?
    - Eu achei que o fgrep resolveria o teu problema de forma mais veloz do que o grep.
    - Perfeito! Tô vendo que você está atento! Está entendendo tudo que estou te explicando! Então vamos ver mais exemplos para clarear de vez as diferenças de uso dos membros da família.

Exemplos

Eu sei que em um arquivo existe um texto falando sobre Linux só não tenho certeza se está escrito com L maiúsculo ou l minúsculo. Posso fazer de duas formas:

$ egrep (Linux | linux) arquivo.txt

ou

$ grep [Ll]inux arquivo.txt

No primeiro caso, a expressão regular complexa "(Linux | linux)" usa os parênteses para agrupar as opções e a barra vertical (|) como um "ou" lógico, isto é, estou procurando Linux ou linux.

No segundo, a expressão regular [Ll]inux significa: começado por L ou l seguido de inux. Por esta expressão ser mais simples, o grep consegue resolvê-la, portanto acho melhor usar a segunda forma, já que o egrep tornaria a pesquisa mais lenta.

Outro exemplo. Para listar todos os subdiretórios do diretório corrente, basta:

$ ls -l | grep '^d' drwxr-xr-x 3 root root 4096 Dec 18 2000 doc drwxr-xr-x 11 root root 4096 Jul 13 18:58 freeciv drwxr-xr-x 3 root root 4096 Oct 17 2000 gimp drwxr-xr-x 3 root root 4096 Aug 8 2000 gnome drwxr-xr-x 2 root root 4096 Aug 8 2000 idl drwxrwxr-x 14 root root 4096 Jul 13 18:58 locale drwxrwxr-x 12 root root 4096 Jan 14 2000 lyx drwxrwxr-x 3 root root 4096 Jan 17 2000 pixmaps drwxr-xr-x 3 root root 4096 Jul 2 20:30 scribus drwxrwxr-x 3 root root 4096 Jan 17 2000 sounds drwxr-xr-x 3 root root 4096 Dec 18 2000 xine

No exemplo que acabamos de ver, o circunflexo (^) serviu para limitar a pesquisa à primeira posição da saída do ls longo. Os apóstrofos foram colocados para o Shell não "ver" o circunflexo (^).

Vamos ver mais um. Sabemos que as quatro primeiras posições possíveis de um ls -l de um arquivo comum (arquivo comum! Não é diretório, nem link, nem ...) devem ser:

Posição  1ª   2ª   3ª   4ª 
      -
 Valores Possíveis  - r w x
  - -   s (suid) 

Assim sendo, para descobrir todos os arquivos executáveis em um determinado diretório eu deveria fazer:

$ ls -la | egrep '^-..(x|s)' -rwxr-xr-x 1 root root 2875 Jun 18 19:38 rc -rwxr-xr-x 1 root root 857 Aug 9 22:03 rc.local -rwxr-xr-x 1 root root 18453 Jul 6 17:28 rc.sysinit

Onde novamente usamos o circunflexo (^) para limitar a pesquisa ao início de cada linha, então as linhas listadas serão as que começam por um traço (-), seguido de qualquer coisa (o ponto quando usado como uma expressão regular significa qualquer coisa), novamente seguido de qualquer coisa, vindo a seguir um x ou um s.

Obteríamos o mesmo resultado se fizéssemos:

$ ls -la | grep '^-..[xs]'

e agilizaríamos a pesquisa.

Vamos Montar uma "cdteca"

Vamos começar a desenvolver programas, acho que a montagem de um banco de dados de músicas é bacana para efeito didático (e útil nesses tempos de downloads de mp3 e "queimadores" de CDs). Não se esqueça que, da mesma forma que vamos desenvolver um monte de programas para organizar os seus CDs de música, com pequenas adaptações, você pode fazer o mesmo com os CDs de software que vêm com a Linux Magazine e outros que você compra ou queima, disponibilizando este banco de software para todos que trabalham com você (o Linux é multiusuário, e como tal deve ser explorado), desta forma ganhando muitos pontos com seu adorado chefe.

    - Péra ai! De onde eu vou receber os dados dos CDs?
    - Inicialmente, vou lhe mostrar como o seu programa pode receber parâmetros de quem o estiver executando e em breve, ensinarei a ler os dados pela tela ou de um arquivo.

Passando parâmetros

O layout do arquivo musicas será o seguinte:

     nome do álbum^intérprete1~nome da música1:..:intérprete~nome da música

isto é, o nome do álbum será separado por um circunflexo (^) do resto do registro, que é formado por diversos grupos compostos 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 internamente, o intérprete será separado por um til (~) do nome da música.

Eu quero escrever um programa que chamado musinc, que incluirá registros no meu arquivo musicas. Eu passarei o conteúdo de cada álbum como parâmetro na chamada do programa fazendo assim:

$ musinc "álbum^interprete~musica:interprete~musica:..."

Desta forma o programa musinc estará recebendo os dados de cada álbum como se fosse uma variável. A única diferença entre um parâmetro recebido e uma variável é que os primeiros recebem nomes numéricos (nome numérico fica muito esquisito, né? O que quis dizer é que seus nomes são formados por um e somente um algarismo), isto é $1, $2, $3, ..., $9. Vamos, antes de tudo, fazer um teste:

Exemplos

$ cat teste #!/bin/bash # Programa para testar passagem de parametros echo "1o. parm -> $1" echo "2o. parm -> $2" echo "3o. parm -> $3"

Vamos executá-lo:

$ teste passando parametros para testar bash: teste: cannot execute

Ops! Esqueci-me de torná-lo executável. Vou fazê-lo de forma a permitir que todos possam executá-lo e em seguida vou testá-lo:

$ chmod 755 teste $ teste passando parametros para testar 1o. parm -> passando 2o. parm -> parametros 3o. parm -> para

Repare que a palavra testar, que seria o quarto parâmetro, não foi listada. Isto deu-se justamente porque o programa teste só listava os três primeiros parâmetros. Vamos executá-lo de outra forma:

$ teste "passando parametros" para testar 1o. parm -> passando parametros 2o. parm -> para 3o. parm -> testar

As aspas não deixaram o Shell ver o espaço em branco entre as palavras e considerou-as um único parâmetro.

Macetes paramétricos

Já que estamos falando em passagem de parâmetros deixa eu te dar mais umas dicas:

Significado das Principais Variáveis Referentes aos Parâmetros
$*   Contém o conjunto de todos os parâmetros (muito parecido com $@)  
  Variável     Significado  
$0   Contém o nome do programa  
$#   Contém a quantidade de parâmetros passados  

Exemplos

Vamos alterar o programa teste para usar as variáveis que acabamos de ver. Vamos fazê-lo assim:

$ cat teste #!/bin/bash # Programa para testar passagem de parametros (2a. Versao) echo O programa $0 recebeu $# parametros echo "1o. parm -> $1" echo "2o. parm -> $2" echo "3o. parm -> $3" echo Todos de uma só \"tacada\": $*

Repare que antes das aspas eu usei uma barra invertida para o escondê-las da interpretação do Shell (se não usasse as contrabarras as aspas não apareceriam). Vamos executá-lo:

$ teste passando parametros para testar O programa teste recebeu 4 parametros 1o. parm -> passando 2o. parm -> parametros 3o. parm -> para Todos de uma só "tacada": passando parametros para testar

Conforme eu disse, os parâmetros recebem números de 1 a 9, mas isso não significa que não posso usar mais de 9 parâmetros significa somente que só posso endereçar 9. Vamos testar isso:

Exemplo:

$ cat teste #!/bin/bash # Programa para testar passagem de parametros (3a. Versao) echo O programa $0 recebeu $# parametros echo "11o. parm -> $11" shift echo "2o. parm -> $1" shift 2 echo "4o. Parm -> $1"

Vamos executá-lo:

$ teste passando parametros para testar O programa teste recebeu 4 parametros que são: 11o. parm -> passando1 2o. parm -> parametros 4o. parm -> testar

Duas coisas muito interessantes neste script:

  1. Para mostrar que os nomes dos parâmetros variam de $1 a $9 eu fiz um echo $11 e o que aconteceu? O Shell interpretou como sendo $1 seguido do algarismo 1 e listou passando1;
  2. O comando shift cuja sintaxe é shift n, podendo o n assumir qualquer valor numérico (porém seu default é 1 como no exemplo dado), despreza os n primeiros parâmetros, tornando o parâmetro de ordem n+1, o primeiro ou seja, o $1.

Bem, agora que você já sabe mais sobre passagem de parâmetros do que eu, vamos voltar à nossa "cdteca" para fazer o script de inclusão de CDs no meu banco chamado musicas. O programa é muito simples (como tudo em Shell) e vou listá-lo para você ver:

Exemplos

$ cat musinc #!/bin/bash # Cadastra CDs (versao 1) # echo $1 >> musicas

O script é fácil e funcional, limito-me a anexar ao fim do arquivo musicas o parâmetro recebido. Vamos cadastrar 3 álbuns para ver se funciona (para não ficar "enchendo lingüiça", vou supor que em cada CD só existem 2 músicas):

$ musinc "album 3^Artista5~Musica5:Artista6~Musica5" $ musinc "album 1^Artista1~Musica1:Artista2~Musica2" $ musinc "album 2^Artista3~Musica3:Artista4~Musica4"

Listando o conteúdo de musicas.

$ cat musicas album 3^Artista5~Musica5:Artista6~Musica6 album 1^Artista1~Musica1:Artista2~Musica2 album 2^Artista3~Musica3:Artista4~Musica4

Não está funcional como achava que deveria ficar... podia ter ficado melhor. Os álbuns estão fora de ordem, dificultando a pesquisa. Vamos alterar nosso script e depois testá-lo novamente:

$ cat musinc #!/bin/bash # Cadastra CDs (versao 2) # echo $1 >> musicas sort musicas -o musicas

Vamos cadastrar mais um:

$ musinc "album 4^Artista7~Musica7:Artista8~Musica8"

Agora vamos ver o que aconteceu com o arquivo musicas:

$ cat musicas album 1^Artista1~Musica1:Artista2~Musica2 album 2^Artista3~Musica3:Artista4~Musica4 album 3^Artista5~Musica5:Artista6~Musica5 album 4^Artista7~Musica7:Artista8~Musica8

Simplesmente inseri uma linha que classifica o arquivo musicas dando a saída nele mesmo (para isso serve a opção -o), após cada álbum ser anexado.

Oba! Agora está legal e quase funcional. Mas atenção, não se desespere! Esta não é a versão final. O programa ficará muito melhor e mais amigável, em uma nova versão que desenvolveremos após aprendermos a adquirir os dados da tela e formatar a entrada.

Exemplos

Ficar listando com o comando cat não está com nada, vamos então fazer um programa chamado muslist para listar um álbum cujo nome será passado como parâmetro:

$ cat muslist #!/bin/bash # Consulta CDs (versao 1) # grep $1 musicas

Vamos executá-lo, procurando pelo album 2. Como já vimos antes, para passar a cadeia album 2 é necessário protegê-la da interpretação do Shell, para que ele não a interprete como dois parâmetros. Vamos fazer assim:

$ muslist "álbum 2" grep: can't open 2 musicas: album 1^Artista1~Musica1:Artista2~Musica2 musicas: album 2^Artista3~Musica3:Artista4~Musica4 musicas: album 3^Artista5~Musica5:Artista6~Musica6 musicas: album 4^Artista7~Musica7:Artista8~Musica8

Que lambança! Onde está o erro? Eu tive o cuidado de colocar o parâmetro passado entre aspas, para o Shell não dividi-lo em dois!

É, mas repare como está o grep executado:

     grep $1 musicas

Mesmo colocando álbum 2 entre aspas, para que fosse encarado como um único parâmetro, quando o $1 foi passado pelo Shell para o comando grep, transformou-se em dois argumentos. Desta forma o conteúdo final da linha, que o comando grep executou foi o seguinte:

     grep album 2 musicas

Como a sintaxe do grep é:

    =grep [arq1, arq2, ..., arqn]=

o grep entendeu que deveria procurar a cadeia de caracteres album nos arquivos 2 e musicas. Por não existir nenhum arquivo chamado 2 gerou o erro, e por encontrar a palavra album em todos os registros de musicas, listou a todos.

Pinguim com placa de dica Sempre que a cadeia de caracteres a ser passada para o comando grep possuir brancos ou TAB, mesmo que dentro de variáveis, coloque-a sempre entre aspas para evitar que as palavras após o primeiro espaço em branco ou TAB sejam interpretadas como nomes de arquivos.

Por outro lado, é melhor ignorarmos maiúsculas e minúsculas na pesquisa. Resolveríamos os dois problemas se o programa tivesse a seguinte forma:

$ cat muslist #!/bin/bash # Consulta CDs (versao 2) # grep -i "$1" musicas

Neste caso, usamos a opção -i do grep, que como já vimos, serve para ignorar maiúsculas e minúsculas, e colocamos o $1 entre aspas, para que o grep continuasse a ver a cadeia de caracteres resultante da expansão da linha pelo Shell como um único argumento de pesquisa.

$ muslist "album 2" album2^Artista3~Musica3:Artista4~Musica4

Agora repare que o grep localiza a cadeia pesquisada em qualquer lugar do registro, então da forma que estamos fazendo, podemos pesquisar por álbum, por música, por intérprete ou até por um pedaço de qualquer um destes. Quando conhecermos os comandos condicionais, montaremos uma nova versão de muslist que permitirá especificar por qual campo pesquisar.

Aí você vai me dizer:

    - Poxa, mas é um saco ter que colocar o argumento de pesquisa entre aspas na hora de passar o nome do álbum. Esta forma não é nem um pouco amigável!
    - Tem razão, e por isso vou te mostrar uma outra forma de fazer o que você pediu:

$ cat muslist #!/bin/bash # Consulta CDs (versao 3) # grep -i "$*" musicas $ muslist album 2 album 2^Artista3~Musica3:Artista4~Musica4

Desta forma, o $*, que significa todos os parâmetros, será substituído pela cadeia album 2 (de acordo com o exemplo anterior, fazendo o que você queria.

Não se esqueça o problema do Shell não é se você pode ou não fazer uma determinada coisa. O problema é decidir qual é a melhor forma de fazê-la, já que para desempenhar qualquer tarefa, a quantidade de opções é enorme.

Ah! Em um dia de verão você foi à praia, esqueceu o CD no carro, aquele "solzinho" de 40 graus empenou o seu CD e agora você precisa de uma ferramenta para removê-lo do banco de dados? Não tem problema, vamos desenvolver um script chamado musexc, para excluir estes CDs.

Antes de desenvolver o "bacalho", quero te apresentar a uma opção bastante útil da família de comandos grep. É a opção -v, que quando usada lista todos os registros da entrada, exceto o(s) localizado(s) pelo comando. Vejamos:

Exemplos

$ grep -v "album 2" musicas album 1^Artista1~Musica1:Artista2~Musica2 album 3^Artista5~Musica5:Artista6~Musica6 album 4^Artista7~Musica7:Artista8~Musica8

Conforme eu expliquei antes, o grep do exemplo listou todos os registros de musicas exceto o referente a album 2, porque atendia ao argumento do comando. Estamos então prontos para desenvolver o script para remover aquele CD empenado da sua "CDteca". Ele tem a seguinte cara:

$ cat musexc #!/bin/bash # Exclui CDs (versao 1) # grep -v "$1" musicas > /tmp/mus$$ mv -f /tmp/mus$$ musicas

Na primeira linha mandei para /tmp/mus$$ o arquivo musicas, sem os registros que atendessem a consulta feita pelo comando grep. Em seguida, movi (que, no duro, equivale a renomear) /tmp/mus$$ por cima do antigo musicas.

Usei o arquivo /tmp/mus$$ como arquivo de trabalho, porque como já havia citado no artigo anterior, o $$ contém o PID (Process Identification ou identificação do processo) e desta forma cada um que editar o arquivo musicas o fará em um arquivo de trabalho diferente, desta forma evitando colisões no uso.

    - Aê cara, estes programas que fizemos até aqui estão muito primários em virtude da falta de ferramentas que ainda temos. Mas é bom, enquanto eu tomo mais um chope, você ir para casa praticar em cima dos exemplos dados porque, eu prometo, chegaremos a desenvolver um sistema bacana para controle dos seus CDs.
    - Quando nos encontrarmos da próxima vez, vou te ensinar como funcionam os comandos condicionais e aprimoraremos mais um pouco estes scripts.
    - Por hoje chega! Já falei demais e preciso molhar a palavra porque estou de goela seca!
    - Garçom! Mais um sem colarinho!

Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.

Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para mim.

 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Wiki-SL? Send feedback