<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://so.v2.cs.unibo.it/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Amonaldini</id>
	<title>Sistemi Operativi - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://so.v2.cs.unibo.it/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Amonaldini"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php/Special:Contributions/Amonaldini"/>
	<updated>2026-05-05T04:26:19Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=366</id>
		<title>SYS CALL viste a lezione.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=366"/>
		<updated>2013-11-27T18:56:41Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: /* LSEEK/READ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Controllo processi==&lt;br /&gt;
===FORK===&lt;br /&gt;
Crea un nuovo processo duplicando il processo chiamante. Il nuovo processo , chiamato figlio, é un duplicato esatto del processo chiamante , chiamato padre. &lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){     &lt;br /&gt;
	if(fork()){&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() ); // getpid() stampa il pid del processo corrente , getppid() stampa il pid del processo padre&lt;br /&gt;
        sleep(2);}   //se togliessimo lo sleep;il processo figlio stamperebbe come getppid() 1,perché essendo il padre terminato e lui rimasto orfano,il nuovo padre diventa init&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2(una piccola osservazione sull'eredità del buffer):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	printf(&amp;quot;cucù! : &amp;quot;);      //notare la differenza se nella sringa metto \n &lt;br /&gt;
	if(fork())&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() );&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio3(fork e malloc):&amp;lt;br/&amp;gt;&lt;br /&gt;
'''(sottolineerei che lo spazio di indirizzamento è di fatto separato: i due processi hanno una analoga visione dell'indirizzamento logico, che però è specifico di ogni processo e i dati sono memorizzati fisicamente in aree di memoria diverse. am_20131110)'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	int *p;&lt;br /&gt;
	if( fork() ){&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	*p = 45;&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());   &lt;br /&gt;
	sleep(2);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());  //i puntatori restituiranno lo stesso indirizzo di memoria sia per il padre che per il figlio         &lt;br /&gt;
	sleep(1);                                                           //perché condividono lo stesso spazio di indirizzamento&lt;br /&gt;
	}&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===_EXIT===&lt;br /&gt;
Termina il proceso chiamante.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc,char *argv[]){&lt;br /&gt;
	_exit(0);                     //Sys call che termina il processo chiamante&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2(atexit):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void at1(void){&lt;br /&gt;
	printf(&amp;quot;at1 \n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
void at2(void){&lt;br /&gt;
	printf(&amp;quot;at2 \n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main (int argc,char *argv[]){&lt;br /&gt;
	printf(&amp;quot;brutal kill \n&amp;quot;);&lt;br /&gt;
	atexit(at1);	//funzione di libreria che termina il processo passato come argomento&lt;br /&gt;
	atexit(at2); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//le funzioni passate ad atexit vengono eseguite in modo inverso rispetto all'invocazione&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===WAIT===&lt;br /&gt;
Aspetta che un processo cambi di stato.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
                sleep(10); &lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;,WEXITSTATUS(status)); //Macro che restituisce l' exit status del figlio,cioè gli otto bit meno significativi dello status che il figlio&lt;br /&gt;
	}                                                         //specifica in una chiamata di _exit o exit o come argomento di ritorno del main.&lt;br /&gt;
	else {&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		exit(1);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) //Macro che restituisce true se il figlio termina normalmente, cioé chiamando _exit o exit oppure tramite il return del main&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if(WIFSIGNALED(status) )  //Macro che restituisce true se il figlio é terminato da un segnale&lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) );  //Macro che restituisce il numero del segnale che causa la terminazione del processo figlio&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		int *p;&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		p = (int *)42;&lt;br /&gt;
		*p = 43;	&lt;br /&gt;
		exit(2);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===EXEC===&lt;br /&gt;
Esegue un programma.&lt;br /&gt;
La famiglia di funzioni exec() rimpiazza l'immagine del processo corrente con l'immagine di un nuovo processo.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) &lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if( WIFSIGNALED(status) )  &lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) ); &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		char *args[] = {&amp;quot;ls&amp;quot;,&amp;quot;-l&amp;quot;,(char *)0};&lt;br /&gt;
		execvp(&amp;quot;ls&amp;quot;,args); //funzione di libreria che prende in input il path(p) e un vettore(v).&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d %s \n&amp;quot;,getpid(),pid,argv[1]);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) &lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if( WIFSIGNALED(status) )  &lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) ); &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		execvp(argv[2],argv+2);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Gestione File==&lt;br /&gt;
* int open(const char *path, int oflag, ...);&amp;lt;br/&amp;gt;&lt;br /&gt;
* int creat(const char *path, mode_t mode);&lt;br /&gt;
* int close(int filedes);&lt;br /&gt;
* off_t lseek(int filedes, off_t offset, int whence);&lt;br /&gt;
* ssize_t read(int filedes, void *buf, size_t nbyte);&lt;br /&gt;
* ssize_t write(int filedes, const void *buf, size_t nbyte);&lt;br /&gt;
&lt;br /&gt;
Qualche esempio? Iniziamo con i file &amp;quot;con il buco&amp;quot; visti a lezione?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===OPEN/WRITE/CLOSE===&lt;br /&gt;
&lt;br /&gt;
*Open: apre e possibilmente crea un file o un device.&lt;br /&gt;
*Write: scrive su il file descriptor.&lt;br /&gt;
*Close: chiude il file descriptor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main ( int argc , char *argv[] ){&lt;br /&gt;
	int fd = open( argv[1] , O_RDWR | O_CREAT | O_TRUNC ,0666); &lt;br /&gt;
	write( fd , argv[2] , strlen( argv[2] ) );&lt;br /&gt;
	close( fd);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===LSEEK/READ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Lseek: sposta l'offset del file descriptor.&lt;br /&gt;
*Read: legge da un file descriptor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esempio1(sparse file o file ciambella):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main ( int argc , char *argv[] ){&lt;br /&gt;
	int fd = open( argv[1] , O_RDWR | O_CREAT | O_TRUNC ,0666); &lt;br /&gt;
	write( fd , argv[2] , strlen( argv[2] ) );&lt;br /&gt;
	lseek( fd, 1000000 , SEEK_SET );&lt;br /&gt;
	write( fd , argv[2] , strlen( argv[2] ) );&lt;br /&gt;
	close( fd);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esempio2(copia di un file):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BUFFSIZE 1024&lt;br /&gt;
&lt;br /&gt;
char buff[BUFFSIZE];		&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
int main ( int argc , char *argv[] ){&lt;br /&gt;
	int fin = open( argv[1] , O_RDONLY );&lt;br /&gt;
	int fout = open( argv[2] , O_RDWR | O_CREAT | O_TRUNC ,0666); &lt;br /&gt;
	ssize_t n;&lt;br /&gt;
	while( ( n = read( fin , buff , BUFFSIZE ) ) != 0 ){&lt;br /&gt;
		write( fout , buff , n );&lt;br /&gt;
	}&lt;br /&gt;
	close( fin);&lt;br /&gt;
	close( fout);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esempio3(copia di uno sparse file):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BUFFSIZE 1024             //la copia avviene per blocchi di 1024B&lt;br /&gt;
&lt;br /&gt;
char buff[BUFFSIZE];&lt;br /&gt;
&lt;br /&gt;
int isEmpty( char *s , int l ){&lt;br /&gt;
	int i;&lt;br /&gt;
	for( i = 0 ; i &amp;lt; l ; i++ )&lt;br /&gt;
		if( s[i] != 0 ) return (0);&lt;br /&gt;
	return(1);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# if 0&lt;br /&gt;
	for ( i = 0 ; ( i &amp;lt; l ) &amp;amp;&amp;amp; ( s[i] != 0 ) ; i++ )&lt;br /&gt;
		;&lt;br /&gt;
	return ( i == l );             //codice più compatto &lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	for( i = 0 ; i &amp;lt; l ; i++ )&lt;br /&gt;
		if( s[i] != 0 ) goto nonempty;&lt;br /&gt;
	return1;&lt;br /&gt;
nonempty:&lt;br /&gt;
	return0;                        //in stile kernel &lt;br /&gt;
#endif&lt;br /&gt;
}		&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
int main ( int argc , char *argv[] ){&lt;br /&gt;
	int fin = open( argv[1] , O_RDONLY );&lt;br /&gt;
	int fout = open( argv[2] , O_RDWR | O_CREAT | O_TRUNC ,0666); &lt;br /&gt;
	ssize_t n;&lt;br /&gt;
	while( ( n = read( fin , buff , BUFFSIZE ) ) != 0 ){&lt;br /&gt;
		if (isEmpty( buff , n ) )                       //il codice in questo esempio é ottimizzato per gli sparse file.&lt;br /&gt;
			lseek( fout , n , SEEK_CUR );&lt;br /&gt;
		else&lt;br /&gt;
		write( fout , buff , n );&lt;br /&gt;
	}&lt;br /&gt;
	close( fin);&lt;br /&gt;
	close( fout);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esempio4(Buffer ed efficienza):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*eseguire lo script di cui sotto in modo da osservare come il buffer modifichi l'efficienza della copia per blocchi di byte&lt;br /&gt;
&lt;br /&gt;
dd if=/dev/urandom  of=casual  bs=1024  count=102400&lt;br /&gt;
for size in 128 256 512 1024 2048 4096&lt;br /&gt;
do &lt;br /&gt;
time ./eseguibile casual ricasual $size&lt;br /&gt;
done&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int isEmpty( char *s , int l ){&lt;br /&gt;
	int i;&lt;br /&gt;
	for( i = 0 ; i &amp;lt; l ; i++ )&lt;br /&gt;
		if( s[i] != 0 ) return (0);&lt;br /&gt;
	return(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
int main ( int argc , char *argv[] ){&lt;br /&gt;
	int fin = open( argv[1] , O_RDONLY );&lt;br /&gt;
	int fout = open( argv[2] , O_RDWR | O_CREAT | O_TRUNC ,0666); &lt;br /&gt;
	int buffsize = atoi( argv[3] );&lt;br /&gt;
	char buff[buffsize];&lt;br /&gt;
	ssize_t n;&lt;br /&gt;
	while( ( n = read( fin , buff , buffsize ) ) != 0 ){&lt;br /&gt;
		if (isEmpty( buff , n ) )&lt;br /&gt;
			lseek( fout , n , SEEK_CUR );&lt;br /&gt;
		else&lt;br /&gt;
		write( fout , buff , n );&lt;br /&gt;
	}&lt;br /&gt;
	close( fin);&lt;br /&gt;
	close( fout);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TRUNCATE===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Truncate: tronca il file a una specifica lunghezza.&lt;br /&gt;
&lt;br /&gt;
Esempio(viene usata per creare File Buco Nero):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( int argc , char *argv[] ) {&lt;br /&gt;
	int fd = open( argv[1] , O_WRONLY | O_CREAT | O_TRUNC , 0666 );&lt;br /&gt;
	ftruncate( fd , atoi( argv[2] ) );&lt;br /&gt;
	close( fd );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===DUP===&lt;br /&gt;
&lt;br /&gt;
*Dup: duplica il file descriptor.&lt;br /&gt;
&lt;br /&gt;
Esempio:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( int argc , char *argv[]){&lt;br /&gt;
	int fd = open( argv[1] , O_WRONLY | O_CREAT | O_TRUNC , 0666 );&lt;br /&gt;
	close(1);&lt;br /&gt;
	dup(fd);   //dup2(fd,1) produce lo stesso effetto&lt;br /&gt;
	printf(&amp;quot;Hello World \n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===FUNZIONI SULLE DIRECTORY===&lt;br /&gt;
&lt;br /&gt;
Esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int mystrcmp( const void *a , const void *b ){&lt;br /&gt;
	char **pa = (char **)a;&lt;br /&gt;
	char **pb = (char **)b;&lt;br /&gt;
	return strcmp( *pa , *pb );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
int main ( int argc , char *argv[] ){&lt;br /&gt;
	DIR *d;&lt;br /&gt;
	struct dirent *de;&lt;br /&gt;
	char **names;&lt;br /&gt;
	int i , count = 0;&lt;br /&gt;
	d = opendir( argv[1] );     &lt;br /&gt;
	while( ( de = readdir(d) ) != NULL )&lt;br /&gt;
		count++;&lt;br /&gt;
	rewinddir(d);&lt;br /&gt;
	names = (char **)calloc( count , sizeof(char *) );&lt;br /&gt;
	count=0;&lt;br /&gt;
	while( ( de = readdir(d) ) != NULL )&lt;br /&gt;
		names[count++] = strdup( de-&amp;gt;d_name );&lt;br /&gt;
	closedir(d);&lt;br /&gt;
	qsort( names , count , sizeof(char *) , mystrcmp );&lt;br /&gt;
	for( i = 0 ; i &amp;lt; count ; i++ )&lt;br /&gt;
		printf(&amp;quot; %s &amp;quot;, names[i] );&lt;br /&gt;
	printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
#include&amp;lt;dirent.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main( int argc , char *argv[] ){&lt;br /&gt;
	int count;&lt;br /&gt;
	int i;&lt;br /&gt;
	struct dirent **de;&lt;br /&gt;
	count = scandir( argv[1] , &amp;amp;de , NULL , alphasort );&lt;br /&gt;
	for ( i = 0 ; i &amp;lt; count ; i++ ){&lt;br /&gt;
		printf(&amp;quot;%s &amp;quot;,de[i]-&amp;gt;d_name);&lt;br /&gt;
		free(de[i]);&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
	free(de);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Correggetemi se ho scritto delle sciocchezze.&lt;br /&gt;
-Pirata-&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.05.29&amp;diff=365</id>
		<title>ProvaPratica 2013.05.29</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.05.29&amp;diff=365"/>
		<updated>2013-11-27T18:51:01Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Python 3]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
29 maggio 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.05.29.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 2:&lt;br /&gt;
        print(&amp;quot;The function requires one argument to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Check parameters&lt;br /&gt;
    topDir = str(sys.argv[1])&lt;br /&gt;
    if not os.path.isdir(topDir):&lt;br /&gt;
        print(&amp;quot;The parameter should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Build a dictionary with key-value pair {file extension - total size}&lt;br /&gt;
    extensionSize = { }&lt;br /&gt;
    GetSize(topDir, extensionSize)&lt;br /&gt;
    &lt;br /&gt;
    # Print results&lt;br /&gt;
    PrintResults(extensionSize)&lt;br /&gt;
&lt;br /&gt;
def GetSize(topDir, extensionSize):&lt;br /&gt;
    for dirPath, dirNames, files in os.walk(topDir):&lt;br /&gt;
        for file in files:&lt;br /&gt;
            # 'example.mp3' -&amp;gt; ['example', 'mp3']&lt;br /&gt;
            # 'example.tar.gz' -&amp;gt; ['example', 'tar', 'gz']&lt;br /&gt;
            parts = file.split('.')&lt;br /&gt;
            # ['example', 'mp3'] -&amp;gt; ['mp3']&lt;br /&gt;
            # ['example', 'tar', 'gz'] -&amp;gt; ['tar', 'gz']&lt;br /&gt;
            parts = parts[1:]&lt;br /&gt;
            # ['mp3'] -&amp;gt; '.mp3'&lt;br /&gt;
            # ['tar', 'gz'] -&amp;gt; '.tar.gz'&lt;br /&gt;
            fileExtension = &amp;quot;.{0}&amp;quot;.format(&amp;quot;.&amp;quot;.join(str(part) for part in parts))&lt;br /&gt;
            &lt;br /&gt;
            # Compute the size in Bytes and update the dictionary&lt;br /&gt;
            filePath = os.path.join(dirPath, file)   &lt;br /&gt;
            fileSize = os.path.getsize(filePath)&lt;br /&gt;
            extensionSize[fileExtension] = extensionSize.get(fileExtension, 0) + fileSize&lt;br /&gt;
&lt;br /&gt;
# Print results&lt;br /&gt;
def PrintResults(extensionSize):&lt;br /&gt;
    for key, value in sorted(extensionSize.items()):&lt;br /&gt;
        print('{0}: {1} Bytes.'.format(key, value))&lt;br /&gt;
        &lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
mia versione&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
import os, sys, copy&lt;br /&gt;
&lt;br /&gt;
def dotsubstr(a):#restituisce la sottostringa .suffisso&lt;br /&gt;
	#fcd = os.listdir('{0}'.format(arg1))&lt;br /&gt;
	i=0&lt;br /&gt;
	try:&lt;br /&gt;
		while a[i]!='.':&lt;br /&gt;
			i=i+1&lt;br /&gt;
		return a[i:]&lt;br /&gt;
	except IndexError:&lt;br /&gt;
		return -1&lt;br /&gt;
&lt;br /&gt;
def compliarg(li,arg):#restituisce una lista di tutti gli elementi contenenti la sottostringa arg come suffisso&lt;br /&gt;
	res=[]&lt;br /&gt;
	while li != []:&lt;br /&gt;
		a=li.pop()&lt;br /&gt;
		if a.endswith(arg): res.append(a)&lt;br /&gt;
	return res&lt;br /&gt;
&lt;br /&gt;
def listremintsect(l2,l1):#restituisce una lista res = l1 - intersezione di l1 ed l2&lt;br /&gt;
	res=[]&lt;br /&gt;
	while l1 != []:&lt;br /&gt;
		a=l1.pop()&lt;br /&gt;
		if not a in l2: res.append(a)&lt;br /&gt;
	return res&lt;br /&gt;
&lt;br /&gt;
def createpathlist(c,path):#restituisce una lista di path 'path' relativi ai file contenuti in c.&lt;br /&gt;
	res = []&lt;br /&gt;
	while c != []:&lt;br /&gt;
		res.append('{0}/{1}'.format(path,c.pop()))&lt;br /&gt;
	return res&lt;br /&gt;
&lt;br /&gt;
def totsizes(d): #data una lista d di path restituisce la somma di tutti i size di d&lt;br /&gt;
	res = 0&lt;br /&gt;
	while d != []:&lt;br /&gt;
		a = d.pop()&lt;br /&gt;
		if os.path.isfile('{0}'.format(a)):&lt;br /&gt;
			res = res + os.path.getsize('{0}'.format(a))&lt;br /&gt;
	return res&lt;br /&gt;
&lt;br /&gt;
def listsubstr(arg): #ritorna un dizionario del tipo diz[str(suffisso)] = int(size relativo al suffisso)&lt;br /&gt;
	res = {}&lt;br /&gt;
	fcd = os.listdir('{0}'.format(arg))&lt;br /&gt;
	while fcd != []:&lt;br /&gt;
		fcdtmp=copy.deepcopy(fcd) #BUGGONE SENZA COPY!!!!!!&lt;br /&gt;
		a = fcd.pop()&lt;br /&gt;
		b = dotsubstr(a)&lt;br /&gt;
		if b == -1: continue&lt;br /&gt;
		else: pass&lt;br /&gt;
		c = compliarg(fcdtmp,b)&lt;br /&gt;
		s=copy.deepcopy(c) #!!!!!!!!!!!!!!!!!!!!!!!!!&lt;br /&gt;
		d = createpathlist(c,arg)&lt;br /&gt;
		res[b] = totsizes(d)&lt;br /&gt;
&lt;br /&gt;
		fcd = listremintsect(s,fcd)&lt;br /&gt;
&lt;br /&gt;
	return res&lt;br /&gt;
		&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
	res = listsubstr(sys.argv[1])&lt;br /&gt;
	a=list(res.keys())&lt;br /&gt;
	while a != []:&lt;br /&gt;
		b = a.pop()&lt;br /&gt;
		print('{0}:\t{1}'.format(b,res[b]))&lt;br /&gt;
except OSError:&lt;br /&gt;
	print(&amp;quot;Could not solve path&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-fede&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Esercizio 1: Linguaggio C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/eventfd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BUFFSIZE 10&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int efd,n,i;&lt;br /&gt;
	char buf1[BUFFSIZE];&lt;br /&gt;
	char buf2[BUFFSIZE];&lt;br /&gt;
	&lt;br /&gt;
	do{&lt;br /&gt;
		efd = eventfd(0,0);&lt;br /&gt;
	}while(efd&amp;lt;0);&lt;br /&gt;
	&lt;br /&gt;
	while(1){&lt;br /&gt;
		if(fork()){ /*padre*/&lt;br /&gt;
				read(0,buf1,sizeof(buf1)); /*0 indica lo standard input*/&lt;br /&gt;
				write(efd, buf1, sizeof(buf1));&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
		else{ /*figlio*/&lt;br /&gt;
			read(efd, buf2, sizeof(buf2));&lt;br /&gt;
			n=atoi(buf2);&lt;br /&gt;
			for(i=0; i&amp;lt;n; i++) printf(&amp;quot;x\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
GiuliaN. con grande aiuto da parte dei colleghi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esercizio 3 in bash(Pirata &amp;amp; Fede):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
&lt;br /&gt;
for f in &amp;quot;$1&amp;quot;/*.* ; do&lt;br /&gt;
	somma=0&lt;br /&gt;
	ext=${f##*.}&lt;br /&gt;
	for file in *.&amp;quot;$ext&amp;quot;&lt;br /&gt;
	do&lt;br /&gt;
		somma=$(expr $somma + $(stat -c%s &amp;quot;$file&amp;quot;))&lt;br /&gt;
	done&lt;br /&gt;
	echo -n &amp;quot;size of file with extension &amp;quot;$ext&amp;quot; : &amp;quot;&lt;br /&gt;
	echo &amp;quot;$somma&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Per (Pirata &amp;amp; Fede) -Bash-: ci siamo quasi...però forse rifate gli stessi calcoli un po' di volte in più del necessario ;-) (am_20131127).&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.06.21&amp;diff=349</id>
		<title>ProvaPratica 2013.06.21</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.06.21&amp;diff=349"/>
		<updated>2013-11-25T17:19:32Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: /* Bash */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Python 3]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
20 giugno 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.06.21.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys, hashlib&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 1:&lt;br /&gt;
        print(&amp;quot;The function does not require arguments to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Build a dictionary with key-value pair {file size - [file name]}&lt;br /&gt;
    sameSize = { }&lt;br /&gt;
    PopulateSameSize(sameSize)&lt;br /&gt;
    &lt;br /&gt;
    # Build a dictionary with key-value pair {MD5 hash - [file name]}&lt;br /&gt;
    sameContent = { }&lt;br /&gt;
    for filePaths in sorted(sameSize.values(), key = len, reverse = True):&lt;br /&gt;
        # No files with same size =&amp;gt; No files with same content&lt;br /&gt;
        if len(filePaths) &amp;lt; 2: break&lt;br /&gt;
        PopulateSameContent(filePaths, sameContent)&lt;br /&gt;
&lt;br /&gt;
    # Print results&lt;br /&gt;
    PrintResults(sameContent)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Done!&amp;quot;)&lt;br /&gt;
     &lt;br /&gt;
# Populate a dictionary with key-value pair {file size - [file name]}&lt;br /&gt;
def PopulateSameSize(sameSize):&lt;br /&gt;
    for dirPath, _, fileNames in os.walk(os.getcwd()):&lt;br /&gt;
        for fileName in fileNames:&lt;br /&gt;
            filePath = os.path.join(dirPath, fileName)&lt;br /&gt;
            fileSize = os.path.getsize(filePath)&lt;br /&gt;
            sameSize[fileSize] = sameSize.get(fileSize, []) + [filePath]  &lt;br /&gt;
 &lt;br /&gt;
# Populate a dictionary with key-value pair {MD5 hash - [file name]}&lt;br /&gt;
def PopulateSameContent(filePaths, sameContent):&lt;br /&gt;
    for filePath in filePaths:&lt;br /&gt;
        md5 = GetMd5Hash(filePath)&lt;br /&gt;
        fileRelPath = os.path.relpath(filePath, os.getcwd())&lt;br /&gt;
        sameContent[md5] = sameContent.get(md5, []) + [fileRelPath]&lt;br /&gt;
&lt;br /&gt;
# Get the MD5 hash without loading the whole file to memory&lt;br /&gt;
# Break the file in chunks whose size is a multiple of 128&lt;br /&gt;
# This takes advantage of the fact that MD5 has 128-byte digest blocks&lt;br /&gt;
def GetMd5Hash(filePath, blockSize = 2 ** 20):&lt;br /&gt;
    digest = hashlib.md5()&lt;br /&gt;
    with open(filePath, &amp;quot;rb&amp;quot;) as file:&lt;br /&gt;
        for chunk in iter(lambda: file.read(blockSize), b''): &lt;br /&gt;
            digest.update(chunk)&lt;br /&gt;
    return digest.hexdigest()&lt;br /&gt;
&lt;br /&gt;
# Printout the lists of files having same content&lt;br /&gt;
def PrintResults(sameContent):&lt;br /&gt;
    print(&amp;quot;Lists of files having same content:&amp;quot;)&lt;br /&gt;
    for files in sorted(sameContent.values(), key = len, reverse = True):&lt;br /&gt;
        if len(files) &amp;lt; 2: break&lt;br /&gt;
        print(&amp;quot;[{0}]&amp;quot;.format(&amp;quot;, &amp;quot;.join(file for file in files)))&lt;br /&gt;
        &lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
ecco la mia versione:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
import os, hashlib&lt;br /&gt;
&lt;br /&gt;
def fileCurrDir():#restituisce una lista res di file presenti nella directory&lt;br /&gt;
	fcd = os.listdir('.')&lt;br /&gt;
	res = []&lt;br /&gt;
	for ott in fcd:&lt;br /&gt;
		if os.path.isfile('{0}'.format(ott)):res.append(ott)&lt;br /&gt;
		else:continue&lt;br /&gt;
	return res&lt;br /&gt;
&lt;br /&gt;
def dictsize(fl=fileCurrDir()):#restituisce un dizionario con key filesize e value lista di filenames aventi size di filesize&lt;br /&gt;
	res = {}&lt;br /&gt;
	for f in fl:&lt;br /&gt;
		if os.path.getsize('{0}'.format(f)) in list(res.keys()):res[os.path.getsize('{0}'.format(f))].append(f);continue&lt;br /&gt;
		else:pass&lt;br /&gt;
		res[os.path.getsize('{0}'.format(f))] = list()&lt;br /&gt;
		res[os.path.getsize('{0}'.format(f))].append(f)&lt;br /&gt;
	return res&lt;br /&gt;
&lt;br /&gt;
def dictremsa(a=dictsize()):#data un dizionario key::list rimuove tutti gli item la cui len di lista sia unitaria&lt;br /&gt;
	tmp = list(a.keys())&lt;br /&gt;
	for tmpkey in tmp:&lt;br /&gt;
		if len(a[tmpkey]) &amp;lt; 2: a.pop(tmpkey)&lt;br /&gt;
		else:continue&lt;br /&gt;
	return a&lt;br /&gt;
&lt;br /&gt;
def hashcontrolinsl(l1): #data una lista di nomi di file compara l hash di tutte le possibili coppie dentro 	l1&lt;br /&gt;
	while l1 != []:&lt;br /&gt;
		toTest = l1.pop()&lt;br /&gt;
		del res[:]&lt;br /&gt;
		res.append(toTest)&lt;br /&gt;
		for tmp in l1:&lt;br /&gt;
			#res.append(list[toTest,tmp])&lt;br /&gt;
	#return res&lt;br /&gt;
			hasher = hashlib.md5()&lt;br /&gt;
			hasher2 = hashlib.md5()&lt;br /&gt;
			f = open('{0}'.format(toTest), 'rb')&lt;br /&gt;
			toHash = f.read()&lt;br /&gt;
			hasher.update(toHash)&lt;br /&gt;
			toTesthash = hasher.hexdigest()&lt;br /&gt;
			f.close()&lt;br /&gt;
			f = open('{0}'.format(tmp), 'rb')&lt;br /&gt;
			toHash2 = f.read()&lt;br /&gt;
			hasher2.update(toHash2)&lt;br /&gt;
			tmphash = hasher2.hexdigest()&lt;br /&gt;
			if tmphash==toTesthash: #print('{0} e {1}  sono uguali\n'.format(toTest,tmp))&lt;br /&gt;
				res.append(tmp)&lt;br /&gt;
			else:continue&lt;br /&gt;
		if len(res)&amp;gt;1: &lt;br /&gt;
			print(res);res.pop(0)&lt;br /&gt;
			for j in res:&lt;br /&gt;
				l1.pop(l1.index(j))&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def hashcontroltoMajorTom(a=dictremsa()):#fa in modo che vengano &amp;quot;hashate&amp;quot; solo delle liste di file che abbiano passato il &amp;quot;stessadimenzione&amp;quot; test&lt;br /&gt;
	hasher = hashlib.md5()&lt;br /&gt;
	try:&lt;br /&gt;
		obviouslyequal = a.pop(0)&lt;br /&gt;
		print(&amp;quot;i seguenti file hanno lo stesso contenuto... NULLA!!!!!:\n&amp;quot;)&lt;br /&gt;
		for oe in obviouslyequal:&lt;br /&gt;
			print(&amp;quot;{0}&amp;quot;.format(oe))&lt;br /&gt;
	except KeyError:pass&lt;br /&gt;
	values = list(a.values())&lt;br /&gt;
	print(&amp;quot;\ni seguenti file contengono qualcosa ma sono uguali:\n&amp;quot;)&lt;br /&gt;
	for namelist in values:&lt;br /&gt;
		hashcontrolinsl(namelist)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
hashcontroltoMajorTom()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-fede&lt;br /&gt;
&lt;br /&gt;
==Bash==&lt;br /&gt;
Qualche idea per Bash...&amp;lt;br/&amp;gt;&lt;br /&gt;
Si potrebbero usare:&amp;lt;br/&amp;gt;&lt;br /&gt;
Per la dimensione in byte dei &amp;lt;file&amp;gt;:&lt;br /&gt;
 fileSize=$(stat --format=%s &amp;lt;file&amp;gt;)&lt;br /&gt;
Per avere l'output del solo hash md5 (senza l'ausilio di altri comandi):&lt;br /&gt;
 fileHashMd5=$(md5sum &amp;lt;file&amp;gt; | while read fileHash fileName; do echo $fileHash; done)&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.06.21&amp;diff=348</id>
		<title>ProvaPratica 2013.06.21</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.06.21&amp;diff=348"/>
		<updated>2013-11-25T17:18:53Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Python 3]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
