Difference between revisions of "Prova pratica 21 01 15"
Jump to navigation
Jump to search
(Created page with "<source lang="text"> Scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo. Questo file contiene due comandi con i rispettivi...") |
|||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
<source lang="text"> | <source lang="text"> | ||
− | + | Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo. | |
Questo file contiene due comandi con i rispettivi parametri, uno per riga. | Questo file contiene due comandi con i rispettivi parametri, uno per riga. | ||
Line 21: | Line 21: | ||
#include <s2argv.h> | #include <s2argv.h> | ||
#include <string.h> | #include <string.h> | ||
− | + | ||
int main(int argc, char *argv[]){ | int main(int argc, char *argv[]){ | ||
int pfd[2]; | int pfd[2]; | ||
Line 27: | Line 27: | ||
char cmd1[256]; | char cmd1[256]; | ||
char cmd2[256]; | char cmd2[256]; | ||
− | + | ||
fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1 | fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1 | ||
fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2 | fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2 | ||
− | + | ||
− | |||
− | |||
− | |||
pipe(pfd);//creo i 2 descrittori | pipe(pfd);//creo i 2 descrittori | ||
− | + | ||
switch(fork()){ | switch(fork()){ | ||
case 0: //figlio fornisce output | case 0: //figlio fornisce output | ||
Line 43: | Line 40: | ||
execsp(cmd1); | execsp(cmd1); | ||
exit(1); | exit(1); | ||
− | + | ||
case -1: exit(1); | case -1: exit(1); | ||
} | } | ||
Line 53: | Line 50: | ||
execsp(cmd2); | execsp(cmd2); | ||
exit(1); | exit(1); | ||
− | + | ||
case -1: exit(1); | case -1: exit(1); | ||
} | } | ||
int status; | int status; | ||
+ | close(pfd[0]); | ||
+ | close(pfd[1]); | ||
+ | wait(&status); | ||
wait(&status); | wait(&status); | ||
fclose(file); | fclose(file); | ||
} | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | <source lang="text"> | ||
+ | Es 2: Il secondo esercizio estende il primo. Il file passato come parametro in questo caso ha un numero arbitario di righe e non solo due come nell'esercizio1. | ||
+ | Ogni riga contiene un comando con I rispettivi parametri. Il programma deve attivare tutti I comandi del file in modo concorrente, e terminare quando tutti finiscono. | ||
+ | L'output di tutti I comandi, tranne l'ultimo, deve essere fornito in input all'ultimo comando | ||
+ | (quello nell'ultima riga significativa del file). | ||
+ | |||
+ | Es: se il file contenesse: | ||
+ | ls -l | ||
+ | ls -l | ||
+ | ls -l | ||
+ | cat | ||
+ | l'output dovrebbe essere la lista dei file della corrente directory 3 volte (nell'output puo' capitare che righe di comandi diversi vengano frapposte, l'accesso alla pipe e' conteso). | ||
+ | </source> | ||
+ | |||
+ | <source lang="c">#include <stdio.h> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <fcntl.h> | ||
+ | #include <s2argv.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | int main(int argc, char *argv[]){ | ||
+ | int pfd[2], num_righe=0, tmp=0; | ||
+ | FILE *file=fopen(argv[1], "r");//apro file in lettura | ||
+ | char buff[256]; | ||
+ | pipe(pfd); | ||
+ | |||
+ | while(fgets(buff, sizeof(buff), file)!=NULL){//calcolo il numero di righe del file | ||
+ | num_righe++; | ||
+ | } | ||
+ | char comandi[num_righe][256];//array di stringhe | ||
+ | rewind(file); | ||
+ | |||
+ | for(tmp=0; tmp<num_righe; tmp++){ | ||
+ | fgets(comandi[tmp], sizeof(comandi[tmp]), file);//copio ogni comando per riga | ||
+ | //printf("comando num %d: %s\n", tmp, comandi[tmp]); | ||
+ | switch(fork()){ | ||
+ | case 0: | ||
+ | if(tmp<num_righe-1){ | ||
+ | dup2(pfd[1], STDOUT_FILENO); | ||
+ | close(pfd[0]); | ||
+ | close(pfd[1]); | ||
+ | execsp(comandi[tmp]); | ||
+ | exit(1); | ||
+ | } | ||
+ | if(tmp==num_righe-1){ | ||
+ | dup2(pfd[0], STDIN_FILENO); | ||
+ | close(pfd[0]); | ||
+ | close(pfd[1]); | ||
+ | execsp(comandi[tmp]); | ||
+ | exit(1); | ||
+ | } | ||
+ | case -1: exit(1); | ||
+ | |||
+ | } | ||
+ | } | ||
+ | int status; | ||
+ | close(pfd[0]); | ||
+ | close(pfd[1]); | ||
+ | for(tmp=0; tmp<num_righe; tmp++) | ||
+ | wait(&status); | ||
+ | fclose(file); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | <source lang="text"> | ||
+ | Esercizio 3: Script bash o Python: | ||
+ | Scrivere un programma python o uno script bash che scandisca il sottoalbero relativo alle directory passate come parametri (o alla direcotry corrente se non ci sono parametri) e | ||
+ | fornisca in output l'elenco dei file che hanno la stessa somma MD5 (i.e. l'output del comando md5sum). | ||
+ | In output ogni riga deve mostrare un elenco di pathname realtivi a file che hanno la stessa somma MD5 (che quindi sono molto molto probabilmente uguali). | ||
+ | </source> | ||
+ | |||
+ | <source lang="bash"> | ||
+ | #! /bin/bash | ||
+ | trova () { | ||
+ | find $1 -type f -exec md5sum {} \; | sort > md5.txt #calcola l'md5 di tutto il sottoalbero, lo ordina e lo salva in un file | ||
+ | cat md5.txt | grep "`cut -d ' ' -f 1 md5.txt | uniq -d`" #stampa le righe del file, nelle quali in primo campo ha valore(md5) duplicato | ||
+ | } | ||
+ | |||
+ | if [[ $# -eq 0 ]] ; then #se num argomenti è 0 | ||
+ | trova | ||
+ | else | ||
+ | for parametro in $* #chiamo la funzione per ogni argomento | ||
+ | do | ||
+ | trova $parametro | ||
+ | done | ||
+ | fi | ||
+ | exit | ||
</source> | </source> |
Latest revision as of 12:32, 3 April 2015
Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo.
Questo file contiene due comandi con i rispettivi parametri, uno per riga.
Il programma deve mettere in esecuzione concorrente I due comandi in modo che l'output del primo venga fornito come input del secondo usando una pipe.
Il programma deve terminare quando entrambi i comandi sono terminati.
Esempio: se il file ffff contiene:
ls -l
tac
il comando:
filepipe ffff
deve restituire lo stesso output del comando:
ls -l | tac
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <s2argv.h>
#include <string.h>
int main(int argc, char *argv[]){
int pfd[2];
FILE *file=fopen(argv[1], "r");//apro file in lettura
char cmd1[256];
char cmd2[256];
fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1
fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2
pipe(pfd);//creo i 2 descrittori
switch(fork()){
case 0: //figlio fornisce output
dup2(pfd[1], STDOUT_FILENO);
close(pfd[0]);
close(pfd[1]);
execsp(cmd1);
exit(1);
case -1: exit(1);
}
switch(fork()){//figlio prende input
case 0:
dup2(pfd[0], STDIN_FILENO);
close(pfd[0]);
close(pfd[1]);
execsp(cmd2);
exit(1);
case -1: exit(1);
}
int status;
close(pfd[0]);
close(pfd[1]);
wait(&status);
wait(&status);
fclose(file);
}
Es 2: Il secondo esercizio estende il primo. Il file passato come parametro in questo caso ha un numero arbitario di righe e non solo due come nell'esercizio1.
Ogni riga contiene un comando con I rispettivi parametri. Il programma deve attivare tutti I comandi del file in modo concorrente, e terminare quando tutti finiscono.
L'output di tutti I comandi, tranne l'ultimo, deve essere fornito in input all'ultimo comando
(quello nell'ultima riga significativa del file).
Es: se il file contenesse:
ls -l
ls -l
ls -l
cat
l'output dovrebbe essere la lista dei file della corrente directory 3 volte (nell'output puo' capitare che righe di comandi diversi vengano frapposte, l'accesso alla pipe e' conteso).
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <s2argv.h>
#include <string.h>
int main(int argc, char *argv[]){
int pfd[2], num_righe=0, tmp=0;
FILE *file=fopen(argv[1], "r");//apro file in lettura
char buff[256];
pipe(pfd);
while(fgets(buff, sizeof(buff), file)!=NULL){//calcolo il numero di righe del file
num_righe++;
}
char comandi[num_righe][256];//array di stringhe
rewind(file);
for(tmp=0; tmp<num_righe; tmp++){
fgets(comandi[tmp], sizeof(comandi[tmp]), file);//copio ogni comando per riga
//printf("comando num %d: %s\n", tmp, comandi[tmp]);
switch(fork()){
case 0:
if(tmp<num_righe-1){
dup2(pfd[1], STDOUT_FILENO);
close(pfd[0]);
close(pfd[1]);
execsp(comandi[tmp]);
exit(1);
}
if(tmp==num_righe-1){
dup2(pfd[0], STDIN_FILENO);
close(pfd[0]);
close(pfd[1]);
execsp(comandi[tmp]);
exit(1);
}
case -1: exit(1);
}
}
int status;
close(pfd[0]);
close(pfd[1]);
for(tmp=0; tmp<num_righe; tmp++)
wait(&status);
fclose(file);
}
Esercizio 3: Script bash o Python:
Scrivere un programma python o uno script bash che scandisca il sottoalbero relativo alle directory passate come parametri (o alla direcotry corrente se non ci sono parametri) e
fornisca in output l'elenco dei file che hanno la stessa somma MD5 (i.e. l'output del comando md5sum).
In output ogni riga deve mostrare un elenco di pathname realtivi a file che hanno la stessa somma MD5 (che quindi sono molto molto probabilmente uguali).
#! /bin/bash
trova () {
find $1 -type f -exec md5sum {} \; | sort > md5.txt #calcola l'md5 di tutto il sottoalbero, lo ordina e lo salva in un file
cat md5.txt | grep "`cut -d ' ' -f 1 md5.txt | uniq -d`" #stampa le righe del file, nelle quali in primo campo ha valore(md5) duplicato
}
if [[ $# -eq 0 ]] ; then #se num argomenti è 0
trova
else
for parametro in $* #chiamo la funzione per ogni argomento
do
trova $parametro
done
fi
exit