Difference between revisions of "Esercizio 1 Prova Pratica 25-09-2014"
		
		
		
		
		
		Jump to navigation
		Jump to search
		
				
		
		
	
m (Migliorata formattazione e aggiunto esercizio 3 da altra pagina)  | 
				|||
| Line 1: | Line 1: | ||
| − | + | ==Esercizio 1==  | |
<source lang ="text">  | <source lang ="text">  | ||
Scrivere un programma che preso come parametro un file contenente un elenco di comandi (con I relativi parametri)  | Scrivere un programma che preso come parametro un file contenente un elenco di comandi (con I relativi parametri)  | ||
| Line 23: | Line 23: | ||
</source>  | </source>  | ||
| − | ==Soluzione di Stefano Zaniboni==  | + | ===Soluzione di Stefano Zaniboni===  | 
<source lang ="c">  | <source lang ="c">  | ||
#include <stdio.h>  | #include <stdio.h>  | ||
| Line 94: | Line 94: | ||
</source>  | </source>  | ||
| − | + | ==Esercizio 2==  | |
<source lang ="text">  | <source lang ="text">  | ||
Completare wta in modo che l'output di ogni comando venga salvato separatemente e solo l'output del processo terminato per  | Completare wta in modo che l'output di ogni comando venga salvato separatemente e solo l'output del processo terminato per  | ||
| Line 104: | Line 104: | ||
</source>  | </source>  | ||
| − | ==Soluzione di Maldus==  | + | ===Soluzione di Maldus===  | 
<source lang="c">  | <source lang="c">  | ||
#include <s2argv.h>  | #include <s2argv.h>  | ||
| Line 189: | Line 189: | ||
Per stampare solo l'output del processo vincente salvo quello di ciascun processo in un file di testo ( che poi cancello ). Mi viene però da pensare che debba esistere un modo migliore per farlo...  | Per stampare solo l'output del processo vincente salvo quello di ciascun processo in un file di testo ( che poi cancello ). Mi viene però da pensare che debba esistere un modo migliore per farlo...  | ||
| + | ==Esercizio 3==  | ||
| + | <source lang="text">  | ||
| + | Scrivere un programma python o uno scrip bash che faccia un backup storico di un file.  | ||
| + | backn file n  | ||
| + | deve mantenere n versioni del file specificato. n>2  | ||
| + | Esempio:  | ||
| + | backn miofile 10  | ||
| + | se esiste miofile.9 deve essere rinominato in miofile.10  | ||
| + | se esiste miofile 8 deve essere rinominato in miofile 9  | ||
| + | e cosi' via fino a miofile.2, rinominato miofile 3.  | ||
| + | ora se miofile.1 ha lo stesso contenuto di miofile.3, miofile diventa un link fisico a miofile.2  | ||
| + | miofile viene copiato in miofile.1  | ||
| + | </source>  | ||
| + | |||
| + | == Soluzione di Blissett ==  | ||
| + | <source lang="bash">  | ||
| + | #! /bin/bash  | ||
| + | |||
| + | if [[ $# != 2 || ! -f $1 ]]  | ||
| + | then   | ||
| + | 		echo "Usage: $0 file n_backup"  | ||
| + | 		exit -48  | ||
| + | fi  | ||
| + | |||
| + | file=$1  | ||
| + | n_backup=$2  | ||
| + | cartella="cartellaBackup"  | ||
| + | true=0   | ||
| + | |||
| + | if [[ ! -d $cartella ]]  | ||
| + | then  | ||
| + | 	mkdir $cartella  | ||
| + | fi  | ||
| + | cd ./$cartella  | ||
| + | |||
| + | for i in `find ./ -name "$file*" | sort -n -r -t. -k3 | cut -d. -f3`   | ||
| + | do  | ||
| + | 	true=1  | ||
| + | 	tmp=`find ./ -name "$file.$i"`  | ||
| + | 	num=$(($i+1))  | ||
| + | 	mv $tmp "$file.$num"  | ||
| + | 	if [[ $num -gt n_backup ]]  | ||
| + | 	then  | ||
| + | 		rm "$file.$num"  | ||
| + | 	fi  | ||
| + | done  | ||
| + | |||
| + | if [[ $true -eq 1 ]]  | ||
| + | then  | ||
| + | 	cmp -s "$file.2" "../$file"  | ||
| + | 	if [[ $? -eq 0 ]]  | ||
| + | 	then	  | ||
| + | 	echo creo link fisico.  | ||
| + | 		ln "$file.2" "$file.1"  | ||
| + | 	else  | ||
| + | 		cp ../$file ./  | ||
| + | 		mv $file "$file.1"  | ||
| + | 	fi  | ||
| + | else  | ||
| + | 		cp ../$file ./  | ||
| + | 		mv $file "$file.1"  | ||
| + | fi  | ||
| + | </source>  | ||
| + | --[[User:Blissett|Blissett]] ([[User talk:Blissett|talk]]) 13:14, 11 May 2015 (CEST)  | ||
| + | |||
| + | ==Soluzione di Maldus==  | ||
| + | <source lang="python">  | ||
| + | import argparse  | ||
| + | import sys  | ||
| + | import os  | ||
| + | import shutil  | ||
| + | import filecmp  | ||
| + | |||
| + | def olderVersion( new, old ):  | ||
| + |     new = new + '.'  | ||
| + |     l = len(new)  | ||
| + |     if new in old:  | ||
| + |         try:  | ||
| + |             num=int(old[l:])  | ||
| + |             if num < args.version and num!=1 : os.rename(old, old[:l]+str(num+1))  | ||
| + |         except ValueError:  | ||
| + |             return   | ||
| + | |||
| + | |||
| + | parser = argparse.ArgumentParser(description='backup storico')  | ||
| + | parser.add_argument('file', metavar='file', type=str, help='file di cui fare backup')  | ||
| + | parser.add_argument('version', metavar='versione', type=int, help='numero di versione')  | ||
| + | args = parser.parse_args()  | ||
| + | new = args.file   | ||
| + | |||
| + | if args.version < 2:  | ||
| + |     print("la versione deve essere > 2")  | ||
| + |     sys.exit(1)  | ||
| + | |||
| + | entries = [ x for x in os.listdir('.') if os.path.isfile(x)]  | ||
| + | if not new in entries:  | ||
| + |     print("Nessun file con quel nome")  | ||
| + |     sys.exit(1)  | ||
| + | |||
| + | for file in entries: olderVersion( new, file )  | ||
| + | |||
| + | if new+'.2' in entries:  | ||
| + |     if filecmp.cmp(new+'.3', new+'.1'): os.link(new, new+'.2')  | ||
| + |     else: os.rename(new+'.1', new+'.2')  | ||
| + | elif new+'.1' in entries: os.rename(new+'.1', new+'.2')  | ||
| + | |||
| + | shutil.copyfile(new, new+'.1')  | ||
| + | </source>  | ||
Latest revision as of 16:22, 6 May 2017
Esercizio 1
Scrivere un programma che preso come parametro un file contenente un elenco di comandi (con I relativi parametri)
 li attivi tutti in esecuzione concorrente e rimanga in attesa. Quando il primo termina, vengono terminati (con segnale SIGTERM) tutti gli altri. 
(consiglio: puo' essere utile usare la mia libreria s2argv-execs)
esempio:
wta commands
il file commands contiene:
      ./ttest 40
      ./ttest 10
      ./ttest 20
lo script ./ttest contiene:
      #!/bin/bash
      echo waiting for $1 seconds
      sleep $1
      echo done $i
l'ouptut sara':
      waiting for 40 seconds
      waiting for 10 seconds
      waiting for 20 seconds
      done 10
e poi basta perche' gli altri processi verranno terminati.
Soluzione di Stefano Zaniboni
#include <stdio.h>
#include <s2argv.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <error.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <poll.h>
int main(int argc, char *argv[]){
   FILE *stream;
   char *line=NULL;
   size_t len=0;
   ssize_t read;
   int i=0;
   int status;
   pid_t fineFirst; /*memorizzo il pid del primo processo terminato*/
   pid_t all[i];
   int pipefd[2];
   struct pollfd pipe_read_poll;
   if(argc!=2){
      fprintf(stderr,"Argomento Mancante!\n");
      exit(1);
   }
   stream=fopen(argv[1], "r");
   if(stream == NULL)
      exit(EXIT_FAILURE);
   /*aprire una pipe, dentro al while dove ho la fork fare poll che aspetta un carattere dalla pipe. Lo mando finito il while*/
   pipe(pipefd);
   pipe_read_poll.fd = pipefd[0];
   pipe_read_poll.events = POLLIN;
   while((read = getline(&line, &len, stream)) != -1) {
      if(fork()==0){
         i++;
         char **lines=s2argv(line, NULL);
         poll(&pipe_read_poll,1,-1);
         execvp(lines[0], lines);
         all[i]=getpid(); /**/
         s2argv_free(lines);
         perror("execvp fail!");
         exit(1);
      }
      else
         exit(2);
   }
   /*inviare carattere alla pipe*/
   char buf='g';
   write(pipefd[1], &buf, 1);
   fineFirst=wait(&status);
   /*kill the rest of process*/
   while(i > 0){
      if(all[i] != fineFirst){
         kill(all[i], SIGTERM);
      }
      --i;
   }
   fclose(stream);
   exit(0);
}
Esercizio 2
Completare wta in modo che l'output di ogni comando venga salvato separatemente e solo l'output del processo terminato per
primo venga mostrato. 
Nell'esempio di prima l'output dovra' essere:
waiting for 10 seconds
done 10
Soluzione di Maldus
#include <s2argv.h>
#include <poll.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
int main(int argc, char* argv[]){
        int i=0, status, out;
        FILE *fd, *output;
        pid_t *idents, winner;
        char *line=NULL, *string;
        size_t n=1;
        int pipefd[2];
        pipe(pipefd);
        struct pollfd pipepoll;
        pipepoll.fd = pipefd[0];
        pipepoll.events = POLLIN;
        if( !(fd = fopen(argv[1], "r"))){
                perror("fopen:");
                exit(1);
        }
        while( getline(&line, &n, fd) > 0){
                i++;
                free(line);
                line=NULL;
        }
        idents = malloc(sizeof(pid_t)*i);
        rewind(fd);
        i = 0;
        while( getline(&line, &n, fd) >0 ){
                switch( idents[i]=fork()){
                        case 0:
                                asprintf( &string, "out%i" ,getpid());
                                if( (out=open(string, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR)) <0){
                                        perror("open");
                                        exit(1);
                                }
                                free(string);
                                dup2(out, 1);
                                close(out);
                                poll(&pipepoll, 1, -1);
                                execsp(line);
                                exit(0);
                        default:
                                free(line);
                                line=NULL;
                                i++;
                                break;
                }
        }
        write(pipefd[1], "g", 1);
        winner = wait(&status);
        i--;
        for( ; i >= 0 ; i--){
                if(idents[i]!=winner){
                        kill(idents[i], SIGTERM);
                        asprintf( &string, "out%i", idents[i]);
                        unlink(string);
                        free(string);
                }
        }
        asprintf( &string, "out%i" , winner);
        if( !(output = fopen(string, "r"))){
                perror("fopen");
                exit(1);
        }
        while( getline(&line, &n, output)>0){
                printf("%s", line);
                free(line);
                line=NULL;
        }
        unlink(string);
        fclose(fd);
        fclose(output);
        return 0 ;
}
Per stampare solo l'output del processo vincente salvo quello di ciascun processo in un file di testo ( che poi cancello ). Mi viene però da pensare che debba esistere un modo migliore per farlo...
Esercizio 3
Scrivere un programma python o uno scrip bash che faccia un backup storico di un file.
backn file n
deve mantenere n versioni del file specificato. n>2
Esempio:
backn miofile 10
se esiste miofile.9 deve essere rinominato in miofile.10
se esiste miofile 8 deve essere rinominato in miofile 9
e cosi' via fino a miofile.2, rinominato miofile 3.
ora se miofile.1 ha lo stesso contenuto di miofile.3, miofile diventa un link fisico a miofile.2
miofile viene copiato in miofile.1
Soluzione di Blissett
#! /bin/bash
if [[ $# != 2 || ! -f $1 ]]
then 
		echo "Usage: $0 file n_backup"
		exit -48
fi
file=$1
n_backup=$2
cartella="cartellaBackup"
true=0 
if [[ ! -d $cartella ]]
then
	mkdir $cartella
fi
cd ./$cartella
for i in `find ./ -name "$file*" | sort -n -r -t. -k3 | cut -d. -f3` 
do
	true=1
	tmp=`find ./ -name "$file.$i"`
	num=$(($i+1))
	mv $tmp "$file.$num"
	if [[ $num -gt n_backup ]]
	then
		rm "$file.$num"
	fi
done
if [[ $true -eq 1 ]]
then
	cmp -s "$file.2" "../$file"
	if [[ $? -eq 0 ]]
	then	
	echo creo link fisico.
		ln "$file.2" "$file.1"
	else
		cp ../$file ./
		mv $file "$file.1"
	fi
else
		cp ../$file ./
		mv $file "$file.1"
fi
--Blissett (talk) 13:14, 11 May 2015 (CEST)
Soluzione di Maldus
import argparse
import sys
import os
import shutil
import filecmp
def olderVersion( new, old ):
    new = new + '.'
    l = len(new)
    if new in old:
        try:
            num=int(old[l:])
            if num < args.version and num!=1 : os.rename(old, old[:l]+str(num+1))
        except ValueError:
            return 
parser = argparse.ArgumentParser(description='backup storico')
parser.add_argument('file', metavar='file', type=str, help='file di cui fare backup')
parser.add_argument('version', metavar='versione', type=int, help='numero di versione')
args = parser.parse_args()
new = args.file 
if args.version < 2:
    print("la versione deve essere > 2")
    sys.exit(1)
entries = [ x for x in os.listdir('.') if os.path.isfile(x)]
if not new in entries:
    print("Nessun file con quel nome")
    sys.exit(1)
for file in entries: olderVersion( new, file )
if new+'.2' in entries:
    if filecmp.cmp(new+'.3', new+'.1'): os.link(new, new+'.2')
    else: os.rename(new+'.1', new+'.2')
elif new+'.1' in entries: os.rename(new+'.1', new+'.2')
shutil.copyfile(new, new+'.1')