20 giugno 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.06.21.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys, hashlib&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 1:&lt;br /&gt;
        print(&amp;quot;The function does not require arguments to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Build a dictionary with key-value pair {file size - [file name]}&lt;br /&gt;
    sameSize = { }&lt;br /&gt;
    PopulateSameSize(sameSize)&lt;br /&gt;
    &lt;br /&gt;
    # Build a dictionary with key-value pair {MD5 hash - [file name]}&lt;br /&gt;
    sameContent = { }&lt;br /&gt;
    for filePaths in sorted(sameSize.values(), key = len, reverse = True):&lt;br /&gt;
        # No files with same size =&amp;gt; No files with same content&lt;br /&gt;
        if len(filePaths) &amp;lt; 2: break&lt;br /&gt;
        PopulateSameContent(filePaths, sameContent)&lt;br /&gt;
&lt;br /&gt;
    # Print results&lt;br /&gt;
    PrintResults(sameContent)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Done!&amp;quot;)&lt;br /&gt;
     &lt;br /&gt;
# Populate a dictionary with key-value pair {file size - [file name]}&lt;br /&gt;
def PopulateSameSize(sameSize):&lt;br /&gt;
    for dirPath, _, fileNames in os.walk(os.getcwd()):&lt;br /&gt;
        for fileName in fileNames:&lt;br /&gt;
            filePath = os.path.join(dirPath, fileName)&lt;br /&gt;
            fileSize = os.path.getsize(filePath)&lt;br /&gt;
            sameSize[fileSize] = sameSize.get(fileSize, []) + [filePath]  &lt;br /&gt;
 &lt;br /&gt;
# Populate a dictionary with key-value pair {MD5 hash - [file name]}&lt;br /&gt;
def PopulateSameContent(filePaths, sameContent):&lt;br /&gt;
    for filePath in filePaths:&lt;br /&gt;
        md5 = GetMd5Hash(filePath)&lt;br /&gt;
        fileRelPath = os.path.relpath(filePath, os.getcwd())&lt;br /&gt;
        sameContent[md5] = sameContent.get(md5, []) + [fileRelPath]&lt;br /&gt;
&lt;br /&gt;
# Get the MD5 hash without loading the whole file to memory&lt;br /&gt;
# Break the file in chunks whose size is a multiple of 128&lt;br /&gt;
# This takes advantage of the fact that MD5 has 128-byte digest blocks&lt;br /&gt;
def GetMd5Hash(filePath, blockSize = 2 ** 20):&lt;br /&gt;
    digest = hashlib.md5()&lt;br /&gt;
    with open(filePath, &amp;quot;rb&amp;quot;) as file:&lt;br /&gt;
        for chunk in iter(lambda: file.read(blockSize), b''): &lt;br /&gt;
            digest.update(chunk)&lt;br /&gt;
    return digest.hexdigest()&lt;br /&gt;
&lt;br /&gt;
# Printout the lists of files having same content&lt;br /&gt;
def PrintResults(sameContent):&lt;br /&gt;
    print(&amp;quot;Lists of files having same content:&amp;quot;)&lt;br /&gt;
    for files in sorted(sameContent.values(), key = len, reverse = True):&lt;br /&gt;
        if len(files) &amp;lt; 2: break&lt;br /&gt;
        print(&amp;quot;[{0}]&amp;quot;.format(&amp;quot;, &amp;quot;.join(file for file in files)))&lt;br /&gt;
        &lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
ecco la mia versione:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
import os, hashlib&lt;br /&gt;
&lt;br /&gt;
def fileCurrDir():#restituisce una lista res di file presenti nella directory&lt;br /&gt;
	fcd = os.listdir('.')&lt;br /&gt;
	res = []&lt;br /&gt;
	for ott in fcd:&lt;br /&gt;
		if os.path.isfile('{0}'.format(ott)):res.append(ott)&lt;br /&gt;
		else:continue&lt;br /&gt;
	return res&lt;br /&gt;
&lt;br /&gt;
def dictsize(fl=fileCurrDir()):#restituisce un dizionario con key filesize e value lista di filenames aventi size di filesize&lt;br /&gt;
	res = {}&lt;br /&gt;
	for f in fl:&lt;br /&gt;
		if os.path.getsize('{0}'.format(f)) in list(res.keys()):res[os.path.getsize('{0}'.format(f))].append(f);continue&lt;br /&gt;
		else:pass&lt;br /&gt;
		res[os.path.getsize('{0}'.format(f))] = list()&lt;br /&gt;
		res[os.path.getsize('{0}'.format(f))].append(f)&lt;br /&gt;
	return res&lt;br /&gt;
&lt;br /&gt;
def dictremsa(a=dictsize()):#data un dizionario key::list rimuove tutti gli item la cui len di lista sia unitaria&lt;br /&gt;
	tmp = list(a.keys())&lt;br /&gt;
	for tmpkey in tmp:&lt;br /&gt;
		if len(a[tmpkey]) &amp;lt; 2: a.pop(tmpkey)&lt;br /&gt;
		else:continue&lt;br /&gt;
	return a&lt;br /&gt;
&lt;br /&gt;
def hashcontrolinsl(l1): #data una lista di nomi di file compara l hash di tutte le possibili coppie dentro 	l1&lt;br /&gt;
	while l1 != []:&lt;br /&gt;
		toTest = l1.pop()&lt;br /&gt;
		del res[:]&lt;br /&gt;
		res.append(toTest)&lt;br /&gt;
		for tmp in l1:&lt;br /&gt;
			#res.append(list[toTest,tmp])&lt;br /&gt;
	#return res&lt;br /&gt;
			hasher = hashlib.md5()&lt;br /&gt;
			hasher2 = hashlib.md5()&lt;br /&gt;
			f = open('{0}'.format(toTest), 'rb')&lt;br /&gt;
			toHash = f.read()&lt;br /&gt;
			hasher.update(toHash)&lt;br /&gt;
			toTesthash = hasher.hexdigest()&lt;br /&gt;
			f.close()&lt;br /&gt;
			f = open('{0}'.format(tmp), 'rb')&lt;br /&gt;
			toHash2 = f.read()&lt;br /&gt;
			hasher2.update(toHash2)&lt;br /&gt;
			tmphash = hasher2.hexdigest()&lt;br /&gt;
			if tmphash==toTesthash: #print('{0} e {1}  sono uguali\n'.format(toTest,tmp))&lt;br /&gt;
				res.append(tmp)&lt;br /&gt;
			else:continue&lt;br /&gt;
		if len(res)&amp;gt;1: &lt;br /&gt;
			print(res);res.pop(0)&lt;br /&gt;
			for j in res:&lt;br /&gt;
				l1.pop(l1.index(j))&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def hashcontroltoMajorTom(a=dictremsa()):#fa in modo che vengano &amp;quot;hashate&amp;quot; solo delle liste di file che abbiano passato il &amp;quot;stessadimenzione&amp;quot; test&lt;br /&gt;
	hasher = hashlib.md5()&lt;br /&gt;
	try:&lt;br /&gt;
		obviouslyequal = a.pop(0)&lt;br /&gt;
		print(&amp;quot;i seguenti file hanno lo stesso contenuto... NULLA!!!!!:\n&amp;quot;)&lt;br /&gt;
		for oe in obviouslyequal:&lt;br /&gt;
			print(&amp;quot;{0}&amp;quot;.format(oe))&lt;br /&gt;
	except KeyError:pass&lt;br /&gt;
	values = list(a.values())&lt;br /&gt;
	print(&amp;quot;\ni seguenti file contengono qualcosa ma sono uguali:\n&amp;quot;)&lt;br /&gt;
	for namelist in values:&lt;br /&gt;
		hashcontrolinsl(namelist)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
hashcontroltoMajorTom()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-fede&lt;br /&gt;
&lt;br /&gt;
==Bash==&lt;br /&gt;
Qualche idea per Bash...&lt;br /&gt;
Si potrebbero usare:&amp;lt;br/&amp;gt;&lt;br /&gt;
Per la dimensione in byte dei &amp;lt;file&amp;gt;&lt;br /&gt;
 fileSize=$(stat --format=%s &amp;lt;file&amp;gt;)&lt;br /&gt;
Per avere l'output del solo hash md5 (senza l'ausilio di altri comandi):&lt;br /&gt;
 fileHashMd5=$(md5sum &amp;lt;file&amp;gt; | while read fileHash fileName; do echo $fileHash; done)&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.07.18&amp;diff=347</id>
		<title>ProvaPratica 2013.07.18</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.07.18&amp;diff=347"/>
		<updated>2013-11-25T15:44:25Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: /* Osservazioni */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Python 3]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
18 luglio 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.07.18.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 3:&lt;br /&gt;
        print(&amp;quot;The function requires two arguments to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Check parameters&lt;br /&gt;
    srcDir = str(argv[1])&lt;br /&gt;
    dstDir = str(argv[2])&lt;br /&gt;
    if not os.path.isdir(srcDir):&lt;br /&gt;
        print(&amp;quot;First argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    if not os.path.isdir(dstDir):&lt;br /&gt;
        print(&amp;quot;Second argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Build a dictionary with key-value pair {file base name - occurrences}&lt;br /&gt;
    nameFreq = { }&lt;br /&gt;
    for dirPath, dirNames, fileNames in os.walk(srcDir):&lt;br /&gt;
        for fileName in fileNames:&lt;br /&gt;
            fileBaseName, _ = os.path.splitext(fileName)&lt;br /&gt;
            nameFreq[fileBaseName] = nameFreq.get(fileBaseName, -1) + 1&lt;br /&gt;
            &lt;br /&gt;
            # Create a soft link&lt;br /&gt;
            freq = nameFreq[fileBaseName]&lt;br /&gt;
            linkName = &amp;quot;{0}{1}&amp;quot;.format(fileBaseName, str(freq) if freq &amp;gt; 0 else &amp;quot;&amp;quot;)&lt;br /&gt;
            srcPath = os.path.join(os.path.abspath(dirPath), fileName)&lt;br /&gt;
            dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            if not os.path.lexists(dstPath):&lt;br /&gt;
                os.symlink(srcPath, dstPath)&lt;br /&gt;
        &lt;br /&gt;
    print(&amp;quot;Done!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Questa è la mia versione&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def collectfiles(arg1,arg2): &lt;br /&gt;
	fcd = os.listdir('{0}'.format(arg1))&lt;br /&gt;
	while fcd != []:&lt;br /&gt;
		B=str(fcd.pop())&lt;br /&gt;
		C='{0}/{1}'.format(arg1,B)&lt;br /&gt;
		if os.path.isdir('{0}'.format(C)):&lt;br /&gt;
			collectfiles(C,arg2)&lt;br /&gt;
		elif os.path.isfile('{0}'.format(C)):&lt;br /&gt;
			try:&lt;br /&gt;
				os.symlink('{0}'.format(C), '{0}/{1}'.format(arg2,B))&lt;br /&gt;
			except OSError:&lt;br /&gt;
				i=1&lt;br /&gt;
				while True:&lt;br /&gt;
					try:&lt;br /&gt;
						os.symlink('{0}'.format(C), '{0}/{1}{2}'.format(arg2,B,i))&lt;br /&gt;
						break&lt;br /&gt;
					except OSError:&lt;br /&gt;
						i=i+1&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
	collectfiles(str(sys.argv[1]),str(sys.argv[2]))&lt;br /&gt;
except OSError:&lt;br /&gt;
		print(&amp;quot;Invalid Directory!&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-Fede&lt;br /&gt;
&lt;br /&gt;
Leggendo la tua versione ho pensato che in effetti se i file sono &amp;quot;&amp;quot;&amp;quot;pochi&amp;quot;&amp;quot;&amp;quot; l'hash-table non e' necessaria. E' sufficiente un controllo iterativo.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
18 luglio 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.07.18.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 3:&lt;br /&gt;
        print(&amp;quot;The function requires two arguments to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Check parameters&lt;br /&gt;
    srcDir = str(argv[1])&lt;br /&gt;
    dstDir = str(argv[2])&lt;br /&gt;
    if not os.path.isdir(srcDir):&lt;br /&gt;
        print(&amp;quot;First argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    if not os.path.isdir(dstDir):&lt;br /&gt;
        print(&amp;quot;Second argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Traverse the directory tree and create a soft link for each file&lt;br /&gt;
    for dirPath, _, fileNames in os.walk(srcDir):&lt;br /&gt;
        for fileName in fileNames:&lt;br /&gt;
            # 'example.pdf' -&amp;gt; 'example'&lt;br /&gt;
            # 'example.xml' -&amp;gt; 'example'&lt;br /&gt;
            fileBaseName, _ = os.path.splitext(fileName)&lt;br /&gt;
            linkName = fileBaseName&lt;br /&gt;
            srcPath = os.path.join(os.path.abspath(dirPath), fileName)&lt;br /&gt;
            dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            i = 0&lt;br /&gt;
            while os.path.isfile(dstPath):&lt;br /&gt;
                # 'example' will point to 'example.pdf'&lt;br /&gt;
                # 'example1' will point to 'example.xml'&lt;br /&gt;
                i += 1&lt;br /&gt;
                linkName = fileBaseName + str(i)&lt;br /&gt;
                dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            if not os.path.lexists(dstPath):&lt;br /&gt;
                os.symlink(srcPath, dstPath)&lt;br /&gt;
        &lt;br /&gt;
    print(&amp;quot;Done!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Ecco la mia versione in bash&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
 &lt;br /&gt;
BornAgainFede () {&lt;br /&gt;
for f in &amp;quot;$1&amp;quot;/*; do&lt;br /&gt;
	bn=$(basename &amp;quot;$f&amp;quot;)&lt;br /&gt;
	if [[ -f $f ]] ; then&lt;br /&gt;
		if [[ -h &amp;quot;$2&amp;quot;/&amp;quot;$bn&amp;quot; ]] ; then&lt;br /&gt;
			i=1&lt;br /&gt;
			while [[ -h &amp;quot;$2&amp;quot;/&amp;quot;$bn$i&amp;quot; ]] ; do&lt;br /&gt;
			let &amp;quot;i += 1&amp;quot; &lt;br /&gt;
			done&lt;br /&gt;
			ln -s &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;/&amp;quot;$bn$i&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			ln -s &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;/&amp;quot;$bn&amp;quot;&lt;br /&gt;
		fi&lt;br /&gt;
	fi&lt;br /&gt;
	if [[ -d $f ]] ; then&lt;br /&gt;
		BornAgainFede &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
BornAgainFede &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-Fede&lt;br /&gt;
&lt;br /&gt;
==Osservazioni==&lt;br /&gt;
Per prima cosa, bel lavoro!&amp;lt;br/&amp;gt;&lt;br /&gt;
Di seguito riporto alcune osservazioni che mi sono venute in mente, prendetele assolutamente con soli fini &amp;quot;costruttivi&amp;quot;! &lt;br /&gt;
* Se non sbaglio, i due programmi (quello di Tommaso e quello di Fede) hanno un comportamento diverso per quanto concerne l'interpretazione del nome file e, in particolare, dell'estensione:&lt;br /&gt;
** Per Tommaso:&lt;br /&gt;
*** dir1/example.pdf --&amp;gt; example&lt;br /&gt;
*** dir1/example.txt --&amp;gt; example1&lt;br /&gt;
*** dir1/dirX/example.pdf --&amp;gt; example2&lt;br /&gt;
** Per Fede:&lt;br /&gt;
*** dir1/example.pdf --&amp;gt; example.pdf&lt;br /&gt;
*** dir1/example.txt --&amp;gt; example.txt&lt;br /&gt;
*** dir1/dirX/example.pdf --&amp;gt; example.pdf1&lt;br /&gt;
** interpretando in modo &amp;quot;stringente&amp;quot; del testo dell'esercizio avrei ipotizzato un comportamento come quello di Fede.&lt;br /&gt;
* Nel codice sorgente c'è in generale poco &amp;quot;commento&amp;quot;. Commentare il codice è essenziale: permette ad altri di capire immediatamente le scelte implementative fatte e permette a voi di capire al volo il perché di queste scelte nel caso dobbiate riprendere in mano il vostro codice dopo un po' di tempo. Quindi: commentate!!!&lt;br /&gt;
* Bash si presta molto all'esercizio&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.07.18&amp;diff=346</id>
		<title>ProvaPratica 2013.07.18</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.07.18&amp;diff=346"/>
		<updated>2013-11-25T15:41:57Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Python 3]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
18 luglio 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.07.18.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 3:&lt;br /&gt;
        print(&amp;quot;The function requires two arguments to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Check parameters&lt;br /&gt;
    srcDir = str(argv[1])&lt;br /&gt;
    dstDir = str(argv[2])&lt;br /&gt;
    if not os.path.isdir(srcDir):&lt;br /&gt;
        print(&amp;quot;First argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    if not os.path.isdir(dstDir):&lt;br /&gt;
        print(&amp;quot;Second argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Build a dictionary with key-value pair {file base name - occurrences}&lt;br /&gt;
    nameFreq = { }&lt;br /&gt;
    for dirPath, dirNames, fileNames in os.walk(srcDir):&lt;br /&gt;
        for fileName in fileNames:&lt;br /&gt;
            fileBaseName, _ = os.path.splitext(fileName)&lt;br /&gt;
            nameFreq[fileBaseName] = nameFreq.get(fileBaseName, -1) + 1&lt;br /&gt;
            &lt;br /&gt;
            # Create a soft link&lt;br /&gt;
            freq = nameFreq[fileBaseName]&lt;br /&gt;
            linkName = &amp;quot;{0}{1}&amp;quot;.format(fileBaseName, str(freq) if freq &amp;gt; 0 else &amp;quot;&amp;quot;)&lt;br /&gt;
            srcPath = os.path.join(os.path.abspath(dirPath), fileName)&lt;br /&gt;
            dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            if not os.path.lexists(dstPath):&lt;br /&gt;
                os.symlink(srcPath, dstPath)&lt;br /&gt;
        &lt;br /&gt;
    print(&amp;quot;Done!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Questa è la mia versione&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def collectfiles(arg1,arg2): &lt;br /&gt;
	fcd = os.listdir('{0}'.format(arg1))&lt;br /&gt;
	while fcd != []:&lt;br /&gt;
		B=str(fcd.pop())&lt;br /&gt;
		C='{0}/{1}'.format(arg1,B)&lt;br /&gt;
		if os.path.isdir('{0}'.format(C)):&lt;br /&gt;
			collectfiles(C,arg2)&lt;br /&gt;
		elif os.path.isfile('{0}'.format(C)):&lt;br /&gt;
			try:&lt;br /&gt;
				os.symlink('{0}'.format(C), '{0}/{1}'.format(arg2,B))&lt;br /&gt;
			except OSError:&lt;br /&gt;
				i=1&lt;br /&gt;
				while True:&lt;br /&gt;
					try:&lt;br /&gt;
						os.symlink('{0}'.format(C), '{0}/{1}{2}'.format(arg2,B,i))&lt;br /&gt;
						break&lt;br /&gt;
					except OSError:&lt;br /&gt;
						i=i+1&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
	collectfiles(str(sys.argv[1]),str(sys.argv[2]))&lt;br /&gt;
except OSError:&lt;br /&gt;
		print(&amp;quot;Invalid Directory!&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-Fede&lt;br /&gt;
&lt;br /&gt;
Leggendo la tua versione ho pensato che in effetti se i file sono &amp;quot;&amp;quot;&amp;quot;pochi&amp;quot;&amp;quot;&amp;quot; l'hash-table non e' necessaria. E' sufficiente un controllo iterativo.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
18 luglio 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.07.18.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 3:&lt;br /&gt;
        print(&amp;quot;The function requires two arguments to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Check parameters&lt;br /&gt;
    srcDir = str(argv[1])&lt;br /&gt;
    dstDir = str(argv[2])&lt;br /&gt;
    if not os.path.isdir(srcDir):&lt;br /&gt;
        print(&amp;quot;First argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    if not os.path.isdir(dstDir):&lt;br /&gt;
        print(&amp;quot;Second argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Traverse the directory tree and create a soft link for each file&lt;br /&gt;
    for dirPath, _, fileNames in os.walk(srcDir):&lt;br /&gt;
        for fileName in fileNames:&lt;br /&gt;
            # 'example.pdf' -&amp;gt; 'example'&lt;br /&gt;
            # 'example.xml' -&amp;gt; 'example'&lt;br /&gt;
            fileBaseName, _ = os.path.splitext(fileName)&lt;br /&gt;
            linkName = fileBaseName&lt;br /&gt;
            srcPath = os.path.join(os.path.abspath(dirPath), fileName)&lt;br /&gt;
            dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            i = 0&lt;br /&gt;
            while os.path.isfile(dstPath):&lt;br /&gt;
                # 'example' will point to 'example.pdf'&lt;br /&gt;
                # 'example1' will point to 'example.xml'&lt;br /&gt;
                i += 1&lt;br /&gt;
                linkName = fileBaseName + str(i)&lt;br /&gt;
                dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            if not os.path.lexists(dstPath):&lt;br /&gt;
                os.symlink(srcPath, dstPath)&lt;br /&gt;
        &lt;br /&gt;
    print(&amp;quot;Done!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Ecco la mia versione in bash&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
 &lt;br /&gt;
BornAgainFede () {&lt;br /&gt;
for f in &amp;quot;$1&amp;quot;/*; do&lt;br /&gt;
	bn=$(basename &amp;quot;$f&amp;quot;)&lt;br /&gt;
	if [[ -f $f ]] ; then&lt;br /&gt;
		if [[ -h &amp;quot;$2&amp;quot;/&amp;quot;$bn&amp;quot; ]] ; then&lt;br /&gt;
			i=1&lt;br /&gt;
			while [[ -h &amp;quot;$2&amp;quot;/&amp;quot;$bn$i&amp;quot; ]] ; do&lt;br /&gt;
			let &amp;quot;i += 1&amp;quot; &lt;br /&gt;
			done&lt;br /&gt;
			ln -s &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;/&amp;quot;$bn$i&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			ln -s &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;/&amp;quot;$bn&amp;quot;&lt;br /&gt;
		fi&lt;br /&gt;
	fi&lt;br /&gt;
	if [[ -d $f ]] ; then&lt;br /&gt;
		BornAgainFede &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
BornAgainFede &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-Fede&lt;br /&gt;
&lt;br /&gt;
==Osservazioni==&lt;br /&gt;
Per prima cosa, bel lavoro!&amp;lt;br/&amp;gt;&lt;br /&gt;
Di seguito riporto alcune osservazioni che mi sono venute in mente, prendetele assolutamente con soli fini &amp;quot;costruttivi&amp;quot;! &lt;br /&gt;
* Se non sbaglio, i due programmi (quello di Tommaso e quello di Fede) hanno un comportamento diverso per quanto concerne l'interpretazione del nome file e, in particolare, dell'estensione:&lt;br /&gt;
** Per Tommaso:&lt;br /&gt;
*** dir1/example.pdf --&amp;gt; example&lt;br /&gt;
*** dir1/example.txt --&amp;gt; example1&lt;br /&gt;
*** dir1/dirX/example.pdf --&amp;gt; example2&lt;br /&gt;
** Per Fede:&lt;br /&gt;
*** dir1/example.pdf --&amp;gt; example.pdf&lt;br /&gt;
*** dir1/example.txt --&amp;gt; example.txt&lt;br /&gt;
*** dir1/dirX/example.pdf --&amp;gt; example.pdf1&lt;br /&gt;
** interpretando in modo &amp;quot;stringente&amp;quot; del testo dell'esercizio avrei ipotizzato un comportamento come quello di Fede.&lt;br /&gt;
* Nel codice sorgente c'è in generale poco &amp;quot;commento&amp;quot;. Commentare il codice è essenziale: permette ad altri di capire immediatamente le scelte implementative fatte e permette a voi di capire al volo il perché di queste scelte nel caso dobbiate riprendere in mano il vostro codice dopo un po' di tempo. Quindi: commentate!!!&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.07.18&amp;diff=345</id>
		<title>ProvaPratica 2013.07.18</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.07.18&amp;diff=345"/>
		<updated>2013-11-25T15:40:03Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Python 3]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
18 luglio 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.07.18.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 3:&lt;br /&gt;
        print(&amp;quot;The function requires two arguments to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Check parameters&lt;br /&gt;
    srcDir = str(argv[1])&lt;br /&gt;
    dstDir = str(argv[2])&lt;br /&gt;
    if not os.path.isdir(srcDir):&lt;br /&gt;
        print(&amp;quot;First argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    if not os.path.isdir(dstDir):&lt;br /&gt;
        print(&amp;quot;Second argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Build a dictionary with key-value pair {file base name - occurrences}&lt;br /&gt;
    nameFreq = { }&lt;br /&gt;
    for dirPath, dirNames, fileNames in os.walk(srcDir):&lt;br /&gt;
        for fileName in fileNames:&lt;br /&gt;
            fileBaseName, _ = os.path.splitext(fileName)&lt;br /&gt;
            nameFreq[fileBaseName] = nameFreq.get(fileBaseName, -1) + 1&lt;br /&gt;
            &lt;br /&gt;
            # Create a soft link&lt;br /&gt;
            freq = nameFreq[fileBaseName]&lt;br /&gt;
            linkName = &amp;quot;{0}{1}&amp;quot;.format(fileBaseName, str(freq) if freq &amp;gt; 0 else &amp;quot;&amp;quot;)&lt;br /&gt;
            srcPath = os.path.join(os.path.abspath(dirPath), fileName)&lt;br /&gt;
            dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            if not os.path.lexists(dstPath):&lt;br /&gt;
                os.symlink(srcPath, dstPath)&lt;br /&gt;
        &lt;br /&gt;
    print(&amp;quot;Done!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Questa è la mia versione&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def collectfiles(arg1,arg2): &lt;br /&gt;
	fcd = os.listdir('{0}'.format(arg1))&lt;br /&gt;
	while fcd != []:&lt;br /&gt;
		B=str(fcd.pop())&lt;br /&gt;
		C='{0}/{1}'.format(arg1,B)&lt;br /&gt;
		if os.path.isdir('{0}'.format(C)):&lt;br /&gt;
			collectfiles(C,arg2)&lt;br /&gt;
		elif os.path.isfile('{0}'.format(C)):&lt;br /&gt;
			try:&lt;br /&gt;
				os.symlink('{0}'.format(C), '{0}/{1}'.format(arg2,B))&lt;br /&gt;
			except OSError:&lt;br /&gt;
				i=1&lt;br /&gt;
				while True:&lt;br /&gt;
					try:&lt;br /&gt;
						os.symlink('{0}'.format(C), '{0}/{1}{2}'.format(arg2,B,i))&lt;br /&gt;
						break&lt;br /&gt;
					except OSError:&lt;br /&gt;
						i=i+1&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
	collectfiles(str(sys.argv[1]),str(sys.argv[2]))&lt;br /&gt;
except OSError:&lt;br /&gt;
		print(&amp;quot;Invalid Directory!&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-Fede&lt;br /&gt;
&lt;br /&gt;
Leggendo la tua versione ho pensato che in effetti se i file sono &amp;quot;&amp;quot;&amp;quot;pochi&amp;quot;&amp;quot;&amp;quot; l'hash-table non e' necessaria. E' sufficiente un controllo iterativo.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
'''&lt;br /&gt;
Prova Pratica di Laboratorio di Sistemi Operativi&lt;br /&gt;
18 luglio 2013&lt;br /&gt;
Esercizio 3&lt;br /&gt;
&lt;br /&gt;
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.07.18.pdf&lt;br /&gt;
&lt;br /&gt;
@author: Tommaso Ognibene&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
def Main(argv):&lt;br /&gt;
    # Check number of arguments&lt;br /&gt;
    if len(argv) != 3:&lt;br /&gt;
        print(&amp;quot;The function requires two arguments to be passed in.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Check parameters&lt;br /&gt;
    srcDir = str(argv[1])&lt;br /&gt;
    dstDir = str(argv[2])&lt;br /&gt;
    if not os.path.isdir(srcDir):&lt;br /&gt;
        print(&amp;quot;First argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    if not os.path.isdir(dstDir):&lt;br /&gt;
        print(&amp;quot;Second argument should be an existing directory.&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
    &lt;br /&gt;
    # Traverse the directory tree and create a soft link for each file&lt;br /&gt;
    for dirPath, _, fileNames in os.walk(srcDir):&lt;br /&gt;
        for fileName in fileNames:&lt;br /&gt;
            # 'example.pdf' -&amp;gt; 'example'&lt;br /&gt;
            # 'example.xml' -&amp;gt; 'example'&lt;br /&gt;
            fileBaseName, _ = os.path.splitext(fileName)&lt;br /&gt;
            linkName = fileBaseName&lt;br /&gt;
            srcPath = os.path.join(os.path.abspath(dirPath), fileName)&lt;br /&gt;
            dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            i = 0&lt;br /&gt;
            while os.path.isfile(dstPath):&lt;br /&gt;
                # 'example' will point to 'example.pdf'&lt;br /&gt;
                # 'example1' will point to 'example.xml'&lt;br /&gt;
                i += 1&lt;br /&gt;
                linkName = fileBaseName + str(i)&lt;br /&gt;
                dstPath = os.path.join(dstDir, linkName)&lt;br /&gt;
            if not os.path.lexists(dstPath):&lt;br /&gt;
                os.symlink(srcPath, dstPath)&lt;br /&gt;
        &lt;br /&gt;
    print(&amp;quot;Done!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.exit(Main(sys.argv))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Ecco la mia versione in bash&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
 &lt;br /&gt;
BornAgainFede () {&lt;br /&gt;
for f in &amp;quot;$1&amp;quot;/*; do&lt;br /&gt;
	bn=$(basename &amp;quot;$f&amp;quot;)&lt;br /&gt;
	if [[ -f $f ]] ; then&lt;br /&gt;
		if [[ -h &amp;quot;$2&amp;quot;/&amp;quot;$bn&amp;quot; ]] ; then&lt;br /&gt;
			i=1&lt;br /&gt;
			while [[ -h &amp;quot;$2&amp;quot;/&amp;quot;$bn$i&amp;quot; ]] ; do&lt;br /&gt;
			let &amp;quot;i += 1&amp;quot; &lt;br /&gt;
			done&lt;br /&gt;
			ln -s &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;/&amp;quot;$bn$i&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			ln -s &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;/&amp;quot;$bn&amp;quot;&lt;br /&gt;
		fi&lt;br /&gt;
	fi&lt;br /&gt;
	if [[ -d $f ]] ; then&lt;br /&gt;
		BornAgainFede &amp;quot;$1&amp;quot;/&amp;quot;$bn&amp;quot; &amp;quot;$2&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
BornAgainFede &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-Fede&lt;br /&gt;
&lt;br /&gt;
==Osservazioni==&lt;br /&gt;
Per prima cosa, bel lavoro!&amp;lt;br/&amp;gt;&lt;br /&gt;
Di seguito riporto alcune osservazioni che mi sono venute in mente, prendetele assolutamente con soli fini &amp;quot;costruttivi&amp;quot;! &lt;br /&gt;
* Se non sbaglio, i due programmi (quello di Tommaso e quello di Fede) hanno un comportamento diverso per quanto concerne l'interpretazione del nome file e, in particolare, l'estensione:&amp;lt;br/&amp;gt;&lt;br /&gt;
** Per Tommaso:&lt;br /&gt;
*** dir1/example.pdf --&amp;gt; example&lt;br /&gt;
*** dir1/example.txt --&amp;gt; example1&lt;br /&gt;
*** dir1/dirX/example.pdf --&amp;gt; example2&lt;br /&gt;
** Per Fede:&lt;br /&gt;
*** dir1/example.pdf --&amp;gt; example.pdf&lt;br /&gt;
*** dir1/example.txt --&amp;gt; example.txt&lt;br /&gt;
*** dir1/dirX/example.pdf --&amp;gt; example.pdf1&lt;br /&gt;
** interpretando in modo &amp;quot;stringente&amp;quot; del testo dell'esercizio avrei ipotizzato un comportamento come quello di Fede.&lt;br /&gt;
* Nel codice sorgente c'è in generale poco &amp;quot;commento&amp;quot;. Commentare il codice è essenziale: permette ad altri di capire immediatamente le scelte implementative fatte e permette a voi di capire al volo il perché di queste scelte nel caso dobbiate riprendere in mano il vostro codice dopo un po' di tempo.&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Comandi_visti_alle_lezioni.&amp;diff=255</id>
		<title>Comandi visti alle lezioni.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Comandi_visti_alle_lezioni.&amp;diff=255"/>
		<updated>2013-11-20T18:53:33Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;mi sembra una buon idea fare una tabellina con commandi importanti visti alle lezioni, e una breve descrizione di che fanno e che parametri ricevono. non ne ho tutti scritti, allora mi raccomando- aggiungete pure!&lt;br /&gt;
&lt;br /&gt;
ps- e' possibile fare una tabella?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
at&lt;br /&gt;
&lt;br /&gt;
cat- concatenare file&lt;br /&gt;
&lt;br /&gt;
chmod- cambia mode&lt;br /&gt;
&lt;br /&gt;
echo- stampa il testo&lt;br /&gt;
&lt;br /&gt;
false- non fa niente - restituisce 1 (falso)&lt;br /&gt;
&lt;br /&gt;
ln- linka tra due file (-s crea il link simbolico)&lt;br /&gt;
&lt;br /&gt;
mkdir- crea una cartella&lt;br /&gt;
&lt;br /&gt;
nologin- prevenire unpriviliggiati utenti di loggare al sistema&lt;br /&gt;
&lt;br /&gt;
od&lt;br /&gt;
&lt;br /&gt;
pwd- stampa l'indirizzio alla cartella in cui sono&lt;br /&gt;
&lt;br /&gt;
touch- crea un file&lt;br /&gt;
&lt;br /&gt;
true- non fa niente (retituisce 0 vero)&lt;br /&gt;
&lt;br /&gt;
umask - stabilisce i permessi standard (i bit accesi nella umask vengono normalmente spenti)&lt;br /&gt;
&lt;br /&gt;
whoami- stampa l'id dell'utente&lt;br /&gt;
&lt;br /&gt;
su- switch user&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Daniele F. &amp;amp; Federico A.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Abbiamo messo qualche comando con relativa descrizione, speriamo vi possano aiutare e che non ci siano troppi errori.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Informazioni e Aiuti: &lt;br /&gt;
&lt;br /&gt;
* '''man''' ''file'' : (manual) apre il manuale, se esiste, alla pagina relativa a ''file''.&lt;br /&gt;
** '''man''' ''[-k]'' ''file'' : elenca tutte le pagine di manuale con la parola ''file''.&lt;br /&gt;
** '''man''' ''[n]'' ''file'' : apre la sezione n (1 eseguibili e comandi, 2 system calls, 3 libreria...)  relativa a ''file''; (p.e. ''man 2 open'' apre la pagina relativa alla system call &amp;quot;open&amp;quot;.). &lt;br /&gt;
* '''info''' ''file'' : apre il documento informativo relativo a 'file'.&lt;br /&gt;
* '''help''' ''[file]'' : visualizza alcuni comandi utili o informazioni su ''file''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi per Cartelle e File:&lt;br /&gt;
&lt;br /&gt;
* '''ls''' ''[path]'' : (list) visualizza la lista dei file/directory nella directory corrente o nel path indicato.&lt;br /&gt;
** '''ls''' ''[-l]'' : visualizza la lista estesa (privilegi, n* hard link, proprietario, dimensione, ultima modifica, nome file/directory)  dei file/directory nella directory corrente.&lt;br /&gt;
* '''pwd''' : (print working directory) visualizza il percorso della directory corrente. &lt;br /&gt;
* '''cd''' ''[path]'' :  (change directory) entra nella directory specificata da ''path'' altrimenti torna al root dell'utente.&lt;br /&gt;
* '''rm''' ''file'' : (remove) elimina ''file''.&lt;br /&gt;
** '''rm''' ''[-Rf]'' ''file/path'' : elimina in modo ricorsivo e forzato i file e le directory nel ''path'' specificato.&lt;br /&gt;
* '''rmdir''' ''dir'' : (remove directory) elimina ''dir'' se vuota.&lt;br /&gt;
* '''mkdir''' ''dir'' : (make directory) crea la directory ''dir'' (può essere anche specificato un path).&lt;br /&gt;
* '''mv''' ''source'' ''dest'' : (move) muovi (o rinomina) il file ''source'' nel path ''dest''.&lt;br /&gt;
* '''touch''' ''file'' : crea ''file'' o se esiste già cambia la data di ultima modifica.&lt;br /&gt;
* '''ln''' ''target'' ''link'' : crea un link al file o directory ''target''.&lt;br /&gt;
** '''ln''' ''[-s]'' ''target'' ''link'' : (soft link) link simbolico.&lt;br /&gt;
** '''ln''' ''[-p]'' ''target'' ''link'' : (hard link) link fisico a file (non è possibile fare link a directory).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi di Gestione e Analisi Sistema:&lt;br /&gt;
&lt;br /&gt;
* '''ps ''' : (process status) visualizza il report dei processi attivi.&lt;br /&gt;
** '''pstree''' : visualizza l'albero dei processi attivi.&lt;br /&gt;
* '''df''' : (disk free) visualizza lo spazio occupato del disco dai file di sistema.&lt;br /&gt;
* '''du''' : (disk usage) visualizza una stima dell'utilizzo del disco di ogni singolo file/directory.&lt;br /&gt;
* '''groupadd''' ''group'' : crea il nuovo gruppo ''group''.&lt;br /&gt;
* '''useradd''' ''username'' : crea il nuovo utente ''username''.&lt;br /&gt;
* '''adduser''' ''username'' : crea il nuovo utente ''username'' (in maniera più veloce).&lt;br /&gt;
* '''groupdel''' ''group'' : elimina il gruppo indicato.&lt;br /&gt;
* '''userdel''' ''username'': elimina l'utente indicato.&lt;br /&gt;
* '''deluser''' ''username'': elimina l'utente indicato (in maniera più veloce).&lt;br /&gt;
* '''chmod''' ''par'' ''file'' : (change mode) modifica i privilegi di ''file'' tramite i valori/caratteri di ''par''.&lt;br /&gt;
* '''chown''' ''file'' : (change owner) cambia il proprietario e il gruppo di ''file''.&lt;br /&gt;
* '''chgrp''' ''group'' ''file'' : (change group) cambia il gruppo di ''file'' in ''group''.&lt;br /&gt;
* '''su''' ''[username]'' : (switch user) cambia utente.&lt;br /&gt;
* '''whoami''' : visualizza l'utente che usa il comando.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi Ctrl:&lt;br /&gt;
&lt;br /&gt;
* '''^S''' : sospende la visualizzazione.&lt;br /&gt;
* '''^Q''' : riattiva la visualizzazione.&lt;br /&gt;
* '''^C''' : cancella un'operazione.&lt;br /&gt;
* '''^D''' : fine del file.&lt;br /&gt;
* '''^V''' : tratta il carattere di controllo sequenze come se fosse carattere normale.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi Vari:&lt;br /&gt;
&lt;br /&gt;
* '''true''' : restituisce 0.&lt;br /&gt;
* '''false''' : restituisce 1.&lt;br /&gt;
* '''od''' ''[file]'' : stampa una rappresentazione in base ottale di ''file'' (esadecimale con -x).&lt;br /&gt;
* '''kill''' ''pid'' : termina il processo con id ''pid''.&lt;br /&gt;
* '''errno''' : (error number)  ultimo errore restituito.&lt;br /&gt;
* '''strerror''' : (string error) stringa corrispondente all'ultimo errore.&lt;br /&gt;
* '''echo''' ''string'' : stampa a video ''string''.&lt;br /&gt;
* '''time''' ''command'' : ???&lt;br /&gt;
* '''dd''' : ???&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[User:Ferra1993|Ferra1993]] ([[User talk:Ferra1993|talk]]) 17:45, 7 November 2013 (CET)&lt;br /&gt;
| [[User:Fede|Fede]] ([[User talk:Fede|talk]]) 17:49, 7 November 2013 (CET)&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=254</id>
		<title>SYS CALL viste a lezione.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=254"/>
		<updated>2013-11-20T15:46:31Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Controllo processi==&lt;br /&gt;
===FORK===&lt;br /&gt;
Crea un nuovo processo duplicando il processo chiamante. Il nuovo processo , chiamato figlio, é un duplicato esatto del processo chiamante , chiamato padre. &lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){     &lt;br /&gt;
	if(fork()){&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() ); // getpid() stampa il pid del processo corrente , getppid() stampa il pid del processo padre&lt;br /&gt;
        sleep(2);}   //se togliessimo lo sleep;il processo figlio stamperebbe come getppid() 1,perché essendo il padre terminato e lui rimasto orfano,il nuovo padre diventa init&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2(una piccola osservazione sull'eredità del buffer):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	printf(&amp;quot;cucù! : &amp;quot;);      //notare la differenza se nella sringa metto \n &lt;br /&gt;
	if(fork())&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() );&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio3(fork e malloc):&amp;lt;br/&amp;gt;&lt;br /&gt;
'''(sottolineerei che lo spazio di indirizzamento è di fatto separato: i due processi hanno una analoga visione dell'indirizzamento logico, che però è specifico di ogni processo e i dati sono memorizzati fisicamente in aree di memoria diverse. am_20131110)'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	int *p;&lt;br /&gt;
	if( fork() ){&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	*p = 45;&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());   &lt;br /&gt;
	sleep(2);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());  //i puntatori restituiranno lo stesso indirizzo di memoria sia per il padre che per il figlio         &lt;br /&gt;
	sleep(1);                                                           //perché condividono lo stesso spazio di indirizzamento&lt;br /&gt;
	}&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===_EXIT===&lt;br /&gt;
Termina il proceso chiamante.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc,char *argv[]){&lt;br /&gt;
	_exit(0);                     //Sys call che termina il processo chiamante&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2(atexit):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void at1(void){&lt;br /&gt;
	printf(&amp;quot;at1 \n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
void at2(void){&lt;br /&gt;
	printf(&amp;quot;at2 \n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main (int argc,char *argv[]){&lt;br /&gt;
	printf(&amp;quot;brutal kill \n&amp;quot;);&lt;br /&gt;
	atexit(at1);	//funzione di libreria che termina il processo passato come argomento&lt;br /&gt;
	atexit(at2); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//le funzioni passate ad atexit vengono eseguite in modo inverso rispetto all'invocazione&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===WAIT===&lt;br /&gt;
Aspetta che un processo cambi di stato.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
                sleep(10); &lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;,WEXITSTATUS(status)); //Macro che restituisce l' exit status del figlio,cioè gli otto bit meno significativi dello status che il figlio&lt;br /&gt;
	}                                                         //specifica in una chiamata di _exit o exit o come argomento di ritorno del main.&lt;br /&gt;
	else {&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		exit(1);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) //Macro che restituisce true se il figlio termina normalmente, cioé chiamando _exit o exit oppure tramite il return del main&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if(WIFSIGNALED(status) )  //Macro che restituisce true se il figlio é terminato da un segnale&lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) );  //Macro che restituisce il numero del segnale che causa la terminazione del processo figlio&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		int *p;&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		p = (int *)42;&lt;br /&gt;
		*p = 43;	&lt;br /&gt;
		exit(2);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===EXEC===&lt;br /&gt;
Esegue un programma.&lt;br /&gt;
La famiglia di funzioni exec() rimpiazza l'immagine del processo corrente con l'immagine di un nuovo processo.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) &lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if( WIFSIGNALED(status) )  &lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) ); &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		char *args[] = {&amp;quot;ls&amp;quot;,&amp;quot;-l&amp;quot;,(char *)0};&lt;br /&gt;
		execvp(&amp;quot;ls&amp;quot;,args); //funzione di libreria che prende in input il path(p) e un vettore(v).&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d %s \n&amp;quot;,getpid(),pid,argv[1]);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) &lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if( WIFSIGNALED(status) )  &lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) ); &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		execvp(argv[2],argv+2);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Correggetemi se ho scritto delle sciocchezze.&lt;br /&gt;
-Pirata-&lt;br /&gt;
&lt;br /&gt;
==Gestione File==&lt;br /&gt;
* int open(const char *path, int oflag, ...);&amp;lt;br/&amp;gt;&lt;br /&gt;
* int creat(const char *path, mode_t mode);&lt;br /&gt;
* int close(int filedes);&lt;br /&gt;
* off_t lseek(int filedes, off_t offset, int whence);&lt;br /&gt;
* ssize_t read(int filedes, void *buf, size_t nbyte);&lt;br /&gt;
* ssize_t write(int filedes, const void *buf, size_t nbyte);&lt;br /&gt;
&lt;br /&gt;
Qualche esempio? Iniziamo con i file &amp;quot;con il buco&amp;quot; visti a lezione?&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=253</id>
		<title>SYS CALL viste a lezione.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=253"/>
		<updated>2013-11-20T15:45:17Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==FORK==&lt;br /&gt;
Crea un nuovo processo duplicando il processo chiamante. Il nuovo processo , chiamato figlio, é un duplicato esatto del processo chiamante , chiamato padre. &lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){     &lt;br /&gt;
	if(fork()){&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() ); // getpid() stampa il pid del processo corrente , getppid() stampa il pid del processo padre&lt;br /&gt;
        sleep(2);}   //se togliessimo lo sleep;il processo figlio stamperebbe come getppid() 1,perché essendo il padre terminato e lui rimasto orfano,il nuovo padre diventa init&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2(una piccola osservazione sull'eredità del buffer):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	printf(&amp;quot;cucù! : &amp;quot;);      //notare la differenza se nella sringa metto \n &lt;br /&gt;
	if(fork())&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() );&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio3(fork e malloc):&amp;lt;br/&amp;gt;&lt;br /&gt;
'''(sottolineerei che lo spazio di indirizzamento è di fatto separato: i due processi hanno una analoga visione dell'indirizzamento logico, che però è specifico di ogni processo e i dati sono memorizzati fisicamente in aree di memoria diverse. am_20131110)'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	int *p;&lt;br /&gt;
	if( fork() ){&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	*p = 45;&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());   &lt;br /&gt;
	sleep(2);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());  //i puntatori restituiranno lo stesso indirizzo di memoria sia per il padre che per il figlio         &lt;br /&gt;
	sleep(1);                                                           //perché condividono lo stesso spazio di indirizzamento&lt;br /&gt;
	}&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==_EXIT==&lt;br /&gt;
Termina il proceso chiamante.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc,char *argv[]){&lt;br /&gt;
	_exit(0);                     //Sys call che termina il processo chiamante&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2(atexit):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void at1(void){&lt;br /&gt;
	printf(&amp;quot;at1 \n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
void at2(void){&lt;br /&gt;
	printf(&amp;quot;at2 \n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main (int argc,char *argv[]){&lt;br /&gt;
	printf(&amp;quot;brutal kill \n&amp;quot;);&lt;br /&gt;
	atexit(at1);	//funzione di libreria che termina il processo passato come argomento&lt;br /&gt;
	atexit(at2); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//le funzioni passate ad atexit vengono eseguite in modo inverso rispetto all'invocazione&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WAIT==&lt;br /&gt;
Aspetta che un processo cambi di stato.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
                sleep(10); &lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;,WEXITSTATUS(status)); //Macro che restituisce l' exit status del figlio,cioè gli otto bit meno significativi dello status che il figlio&lt;br /&gt;
	}                                                         //specifica in una chiamata di _exit o exit o come argomento di ritorno del main.&lt;br /&gt;
	else {&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		exit(1);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) //Macro che restituisce true se il figlio termina normalmente, cioé chiamando _exit o exit oppure tramite il return del main&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if(WIFSIGNALED(status) )  //Macro che restituisce true se il figlio é terminato da un segnale&lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) );  //Macro che restituisce il numero del segnale che causa la terminazione del processo figlio&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		int *p;&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		p = (int *)42;&lt;br /&gt;
		*p = 43;	&lt;br /&gt;
		exit(2);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==EXEC==&lt;br /&gt;
Esegue un programma.&lt;br /&gt;
La famiglia di funzioni exec() rimpiazza l'immagine del processo corrente con l'immagine di un nuovo processo.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) &lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if( WIFSIGNALED(status) )  &lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) ); &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		char *args[] = {&amp;quot;ls&amp;quot;,&amp;quot;-l&amp;quot;,(char *)0};&lt;br /&gt;
		execvp(&amp;quot;ls&amp;quot;,args); //funzione di libreria che prende in input il path(p) e un vettore(v).&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d %s \n&amp;quot;,getpid(),pid,argv[1]);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,&amp;amp;status,0);&lt;br /&gt;
		if (WIFEXITED(status)) &lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if( WIFSIGNALED(status) )  &lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) ); &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		execvp(argv[2],argv+2);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Correggetemi se ho scritto delle sciocchezze.&lt;br /&gt;
-Pirata-&lt;br /&gt;
&lt;br /&gt;
==Gestione File==&lt;br /&gt;
* int open(const char *path, int oflag, ...);&amp;lt;br/&amp;gt;&lt;br /&gt;
* int creat(const char *path, mode_t mode);&lt;br /&gt;
* int close(int filedes);&lt;br /&gt;
* off_t lseek(int filedes, off_t offset, int whence);&lt;br /&gt;
* ssize_t read(int filedes, void *buf, size_t nbyte);&lt;br /&gt;
* ssize_t write(int filedes, const void *buf, size_t nbyte);&lt;br /&gt;
&lt;br /&gt;
Qualche esempio? Iniziamo con i file &amp;quot;con il buco&amp;quot; visti a lezione?&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Comandi_visti_alle_lezioni.&amp;diff=201</id>
		<title>Comandi visti alle lezioni.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Comandi_visti_alle_lezioni.&amp;diff=201"/>
		<updated>2013-11-12T11:43:13Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;mi sembra una buon idea fare una tabellina con commandi importanti visti alle lezioni, e una breve descrizione di che fanno e che parametri ricevono. non ne ho tutti scritti, allora mi raccomando- aggiungete pure!&lt;br /&gt;
&lt;br /&gt;
ps- e' possibile fare una tabella?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
at&lt;br /&gt;
&lt;br /&gt;
cat- concatenare file&lt;br /&gt;
&lt;br /&gt;
chmod- cambia mode&lt;br /&gt;
&lt;br /&gt;
echo- stampa il testo&lt;br /&gt;
&lt;br /&gt;
false- non fa niente - restituisce 1 (falso)&lt;br /&gt;
&lt;br /&gt;
ln- linka tra due file (-s crea il link simbolico)&lt;br /&gt;
&lt;br /&gt;
mkdir- crea una cartella&lt;br /&gt;
&lt;br /&gt;
nologin- prevenire unpriviliggiati utenti di loggare al sistema&lt;br /&gt;
&lt;br /&gt;
od&lt;br /&gt;
&lt;br /&gt;
pwd- stampa l'indirizzio alla cartella in cui sono&lt;br /&gt;
&lt;br /&gt;
touch- crea un file&lt;br /&gt;
&lt;br /&gt;
true- non fa niente (retituisce 0 vero)&lt;br /&gt;
&lt;br /&gt;
umask - stabilisce i permessi standard (i bit accesi nella umask vengono normalmente spenti)&lt;br /&gt;
&lt;br /&gt;
whoami- stampa l'id dell'utente&lt;br /&gt;
&lt;br /&gt;
su- switch user&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Daniele F. &amp;amp; Federico A.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Abbiamo messo qualche comando con relativa descrizione, speriamo vi possano aiutare e che non ci siano troppi errori.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Informazioni e Aiuti: &lt;br /&gt;
&lt;br /&gt;
* '''man''' ''file'' : (manual) apre il manuale, se esiste, alla pagina relativa a ''file''.&lt;br /&gt;
** '''man''' ''[-k]'' ''file'' : elenca tutte le pagine di manuale con la parola ''file''.&lt;br /&gt;
** '''man''' ''[n]'' ''file'' : apre la sezione n (1 eseguibili e comandi, 2 system calls, 3 libreria...)  relativa a ''file''; (p.e. ''man 2 open'' apre la pagina relativa alla system call &amp;quot;open&amp;quot;.). &lt;br /&gt;
* '''info''' ''file'' : apre il documento informativo relativo a 'file'.&lt;br /&gt;
* '''help''' ''[file]'' : visualizza alcuni comandi utili o informazioni su ''file''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi per Cartelle e File:&lt;br /&gt;
&lt;br /&gt;
* '''ls''' ''[path]'' : (list) visualizza la lista dei file/directory nella directory corrente o nel path indicato.&lt;br /&gt;
** '''ls''' ''[-l]'' : visualizza la lista estesa (privilegi, n* hard link, proprietario, dimensione, ultima modifica, nome file/directory)  dei file/directory nella directory corrente.&lt;br /&gt;
* '''pwd''' : (print working directory) visualizza il percorso della directory corrente. &lt;br /&gt;
* '''cd''' ''[path]'' :  (change directory) entra nella directory specificata da ''path'' altrimenti torna al root dell'utente.&lt;br /&gt;
* '''rm''' ''file'' : (remove) elimina ''file''.&lt;br /&gt;
** '''rm''' ''[-Rf]'' ''file/path'' : elimina in modo ricorsivo e forzato i file e le directory nel ''path'' specificato.&lt;br /&gt;
* '''rmdir''' ''dir'' : (remove directory) elimina ''dir'' se vuota.&lt;br /&gt;
* '''mkdir''' ''dir'' : (make directory) crea la directory ''dir'' (può essere anche specificato un path).&lt;br /&gt;
* '''mv''' ''source'' ''dest'' : (move) muovi (o rinomina) il file ''source'' nel path ''dest''.&lt;br /&gt;
* '''touch''' ''file'' : crea ''file'' o se esiste già cambia la data di ultima modifica.&lt;br /&gt;
* '''ln''' ''target'' ''link'' : crea un link al file o directory ''target''.&lt;br /&gt;
** '''ln''' ''[-s]'' ''target'' ''link'' : (soft link) link simbolico.&lt;br /&gt;
** '''ln''' ''[-p]'' ''target'' ''link'' : (hard link) link fisico a file (non è possibile fare link a directory).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi di Gestione e Analisi Sistema:&lt;br /&gt;
&lt;br /&gt;
* '''ps ''' : (process status) visualizza il report dei processi attivi.&lt;br /&gt;
** '''pstree''' : visualizza l'albero dei processi attivi.&lt;br /&gt;
* '''df''' : (disk free) visualizza lo spazio occupato del disco dai file di sistema.&lt;br /&gt;
* '''du''' : (disk usage) visualizza una stima dell'utilizzo del disco di ogni singolo file/directory.&lt;br /&gt;
* '''groupadd''' ''group'' : crea il nuovo gruppo ''group''.&lt;br /&gt;
* '''useradd''' ''username'' : crea il nuovo utente ''username''.&lt;br /&gt;
* '''adduser''' ''username'' : crea il nuovo utente ''username'' (in maniera più veloce).&lt;br /&gt;
* '''groupdel''' ''group'' : elimina il gruppo indicato.&lt;br /&gt;
* '''userdel''' ''username'': elimina l'utente indicato.&lt;br /&gt;
* '''deluser''' ''username'': elimina l'utente indicato (in maniera più veloce).&lt;br /&gt;
* '''chmod''' ''par'' ''file'' : (change mode) modifica i privilegi di ''file'' tramite i valori/caratteri di ''par''.&lt;br /&gt;
* '''chown''' ''file'' : (change owner) cambia il proprietario e il gruppo di ''file''.&lt;br /&gt;
* '''chgrp''' ''group'' ''file'' : (change group) cambia il gruppo di ''file'' in ''group''.&lt;br /&gt;
* '''su''' ''[username]'' : (switch user) cambia utente.&lt;br /&gt;
* '''whoami''' : visualizza l'utente che usa il comando.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi Ctrl:&lt;br /&gt;
&lt;br /&gt;
* '''^S''' : sospende la visualizzazione.&lt;br /&gt;
* '''^Q''' : riattiva la visualizzazione.&lt;br /&gt;
* '''^C''' : cancella un'operazione.&lt;br /&gt;
* '''^D''' : fine del file.&lt;br /&gt;
* '''^V''' : tratta il carattere di controllo sequenze come se fosse carattere normale.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi Vari:&lt;br /&gt;
&lt;br /&gt;
* '''true''' : restituisce 0.&lt;br /&gt;
* '''false''' : restituisce 1.&lt;br /&gt;
* '''od''' ''[file]'' : stampa una rappresentazione in base ottale di ''file'' (esadecimale con -x).&lt;br /&gt;
* '''kill''' ''pid'' : termina il processo con id ''pid''.&lt;br /&gt;
* '''errno''' : (error number)  ultimo errore restituito.&lt;br /&gt;
* '''strerror''' : (string error) stringa corrispondente all'ultimo errore.&lt;br /&gt;
* '''echo''' ''string'' : stampa a video ''string''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[User:Ferra1993|Ferra1993]] ([[User talk:Ferra1993|talk]]) 17:45, 7 November 2013 (CET)&lt;br /&gt;
| [[User:Fede|Fede]] ([[User talk:Fede|talk]]) 17:49, 7 November 2013 (CET)&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Python_Programma_tieni_punteggio.&amp;diff=200</id>
		<title>Python Programma tieni punteggio.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Python_Programma_tieni_punteggio.&amp;diff=200"/>
		<updated>2013-11-12T11:27:31Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ho voglia di organizzare un torneo di 105, per chi non lo conoscesse e` il gioco che ha ispirato UNO solamente un po' piu complesso.&lt;br /&gt;
Ma, prima di poterci giocare avevo intenzione di fare un programma in python il cui scopo &amp;amp;egrave; quello di tenere il punteggio del torneo e, all`occorrenza, quello di crearmi un file.txt con tutti i nomi dei partecipanti e i relativi punteggi, in ordine decrescente.&lt;br /&gt;
Ovviamente in qualsiasi momento si dovra poter aggiungere un partecipante, diminuirne o aumentarne il punteggio, eliminarlo dal torneo.&lt;br /&gt;
Il programma che ho in mente non e specializzato per il centocinque ma &amp;amp;egrave; un generico &amp;quot;tieni punteggio metti in ordine decrescente e scrivi file nel formato &amp;quot;NOME GIOCATORE \t\t PUNTEGGIO&amp;quot;&amp;quot; per cos&amp;amp;igrave; dire.&lt;br /&gt;
Ecco come mi immagino la struttura del programma (ma che probabilmente fara schifo perche non ho mai fatto niente di utile): &lt;br /&gt;
* Una directory con dentro dei file.py ciascuno dei quali grazie alla libreria 'pickle' interagisce con un file che sar&amp;amp;agrave; appunto info.pck e, ciascuno dei quali ha un compito ben preciso: sorting decrescente, generare il file.txt, aggiungere un partecipante, rimuovere un partecipante, etc...&lt;br /&gt;
* Ciascuno di questi file python poi verr&amp;amp;agrave; interpellato dall`utente direttamente da console tramite degli script posti in /usr/bin.&lt;br /&gt;
Ho deciso di usare questa implementazione cosi che semmai volessi aggiungere qualche nuova feature al programma, non dovro mai modificare n&amp;amp;eacute; i vecchi script n&amp;amp;eacute; i file.py ma dovr&amp;amp;ograve; semplicemente creare le nuove feature e farle interagire con il file.pck.&lt;br /&gt;
Prima di andare avanti volevo qualche opinione o consiglio riguardo alla struttura sopra descritta, ed eventualmente migliorie o magari una struttura completamente diversa.&lt;br /&gt;
*Fede&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Questo esempio ci apre sicuramente spunti di riflessione sulla persistenza: interessante!&amp;lt;br/&amp;gt;&lt;br /&gt;
Aggiungo qualche idea...&amp;lt;br/&amp;gt;&lt;br /&gt;
Le operazioni che si ipotizzano sui partecipanti sono le CRUD: necessarie. Per usabilità aggiungerei anche qualche operazioni per elencare o ricercare i partecipanti già inseriti.&lt;br /&gt;
Al fine di distinguere partecipanti omonimi si potrebbe pensare di creare un'astrazione specifica di &amp;quot;Partecipante&amp;quot; (verso l'OOP), così da caratterizzarlo ulteriormente (ID?, data iscrizione al torneo?...tutto quello che ci viene in mente...).&lt;br /&gt;
Per la parte di (de)serializzazione si utilizza pikle: interessante &amp;quot;guardare&amp;quot; dentro al file serializzato o, eventualmente, provare a creare una nostra libreria di serializzazione: attenzione agli oggetti che, anche indirettamente, hanno riferimenti a se stesso!&amp;lt;br/&amp;gt;&lt;br /&gt;
am_20131112&amp;lt;br/&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
*Primo modulo.py, Starter.py:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt; import pickle&lt;br /&gt;
scelta = 'y'&lt;br /&gt;
infotorneo  = {}&lt;br /&gt;
while scelta == 'y':&lt;br /&gt;
	a = raw_input(&amp;quot;Nome Giocatore:&amp;quot; ) #a = input(&amp;quot;Nome Giocatore:&amp;quot; )&lt;br /&gt;
	infotorneo[a] = 0 #Inizialmente nel torneo tutti hanno punteggio 0.&lt;br /&gt;
	scelta = raw_input(&amp;quot;Vuoi inserire altri Giocatori? (y/n)&amp;quot; ) #scelta = input(&amp;quot;Vuoi inserire altri Giocatori? (y/n)&amp;quot; )&lt;br /&gt;
	while (scelta != 'y' and scelta != 'n'):&lt;br /&gt;
		scelta = raw_input(&amp;quot;Specificare y/n&amp;quot; ) #scelta = input(&amp;quot;Specificare y/n&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;w&amp;quot;)&lt;br /&gt;
pickle.dump(infotorneo, f)&lt;br /&gt;
f.close() &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*il modulo cambiapunteggiodi.py, poi gli mettero un controllo per verificare l`esistenza di Giocatore:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt; import pickle&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;r&amp;quot;)&lt;br /&gt;
infotorneo = {}&lt;br /&gt;
infotorneo = pickle.load(f)&lt;br /&gt;
f.close()&lt;br /&gt;
scelta = 'y'&lt;br /&gt;
while (scelta == 'y'):&lt;br /&gt;
	Giocatore = raw_input(&amp;quot;Di chi vuoi cambiare il punteggio?&amp;quot; )&lt;br /&gt;
	NuovoPunteggio = raw_input(&amp;quot;Inserire nuovo punteggio.&amp;quot; )&lt;br /&gt;
	infotorneo[Giocatore] = NuovoPunteggio&lt;br /&gt;
	scelta = raw_input(&amp;quot;Vuoi cambiare il punteggio di un altro giocatore?(y/n)&amp;quot; )&lt;br /&gt;
	while(scelta != 'y' and scelta != 'n'):&lt;br /&gt;
		scelta = raw_input(&amp;quot;Specificare y/n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;w&amp;quot;)&lt;br /&gt;
pickle.dump(infotorneo, f)&lt;br /&gt;
f.close() &amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Python_Programma_tieni_punteggio.&amp;diff=199</id>
		<title>Python Programma tieni punteggio.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Python_Programma_tieni_punteggio.&amp;diff=199"/>
		<updated>2013-11-12T11:26:30Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ho voglia di organizzare un torneo di 105, per chi non lo conoscesse e` il gioco che ha ispirato UNO solamente un po' piu complesso.&lt;br /&gt;
Ma, prima di poterci giocare avevo intenzione di fare un programma in python il cui scopo &amp;amp;egrave; quello di tenere il punteggio del torneo e, all`occorrenza, quello di crearmi un file.txt con tutti i nomi dei partecipanti e i relativi punteggi, in ordine decrescente.&lt;br /&gt;
Ovviamente in qualsiasi momento si dovra poter aggiungere un partecipante, diminuirne o aumentarne il punteggio, eliminarlo dal torneo.&lt;br /&gt;
Il programma che ho in mente non e specializzato per il centocinque ma &amp;amp;egrave; un generico &amp;quot;tieni punteggio metti in ordine decrescente e scrivi file nel formato &amp;quot;NOME GIOCATORE \t\t PUNTEGGIO&amp;quot;&amp;quot; per cos&amp;amp;igrave; dire.&lt;br /&gt;
Ecco come mi immagino la struttura del programma (ma che probabilmente fara schifo perche non ho mai fatto niente di utile): &lt;br /&gt;
* Una directory con dentro dei file.py ciascuno dei quali grazie alla libreria 'pickle' interagisce con un file che sar&amp;amp;agrave; appunto info.pck e, ciascuno dei quali ha un compito ben preciso: sorting decrescente, generare il file.txt, aggiungere un partecipante, rimuovere un partecipante, etc...&lt;br /&gt;
* Ciascuno di questi file python poi verr&amp;amp;agrave; interpellato dall`utente direttamente da console tramite degli script posti in /usr/bin.&lt;br /&gt;
Ho deciso di usare questa implementazione cosi che semmai volessi aggiungere qualche nuova feature al programma, non dovro mai modificare n&amp;amp;eacute; i vecchi script n&amp;amp;eacute; i file.py ma dovr&amp;amp;ograve; semplicemente creare le nuove feature e farle interagire con il file.pck.&lt;br /&gt;
Prima di andare avanti volevo qualche opinione o consiglio riguardo alla struttura sopra descritta, ed eventualmente migliorie o magari una struttura completamente diversa.&lt;br /&gt;
*Fede&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Questo esempio ci apre sicuramente spunti di riflessione sulla persistenza: interessante!&lt;br /&gt;
Aggiungo qualche idea:&lt;br /&gt;
Le operazioni che si ipotizzano sui partecipanti sono le CRUD: necessarie. Per usabilità aggiungerei anche qualche operazioni per elencare o ricercare i partecipanti già inseriti.&lt;br /&gt;
Al fine di distinguere partecipanti omonimi si potrebbe pensare di creare un'astrazione specifica di &amp;quot;Partecipante&amp;quot; (verso l'OOP), così da caratterizzarlo ulteriormente (ID?, data iscrizione al torneo?...tutto quello che ci viene in mente...).&lt;br /&gt;
Per la parte di (de)serializzazione si utilizza pikle: interessante &amp;quot;guardare&amp;quot; dentro al file serializzato o, eventualmente, provare a creare una nostra libreria di serializzazione: attenzione agli oggetti che, anche indirettamente, hanno riferimenti a se stesso!&lt;br /&gt;
am_20131112&lt;br /&gt;
----&lt;br /&gt;
*Primo modulo.py, Starter.py:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt; import pickle&lt;br /&gt;
scelta = 'y'&lt;br /&gt;
infotorneo  = {}&lt;br /&gt;
while scelta == 'y':&lt;br /&gt;
	a = raw_input(&amp;quot;Nome Giocatore:&amp;quot; ) #a = input(&amp;quot;Nome Giocatore:&amp;quot; )&lt;br /&gt;
	infotorneo[a] = 0 #Inizialmente nel torneo tutti hanno punteggio 0.&lt;br /&gt;
	scelta = raw_input(&amp;quot;Vuoi inserire altri Giocatori? (y/n)&amp;quot; ) #scelta = input(&amp;quot;Vuoi inserire altri Giocatori? (y/n)&amp;quot; )&lt;br /&gt;
	while (scelta != 'y' and scelta != 'n'):&lt;br /&gt;
		scelta = raw_input(&amp;quot;Specificare y/n&amp;quot; ) #scelta = input(&amp;quot;Specificare y/n&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;w&amp;quot;)&lt;br /&gt;
pickle.dump(infotorneo, f)&lt;br /&gt;
f.close() &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*il modulo cambiapunteggiodi.py, poi gli mettero un controllo per verificare l`esistenza di Giocatore:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt; import pickle&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;r&amp;quot;)&lt;br /&gt;
infotorneo = {}&lt;br /&gt;
infotorneo = pickle.load(f)&lt;br /&gt;
f.close()&lt;br /&gt;
scelta = 'y'&lt;br /&gt;
while (scelta == 'y'):&lt;br /&gt;
	Giocatore = raw_input(&amp;quot;Di chi vuoi cambiare il punteggio?&amp;quot; )&lt;br /&gt;
	NuovoPunteggio = raw_input(&amp;quot;Inserire nuovo punteggio.&amp;quot; )&lt;br /&gt;
	infotorneo[Giocatore] = NuovoPunteggio&lt;br /&gt;
	scelta = raw_input(&amp;quot;Vuoi cambiare il punteggio di un altro giocatore?(y/n)&amp;quot; )&lt;br /&gt;
	while(scelta != 'y' and scelta != 'n'):&lt;br /&gt;
		scelta = raw_input(&amp;quot;Specificare y/n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;w&amp;quot;)&lt;br /&gt;
pickle.dump(infotorneo, f)&lt;br /&gt;
f.close() &amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Python_Programma_tieni_punteggio.&amp;diff=198</id>
		<title>Python Programma tieni punteggio.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Python_Programma_tieni_punteggio.&amp;diff=198"/>
		<updated>2013-11-12T11:25:33Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ho voglia di organizzare un torneo di 105, per chi non lo conoscesse e` il gioco che ha ispirato UNO solamente un po' piu complesso.&lt;br /&gt;
Ma, prima di poterci giocare avevo intenzione di fare un programma in python il cui scopo &amp;amp;egrave; quello di tenere il punteggio del torneo e, all`occorrenza, quello di crearmi un file.txt con tutti i nomi dei partecipanti e i relativi punteggi, in ordine decrescente.&lt;br /&gt;
Ovviamente in qualsiasi momento si dovra poter aggiungere un partecipante, diminuirne o aumentarne il punteggio, eliminarlo dal torneo.&lt;br /&gt;
Il programma che ho in mente non e specializzato per il centocinque ma &amp;amp;egrave; un generico &amp;quot;tieni punteggio metti in ordine decrescente e scrivi file nel formato &amp;quot;NOME GIOCATORE \t\t PUNTEGGIO&amp;quot;&amp;quot; per cos&amp;amp;igrave; dire.&lt;br /&gt;
Ecco come mi immagino la struttura del programma (ma che probabilmente fara schifo perche non ho mai fatto niente di utile): &lt;br /&gt;
* Una directory con dentro dei file.py ciascuno dei quali grazie alla libreria 'pickle' interagisce con un file che sar&amp;amp;agrave; appunto info.pck e, ciascuno dei quali ha un compito ben preciso: sorting decrescente, generare il file.txt, aggiungere un partecipante, rimuovere un partecipante, etc...&lt;br /&gt;
* Ciascuno di questi file python poi verr&amp;amp;agrave; interpellato dall`utente direttamente da console tramite degli script posti in /usr/bin.&lt;br /&gt;
Ho deciso di usare questa implementazione cosi che semmai volessi aggiungere qualche nuova feature al programma, non dovro mai modificare n&amp;amp;eacute; i vecchi script n&amp;amp;eacute; i file.py ma dovr&amp;amp;ograve; semplicemente creare le nuove feature e farle interagire con il file.pck.&lt;br /&gt;
Prima di andare avanti volevo qualche opinione o consiglio riguardo alla struttura sopra descritta, ed eventualmente migliorie o magari una struttura completamente diversa.&lt;br /&gt;
*Fede&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
Questo esempio ci apre sicuramente spunti di riflessione sulla persistenza: interessante!&lt;br /&gt;
Aggiungo qualche idea:&lt;br /&gt;
Le operazioni che si ipotizzano sui partecipanti sono le CRUD: necessarie. Per usabilità aggiungerei anche qualche operazioni per elencare o ricercare i partecipanti già inseriti.&lt;br /&gt;
Al fine di distinguere partecipanti omonimi si potrebbe pensare di creare un'astrazione specifica di &amp;quot;Partecipante&amp;quot; (verso l'OOP), così da caratterizzarlo ulteriormente (ID?, data iscrizione al torneo?...tutto quello che ci viene in mente...).&lt;br /&gt;
Per la parte di (de)serializzazione si utilizza pikle: interessante &amp;quot;guardare&amp;quot; dentro al file serializzato o, eventualmente, provare a creare una nostra libreria di serializzazione: attenzione agli oggetti che, anche indirettamente, hanno riferimenti a se stesso!&lt;br /&gt;
am_20131112&lt;br /&gt;
----&lt;br /&gt;
*Primo modulo.py, Starter.py:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt; import pickle&lt;br /&gt;
scelta = 'y'&lt;br /&gt;
infotorneo  = {}&lt;br /&gt;
while scelta == 'y':&lt;br /&gt;
	a = raw_input(&amp;quot;Nome Giocatore:&amp;quot; ) #a = input(&amp;quot;Nome Giocatore:&amp;quot; )&lt;br /&gt;
	infotorneo[a] = 0 #Inizialmente nel torneo tutti hanno punteggio 0.&lt;br /&gt;
	scelta = raw_input(&amp;quot;Vuoi inserire altri Giocatori? (y/n)&amp;quot; ) #scelta = input(&amp;quot;Vuoi inserire altri Giocatori? (y/n)&amp;quot; )&lt;br /&gt;
	while (scelta != 'y' and scelta != 'n'):&lt;br /&gt;
		scelta = raw_input(&amp;quot;Specificare y/n&amp;quot; ) #scelta = input(&amp;quot;Specificare y/n&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;w&amp;quot;)&lt;br /&gt;
pickle.dump(infotorneo, f)&lt;br /&gt;
f.close() &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*il modulo cambiapunteggiodi.py, poi gli mettero un controllo per verificare l`esistenza di Giocatore:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt; import pickle&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;r&amp;quot;)&lt;br /&gt;
infotorneo = {}&lt;br /&gt;
infotorneo = pickle.load(f)&lt;br /&gt;
f.close()&lt;br /&gt;
scelta = 'y'&lt;br /&gt;
while (scelta == 'y'):&lt;br /&gt;
	Giocatore = raw_input(&amp;quot;Di chi vuoi cambiare il punteggio?&amp;quot; )&lt;br /&gt;
	NuovoPunteggio = raw_input(&amp;quot;Inserire nuovo punteggio.&amp;quot; )&lt;br /&gt;
	infotorneo[Giocatore] = NuovoPunteggio&lt;br /&gt;
	scelta = raw_input(&amp;quot;Vuoi cambiare il punteggio di un altro giocatore?(y/n)&amp;quot; )&lt;br /&gt;
	while(scelta != 'y' and scelta != 'n'):&lt;br /&gt;
		scelta = raw_input(&amp;quot;Specificare y/n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
f = open(&amp;quot;.info.pck&amp;quot;,&amp;quot;w&amp;quot;)&lt;br /&gt;
pickle.dump(infotorneo, f)&lt;br /&gt;
f.close() &amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=170</id>
		<title>SYS CALL viste a lezione.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=170"/>
		<updated>2013-11-10T08:40:45Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FORK&lt;br /&gt;
Crea un nuovo processo duplicando il processo chiamante. Il nuovo processo , chiamato figlio, é un duplicato esatto del processo chiamante , chiamato padre. &lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){     &lt;br /&gt;
	if(fork()){&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() ); // getpid() stampa il pid del processo corrente , getppid() stampa il pid del processo padre&lt;br /&gt;
        sleep(2);}   //se togliessimo lo sleep;il processo figlio stamperebbe come getppid() 1,perché essendo il padre terminato e lui rimasto orfano,il nuovo padre diventa init&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2(una piccola osservazione sull'eredità del buffer):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	printf(&amp;quot;cucù! : &amp;quot;);      //notare la differenza se nella sringa metto \n &lt;br /&gt;
	if(fork())&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() );&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio3(fork e malloc):&amp;lt;br/&amp;gt;&lt;br /&gt;
(sottolineerei che lo spazio di indirizzamento è di fatto separato: i due processi hanno una analoga visione dell'indirizzamento logico, che però è specifico di ogni processo e i dati sono memorizzati fisicamente in aree di memoria diverse. am_20131110)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	int *p;&lt;br /&gt;
	if( fork() ){&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	*p = 45;&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());   &lt;br /&gt;
	sleep(2);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());  //i puntatori restituiranno lo stesso indirizzo di memoria sia per il padre che per il figlio perché condividono lo stesso spazio di indirizzamento&lt;br /&gt;
	sleep(1);&lt;br /&gt;
	}&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* WAIT&lt;br /&gt;
Aspetta che un processo cambi di stato.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
                sleep(10); &lt;br /&gt;
		waitpid(pid,status,0);&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;,WEXITSTATUS(status));&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		exit(1);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,status,0);&lt;br /&gt;
		if (WIFEXITED(status))&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if(WIFSIGNALED(status) )&lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) );&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		int *p;&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		p = (int *)42;&lt;br /&gt;
		*p = 43;	&lt;br /&gt;
		exit(2);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Correggetemi se ho scritto delle sciocchezze.&lt;br /&gt;
(Pirata)&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=169</id>
		<title>SYS CALL viste a lezione.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=SYS_CALL_viste_a_lezione.&amp;diff=169"/>
		<updated>2013-11-10T08:40:10Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FORK&lt;br /&gt;
Crea un nuovo processo duplicando il processo chiamante. Il nuovo processo , chiamato figlio, é un duplicato esatto del processo chiamante , chiamato padre. &lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){     &lt;br /&gt;
	if(fork()){&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() ); // getpid() stampa il pid del processo corrente , getppid() stampa il pid del processo padre&lt;br /&gt;
        sleep(2);}   //se togliessimo lo sleep;il processo figlio stamperebbe come getppid() 1,perché essendo il padre terminato e lui rimasto orfano,il nuovo padre diventa init&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio2(una piccola osservazione sull'eredità del buffer):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	printf(&amp;quot;cucù! : &amp;quot;);      //notare la differenza se nella sringa metto \n &lt;br /&gt;
	if(fork())&lt;br /&gt;
	printf(&amp;quot;uno  %d  %d \n&amp;quot;, getpid(), getppid() );&lt;br /&gt;
	else&lt;br /&gt;
	printf(&amp;quot;due %d %d  \n&amp;quot;,getpid(), getppid() );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
esempio3(fork e malloc):&lt;br /&gt;
(sottolineerei che lo spazio di indirizzamento è di fatto separato: i due processi hanno una analoga visione dell'indirizzamento logico, che però è specifico di ogni processo e i dati sono memorizzati fisicamente in aree di memoria diverse. am_20131110)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main (void){&lt;br /&gt;
	int *p;&lt;br /&gt;
	if( fork() ){&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	*p = 45;&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());   &lt;br /&gt;
	sleep(2);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
	p = malloc(sizeof(int));&lt;br /&gt;
	printf(&amp;quot;%d %p  pid : %d  , ppid : %d \n&amp;quot;,*p,p,getpid(),getppid());  //i puntatori restituiranno lo stesso indirizzo di memoria sia per il padre che per il figlio perché condividono lo stesso spazio di indirizzamento&lt;br /&gt;
	sleep(1);&lt;br /&gt;
	}&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* WAIT&lt;br /&gt;
Aspetta che un processo cambi di stato.&lt;br /&gt;
&lt;br /&gt;
esempio1:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
                sleep(10); &lt;br /&gt;
		waitpid(pid,status,0);&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;,WEXITSTATUS(status));&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		exit(1);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
esempio2:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]){&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	if( pid = fork() ){&lt;br /&gt;
		int status;&lt;br /&gt;
		printf(&amp;quot; padre : %d  figlio : %d \n&amp;quot;,getpid(),pid);&lt;br /&gt;
		sleep(5);&lt;br /&gt;
		waitpid(pid,status,0);&lt;br /&gt;
		if (WIFEXITED(status))&lt;br /&gt;
		printf(&amp;quot; exit status %d \n&amp;quot;, WEXITSTATUS(status));&lt;br /&gt;
		else if(WIFSIGNALED(status) )&lt;br /&gt;
			printf(&amp;quot;signal : %d \n&amp;quot;, WTERMSIG(status) );&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		int *p;&lt;br /&gt;
		printf(&amp;quot; figlio : %d  padre : %d \n&amp;quot;,getpid(),getppid());&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		p = (int *)42;&lt;br /&gt;
		*p = 43;	&lt;br /&gt;
		exit(2);&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Correggetemi se ho scritto delle sciocchezze.&lt;br /&gt;
(Pirata)&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=149</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=149"/>
		<updated>2013-11-08T10:05:58Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questo &amp;amp;egrave; il Wiki del Corso di Sistemi Operativi&lt;br /&gt;
&lt;br /&gt;
[[Esercizi a caso del Prof.]]&lt;br /&gt;
&lt;br /&gt;
[[Python Programma tieni punteggio.]]&lt;br /&gt;
&lt;br /&gt;
[[Comandi visti alle lezioni.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Ricordate che per creare un account o quando viene richiesto di risolvere un semplice calcolo occorre ricordare quanto scritto [[qui]]&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Commandi_visti_alle_lezioni.&amp;diff=148</id>
		<title>Commandi visti alle lezioni.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Commandi_visti_alle_lezioni.&amp;diff=148"/>
		<updated>2013-11-08T10:05:36Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: Amonaldini moved page Commandi visti alle lezioni. to Comandi visti alle lezioni.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Comandi visti alle lezioni.]]&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Comandi_visti_alle_lezioni.&amp;diff=147</id>
		<title>Comandi visti alle lezioni.</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Comandi_visti_alle_lezioni.&amp;diff=147"/>
		<updated>2013-11-08T10:05:36Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: Amonaldini moved page Commandi visti alle lezioni. to Comandi visti alle lezioni.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;mi sembra una buon idea fare una tabellina con commandi importanti visti alle lezioni, e una breve descrizione di che fanno e che parametri ricevono. non ne ho tutti scritti, allora mi raccomando- aggiungete pure!&lt;br /&gt;
&lt;br /&gt;
ps- e' possibile fare una tabella?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
at&lt;br /&gt;
&lt;br /&gt;
cat- concatenare file&lt;br /&gt;
&lt;br /&gt;
chmod- cambia mode&lt;br /&gt;
&lt;br /&gt;
echo- stampa il testo&lt;br /&gt;
&lt;br /&gt;
false- non fa niente&lt;br /&gt;
&lt;br /&gt;
ln- linka tra due file (-s crea il link simbolico)&lt;br /&gt;
&lt;br /&gt;
mkdir- crea una cartella&lt;br /&gt;
&lt;br /&gt;
nologin- prevenire unpriviliggiati utenti di loggare al sistema&lt;br /&gt;
&lt;br /&gt;
od&lt;br /&gt;
&lt;br /&gt;
pwd- stampa l'indirizzio alla cartella in cui sono&lt;br /&gt;
&lt;br /&gt;
touch- crea un file&lt;br /&gt;
&lt;br /&gt;
true- non fa niente&lt;br /&gt;
&lt;br /&gt;
umask&lt;br /&gt;
&lt;br /&gt;
whoami- stampa l'id dell'utente&lt;br /&gt;
&lt;br /&gt;
su- swicth user&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Daniele F. &amp;amp; Federico A.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Abbiamo messo qualche comando con relativa descrizione, speriamo vi possano aiutare e che non ci siano troppi errori.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Informazioni e Aiuti: &lt;br /&gt;
&lt;br /&gt;
* '''man''' ''file'' : (manual) apre il manuale, se esiste, alla pagina relativa a ''file''.&lt;br /&gt;
** '''man''' ''[-k]'' ''file'' : elenca tutte le pagine di manuale con la parola ''file''.&lt;br /&gt;
** '''man''' ''[n]'' ''file'' : apre la pagina relativa a ''file(n)''; (p.e. ''man 2 open'' apre la pagina relativa alla funzione (2) open).&lt;br /&gt;
* '''info''' ''file'' : apre il documento informativo relativo a 'file'.&lt;br /&gt;
* '''help''' ''[file]'' : visualizza alcuni comandi utili o informazioni su ''file''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi per Cartelle e File:&lt;br /&gt;
&lt;br /&gt;
* '''ls''' ''[path]'' : (list) visualizza la lista dei file/directory nella directory corrente o nel path indicato.&lt;br /&gt;
** '''ls''' ''[-l]'' : visualizza la lista estesa (privilegi, n* hard link, proprietario, dimensione, ultima modifica, nome file/directory)  dei file/directory nella directory corrente.&lt;br /&gt;
* '''pwd''' : (print working directory) visualizza il percorso della directory corrente. &lt;br /&gt;
* '''cd''' ''[path]'' :  (change directory) entra nella directory specificata da ''path'' altrimenti torna al root dell'utente.&lt;br /&gt;
* '''rm''' ''file/dir'' : (remove) elimina ''file/dir''.&lt;br /&gt;
** '''rm''' ''[-Rf]'' ''file/path'' : elimina in modo ricorsivo e forzato i file e le directory nel ''path'' specificato.&lt;br /&gt;
* '''rmdir''' ''dir'' : (remove directory) elimina ''dir'' se vuota.&lt;br /&gt;
* '''mkdir''' ''dir'' : (make directory) crea la directory ''dir'' (può essere anche specificato un path).&lt;br /&gt;
* '''mv''' ''source'' ''dest'' : (move) muovi (o rinomina) il file ''source'' nel path ''dest''.&lt;br /&gt;
* '''touch''' ''file'' : crea ''file'' o se esiste già cambia la data di ultima modifica.&lt;br /&gt;
* '''ln''' ''target'' ''link'' : crea un link al file o directory ''target''.&lt;br /&gt;
** '''ln''' ''[-s]'' ''target'' ''link'' : (soft link) link simbolico.&lt;br /&gt;
** '''ln''' ''[-p]'' ''target'' ''link'' : (hard link) link fisico a file (non è possibile fare link a directory).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi di Gestione e Analisi Sistema:&lt;br /&gt;
&lt;br /&gt;
* '''ps ''' : (process status) visualizza il report dei processi attivi.&lt;br /&gt;
** '''pstree''' : visualizza l'albero dei processi attivi.&lt;br /&gt;
* '''df''' : (disk free) visualizza lo spazio occupato del disco dai file di sistema.&lt;br /&gt;
* '''du''' : (disk usage) visualizza una stima dell'utilizzo del disco di ogni singolo file/directory.&lt;br /&gt;
* '''groupadd''' ''group'' : crea il nuovo gruppo ''group''.&lt;br /&gt;
* '''useradd''' ''username'' : crea il nuovo utente ''username''.&lt;br /&gt;
* '''adduser''' ''username'' : crea il nuovo utente ''username'' (in maniera più veloce).&lt;br /&gt;
* '''groupdel''' ''group'' : elimina il gruppo indicato.&lt;br /&gt;
* '''userdel''' ''username'': elimina l'utente indicato.&lt;br /&gt;
* '''deluser''' ''username'': elimina l'utente indicato (in maniera più veloce).&lt;br /&gt;
* '''chmod''' ''par'' ''file'' : (change mode) modifica i privilegi di ''file'' tramite i valori/caratteri di ''par''.&lt;br /&gt;
* '''chown''' ''file'' : (change owner) cambia il proprietario e il gruppo di ''file''.&lt;br /&gt;
* '''chgrp''' ''group'' ''file'' : (change group) cambia il gruppo di ''file'' in ''group''.&lt;br /&gt;
* '''su''' ''[username]'' : (switch user) cambia utente.&lt;br /&gt;
* '''whoami''' : visualizza l'utente che usa il comando.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi Ctrl:&lt;br /&gt;
&lt;br /&gt;
* '''^S''' : sospende la visualizzazione.&lt;br /&gt;
* '''^Q''' : riattiva la visualizzazione.&lt;br /&gt;
* '''^C''' : cancella un'operazione.&lt;br /&gt;
* '''^D''' : fine del file.&lt;br /&gt;
* '''^V''' : tratta il carattere di controllo sequenze come se fosse carattere normale.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Comandi Vari:&lt;br /&gt;
&lt;br /&gt;
* '''true''' : restituisce 0.&lt;br /&gt;
* '''false''' : restituisce 1.&lt;br /&gt;
* '''kill''' ''pid'' : termina il processo con id ''pid''.&lt;br /&gt;
* '''errno''' : (error number)  ultimo errore restituito.&lt;br /&gt;
* '''strerror''' : (string error) stringa corrispondente all'ultimo errore.&lt;br /&gt;
* '''echo''' ''string'' : stampa a video ''string''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[User:Ferra1993|Ferra1993]] ([[User talk:Ferra1993|talk]]) 17:45, 7 November 2013 (CET)&lt;br /&gt;
| [[User:Fede|Fede]] ([[User talk:Fede|talk]]) 17:49, 7 November 2013 (CET)&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=146</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=146"/>
		<updated>2013-11-08T10:05:21Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: Undo revision 145 by Amonaldini (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questo &amp;amp;egrave; il Wiki del Corso di Sistemi Operativi&lt;br /&gt;
&lt;br /&gt;
[[Esercizi a caso del Prof.]]&lt;br /&gt;
&lt;br /&gt;
[[Python Programma tieni punteggio.]]&lt;br /&gt;
&lt;br /&gt;
[[Commandi visti alle lezioni.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Ricordate che per creare un account o quando viene richiesto di risolvere un semplice calcolo occorre ricordare quanto scritto [[qui]]&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=145</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=145"/>
		<updated>2013-11-08T10:01:43Z</updated>

		<summary type="html">&lt;p&gt;Amonaldini: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questo &amp;amp;egrave; il Wiki del Corso di Sistemi Operativi&lt;br /&gt;
&lt;br /&gt;
[[Esercizi a caso del Prof.]]&lt;br /&gt;
&lt;br /&gt;
[[Python Programma tieni punteggio.]]&lt;br /&gt;
&lt;br /&gt;
[[Comandi visti alle lezioni.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Ricordate che per creare un account o quando viene richiesto di risolvere un semplice calcolo occorre ricordare quanto scritto [[qui]]&lt;/div&gt;</summary>
		<author><name>Amonaldini</name></author>
	</entry>
</feed>