<?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=Aula</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=Aula"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php/Special:Contributions/Aula"/>
	<updated>2026-06-21T15:42:23Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=ProvaPratica_2013.07.18&amp;diff=712</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=712"/>
		<updated>2014-05-12T15:36:56Z</updated>

		<summary type="html">&lt;p&gt;Aula: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Esercizio 1 ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&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 1&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;
#include &amp;lt;errno.h&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;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Constants&lt;br /&gt;
#define MaxNumArguments 10&lt;br /&gt;
#define MaxLenArguments 50&lt;br /&gt;
#define MaxLenPath 100&lt;br /&gt;
#define MaxLenLine MaxLenArguments * MaxNumArguments&lt;br /&gt;
#define MaxLenCommands 500&lt;br /&gt;
&lt;br /&gt;
// Structure for a process element&lt;br /&gt;
typedef struct processElem&lt;br /&gt;
{&lt;br /&gt;
	char CommandLine[MaxLenCommands];&lt;br /&gt;
	pid_t Pid;&lt;br /&gt;
	struct processElem *Next;&lt;br /&gt;
} ProcessElem;&lt;br /&gt;
&lt;br /&gt;
// Function prototypes&lt;br /&gt;
ProcessElem *appendElement    (ProcessElem *tail);&lt;br /&gt;
char        *findCommand      (pid_t pid);&lt;br /&gt;
void         countTokens      (const char *string, const char delimiter, int *count, int *longest);&lt;br /&gt;
int          tokenize         (char *string, char delimiter, char ***tokens, int *count);&lt;br /&gt;
void         readMultipleLines(void);&lt;br /&gt;
void         runProcesses     (void);&lt;br /&gt;
&lt;br /&gt;
// Global variables&lt;br /&gt;
static ProcessElem *ProcessList  = NULL;&lt;br /&gt;
int                 ProcessCount = 0;&lt;br /&gt;
&lt;br /&gt;
// Given a PID retrieve the relative command&lt;br /&gt;
char *findCommand(pid_t pid)&lt;br /&gt;
{&lt;br /&gt;
	ProcessElem *process;&lt;br /&gt;
	for(process = ProcessList; process-&amp;gt;Pid != pid; process = process-&amp;gt;Next);&lt;br /&gt;
	return (process)? (process-&amp;gt;CommandLine) : (NULL);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Create a new element&lt;br /&gt;
ProcessElem *appendElement(ProcessElem *tail)&lt;br /&gt;
{&lt;br /&gt;
	ProcessElem *newElem = (ProcessElem *)malloc(sizeof(ProcessElem));&lt;br /&gt;
	newElem-&amp;gt;Next = NULL;&lt;br /&gt;
	(tail)? (tail-&amp;gt;Next = newElem) : (tail = newElem);&lt;br /&gt;
	return newElem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Count tokens and find the longest one&lt;br /&gt;
 * Example:&lt;br /&gt;
 *    Input:&lt;br /&gt;
 *       string = &amp;quot;ping -c 4 google.com&amp;quot;&lt;br /&gt;
 *       delimiter = ' '&lt;br /&gt;
 *    Output:&lt;br /&gt;
 *       count = 4&lt;br /&gt;
 *       longest = 10&lt;br /&gt;
 */&lt;br /&gt;
void countTokens(const char *string, const char delimiter, int *count, int *longest)&lt;br /&gt;
{&lt;br /&gt;
	int iterator, lenght;&lt;br /&gt;
	lenght = *longest = *count = 0;&lt;br /&gt;
&lt;br /&gt;
	// Count the first (n - 1) tokens&lt;br /&gt;
	for(iterator = 0; string[iterator]; iterator++)&lt;br /&gt;
	{&lt;br /&gt;
		if(string[iterator] == delimiter)&lt;br /&gt;
		{&lt;br /&gt;
			if(*longest &amp;lt; lenght)&lt;br /&gt;
				*longest = lenght;&lt;br /&gt;
			lenght = 0;&lt;br /&gt;
			(*count)++;&lt;br /&gt;
		}&lt;br /&gt;
		lenght++;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Count the last token&lt;br /&gt;
	if(string[iterator - 1] != delimiter)&lt;br /&gt;
	{&lt;br /&gt;
		lenght--;&lt;br /&gt;
		if(*longest &amp;lt; lenght)&lt;br /&gt;
			*longest = lenght;&lt;br /&gt;
		(*count)++;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Tokenize a string accordingly to a given delimiter&lt;br /&gt;
 * Example:&lt;br /&gt;
 *    Input:&lt;br /&gt;
 *       string = &amp;quot;ping -c 4 google.com&amp;quot;&lt;br /&gt;
 *       delimiter = ' '&lt;br /&gt;
 *    Output:&lt;br /&gt;
 *       tokens = [&amp;quot;ping&amp;quot;, &amp;quot;-c&amp;quot;, &amp;quot;4&amp;quot;, &amp;quot;google.com&amp;quot;]&lt;br /&gt;
 *       count = 4&lt;br /&gt;
 */&lt;br /&gt;
int tokenize(char *string, char delimiter, char ***tokens, int *count)&lt;br /&gt;
{&lt;br /&gt;
	if(!(tokens &amp;amp;&amp;amp; string &amp;amp;&amp;amp; count)) return 0;&lt;br /&gt;
&lt;br /&gt;
	int token, i, j, longest;&lt;br /&gt;
	*count = longest = 0;&lt;br /&gt;
&lt;br /&gt;
	countTokens(string, delimiter, count, &amp;amp;longest);&lt;br /&gt;
&lt;br /&gt;
	// Allocate space for array of strings&lt;br /&gt;
	*tokens = (char **)malloc(*count * sizeof(char *));&lt;br /&gt;
&lt;br /&gt;
	if(!*tokens)&lt;br /&gt;
	{&lt;br /&gt;
		perror(&amp;quot;malloc()&amp;quot;);&lt;br /&gt;
		exit(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Allocate space for each string in the array and tokenize it&lt;br /&gt;
	i = 0;&lt;br /&gt;
	for(token = 0; token &amp;lt; *count; token++)&lt;br /&gt;
	{&lt;br /&gt;
		(*tokens)[token] = (char *)malloc(sizeof(char) * (longest + 1));&lt;br /&gt;
&lt;br /&gt;
		j = 0;&lt;br /&gt;
		while(string[i] != delimiter &amp;amp;&amp;amp; string[i])&lt;br /&gt;
		{&lt;br /&gt;
			(*tokens)[token][j] = string[i];&lt;br /&gt;
			j++;&lt;br /&gt;
			i++;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Null-terminated string&lt;br /&gt;
		(*tokens)[token][j] = (char)0;&lt;br /&gt;
		i++;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Read multiple input lines&lt;br /&gt;
void readMultipleLines(void)&lt;br /&gt;
{&lt;br /&gt;
	ProcessElem *process = NULL;&lt;br /&gt;
	char input[MaxLenLine];&lt;br /&gt;
	char *iterator;&lt;br /&gt;
&lt;br /&gt;
	printf(&amp;quot;Enter commands. Press enter on blank line to start them.\n&amp;quot;);&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		// Get input string&lt;br /&gt;
		if(!fgets(input, MaxLenLine, stdin))&lt;br /&gt;
		{&lt;br /&gt;
			perror(&amp;quot;fgets()&amp;quot;);&lt;br /&gt;
			exit(EXIT_FAILURE);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Skip blank lines&lt;br /&gt;
		for(iterator = input; *iterator == ' '; iterator++);&lt;br /&gt;
&lt;br /&gt;
		// Check if enter was pressed on blank line&lt;br /&gt;
		if(*iterator == '\n') break;&lt;br /&gt;
&lt;br /&gt;
		// Append a new input element&lt;br /&gt;
		if(!(ProcessList))&lt;br /&gt;
			process = ProcessList = appendElement(ProcessList);&lt;br /&gt;
		else&lt;br /&gt;
		{&lt;br /&gt;
			process-&amp;gt;Next = appendElement(process);&lt;br /&gt;
			process = process-&amp;gt;Next;&lt;br /&gt;
		}&lt;br /&gt;
		ProcessCount++;&lt;br /&gt;
&lt;br /&gt;
		// Eliminate &amp;quot;\n&amp;quot; from the input string&lt;br /&gt;
		iterator = strtok(iterator, &amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		strcpy(process-&amp;gt;CommandLine, iterator);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Run child processes -&amp;gt;&lt;br /&gt;
 * Print when a child process terminates&lt;br /&gt;
 */&lt;br /&gt;
void runProcesses(void)&lt;br /&gt;
{&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
	int status, terminated, count;&lt;br /&gt;
	char path[MaxLenPath];&lt;br /&gt;
	ProcessElem *process = ProcessList;&lt;br /&gt;
	char **command = NULL;&lt;br /&gt;
	terminated = count = 0;&lt;br /&gt;
&lt;br /&gt;
	// Start processes&lt;br /&gt;
	while(process)&lt;br /&gt;
	{&lt;br /&gt;
		// Tokenize command line&lt;br /&gt;
		tokenize(process-&amp;gt;CommandLine, ' ', &amp;amp;command, &amp;amp;count);&lt;br /&gt;
&lt;br /&gt;
		// Create path&lt;br /&gt;
		snprintf(path, sizeof path, &amp;quot;%s%s&amp;quot;, &amp;quot;/bin/&amp;quot;, command[0]);&lt;br /&gt;
&lt;br /&gt;
		// Create child process&lt;br /&gt;
		pid = fork();&lt;br /&gt;
&lt;br /&gt;
		// Check PID&lt;br /&gt;
		switch(pid)&lt;br /&gt;
		{&lt;br /&gt;
		// Error&lt;br /&gt;
		case -1:&lt;br /&gt;
			perror(&amp;quot;fork()&amp;quot;);&lt;br /&gt;
			exit(EXIT_FAILURE);&lt;br /&gt;
		// Child process&lt;br /&gt;
		case 0:&lt;br /&gt;
			// Execute command&lt;br /&gt;
			if (execv(path, command) == -1)&lt;br /&gt;
			{&lt;br /&gt;
				perror(&amp;quot;execv()&amp;quot;);&lt;br /&gt;
				exit(EXIT_FAILURE);&lt;br /&gt;
			}&lt;br /&gt;
			break;&lt;br /&gt;
		// Parent process&lt;br /&gt;
		default:&lt;br /&gt;
			process-&amp;gt;Pid = pid;&lt;br /&gt;
		}&lt;br /&gt;
		process = process-&amp;gt;Next;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Wait processes&lt;br /&gt;
	do&lt;br /&gt;
	{&lt;br /&gt;
		// Check if a child process has terminated&lt;br /&gt;
		pid = waitpid(-1, &amp;amp;status, WNOHANG);&lt;br /&gt;
		switch(pid)&lt;br /&gt;
		{&lt;br /&gt;
		// Error&lt;br /&gt;
		case -1:&lt;br /&gt;
			perror(&amp;quot;waitpid()&amp;quot;);&lt;br /&gt;
			exit(EXIT_FAILURE);&lt;br /&gt;
		// All child processes are still running&lt;br /&gt;
		case 0:&lt;br /&gt;
			break;&lt;br /&gt;
		// A child process has terminated&lt;br /&gt;
		default:&lt;br /&gt;
			terminated++;&lt;br /&gt;
			printf(&amp;quot;Finished #%d: %s\n&amp;quot;, terminated, findCommand(pid));&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	while(terminated &amp;lt; ProcessCount);&lt;br /&gt;
&lt;br /&gt;
	exit(EXIT_SUCCESS);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Entry point&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
	// Get input&lt;br /&gt;
	readMultipleLines();&lt;br /&gt;
&lt;br /&gt;
	// Set output&lt;br /&gt;
	runProcesses();&lt;br /&gt;
&lt;br /&gt;
	return EXIT_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Esercizio 3 ==&lt;br /&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;
&lt;br /&gt;
----&lt;br /&gt;
Versione by Daniele Cortesi:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
from sys import argv&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
#controllo se il programma e' stato chiamato correttamente&lt;br /&gt;
if len(argv)&amp;lt;3:&lt;br /&gt;
	print &amp;quot;uso: programma cartella1 cartella2&amp;quot;&lt;br /&gt;
	exit(1)&lt;br /&gt;
	&lt;br /&gt;
dir1=argv[1]&lt;br /&gt;
dir2=argv[2]&lt;br /&gt;
&lt;br /&gt;
#controllo che gli argomenti siano effettivamente cartelle&lt;br /&gt;
if not os.path.isdir(dir1) or  not os.path.isdir(dir2):&lt;br /&gt;
	print &amp;quot;cartelle non valide&amp;quot;&lt;br /&gt;
	exit(1)&lt;br /&gt;
&lt;br /&gt;
cartelle=[os.getcwd()+&amp;quot;/&amp;quot;+dir1] #lista che conterra' mano a mano tutte le sottocartelle&lt;br /&gt;
files={} #dizionario con nomefile: [lista con tutti i file che si chiamano &amp;quot;nomefile&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
while len(cartelle)&amp;gt;0:&lt;br /&gt;
	c=cartelle.pop() &lt;br /&gt;
	for f in os.listdir(c): #analizzo tutti i file nella cartella c&lt;br /&gt;
		#se f non e' una cartella, allora lo inserisco nel dizionario se non c'e', altrimenti aggiungo il suo percorso alla lista&lt;br /&gt;
		if not os.path.isdir(c+&amp;quot;/&amp;quot;+f):&lt;br /&gt;
			if not files.has_key(f):&lt;br /&gt;
				files[f]=[c+&amp;quot;/&amp;quot;+f]&lt;br /&gt;
			else: files[f].append(c+&amp;quot;/&amp;quot;+f)&lt;br /&gt;
		#se f invece e' una cartella, la aggiungo alla lista cosi' alla prossima iterazione (o dopo in caso di piu' cartelle) verra' analizzata&lt;br /&gt;
		else: cartelle.append(c+&amp;quot;/&amp;quot;+f)&lt;br /&gt;
		&lt;br /&gt;
#creo i link simbolici	&lt;br /&gt;
for k in files.keys():&lt;br /&gt;
	for i,f in enumerate(files[k]):&lt;br /&gt;
		link=k&lt;br /&gt;
		if (i&amp;gt;0): link+=str(i)&lt;br /&gt;
		os.symlink(f, dir2+&amp;quot;/&amp;quot;+link)&lt;br /&gt;
&lt;br /&gt;
exit(0)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
ESERCIZIO 3.&lt;br /&gt;
*/&lt;br /&gt;
#include&amp;lt;unistd.h&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;
#include &amp;lt;sys/types.h&amp;gt; &lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
void collectandlink(char *arg1, char *carg2)&lt;br /&gt;
{ &lt;br /&gt;
	struct dirent **namelist; &lt;br /&gt;
	int n; &lt;br /&gt;
	n = scandir( arg1 , &amp;amp;namelist, 0, alphasort); &lt;br /&gt;
&lt;br /&gt;
	if (n &amp;lt; 0) &lt;br /&gt;
		perror(&amp;quot;scandir&amp;quot;); &lt;br /&gt;
	else &lt;br /&gt;
	{ &lt;br /&gt;
		while(n--)&lt;br /&gt;
		{ &lt;br /&gt;
			int i;&lt;br /&gt;
			char* istr;&lt;br /&gt;
			int datest;&lt;br /&gt;
			char *pathnametmp;&lt;br /&gt;
			char *pathwithname=(char *)malloc(512);&lt;br /&gt;
			char *pathwithname2=(char *)malloc(512);&lt;br /&gt;
			strcpy(pathwithname,arg1);&lt;br /&gt;
			strcpy(pathwithname2,carg2);&lt;br /&gt;
			strcat(pathwithname,&amp;quot;/&amp;quot;);&lt;br /&gt;
			strcat(pathwithname2,&amp;quot;/&amp;quot;);&lt;br /&gt;
			strcat(pathwithname,namelist[n]-&amp;gt;d_name);&lt;br /&gt;
			strcat(pathwithname2,namelist[n]-&amp;gt;d_name);&lt;br /&gt;
			struct stat s; &lt;br /&gt;
			if( stat(pathwithname,&amp;amp;s) == 0 ) &lt;br /&gt;
			{  &lt;br /&gt;
				if( s.st_mode &amp;amp; S_IFDIR ) //è un dir&lt;br /&gt;
				{ &lt;br /&gt;
					if ( strcmp( namelist[n]-&amp;gt;d_name , &amp;quot;..&amp;quot; ) == 0 )//si deve escludere &amp;quot;..&amp;quot;&lt;br /&gt;
					{ &lt;br /&gt;
						continue; &lt;br /&gt;
					} &lt;br /&gt;
					if( strcmp( namelist[n]-&amp;gt;d_name , &amp;quot;.&amp;quot; ) == 0 )//si deve escludere &amp;quot;.&amp;quot;&lt;br /&gt;
					{ &lt;br /&gt;
						continue; &lt;br /&gt;
					}  &lt;br /&gt;
					else &lt;br /&gt;
					{&lt;br /&gt;
						collectandlink(pathwithname,carg2);&lt;br /&gt;
					}&lt;br /&gt;
				} &lt;br /&gt;
				else &lt;br /&gt;
				{&lt;br /&gt;
					if( s.st_mode &amp;amp; S_IFREG ) //è un file&lt;br /&gt;
					{ &lt;br /&gt;
						datest=symlink(pathwithname,pathwithname2);//torna 0 al successo -1 altrimenti&lt;br /&gt;
						if(datest==-1) //se simlink fallisce =&amp;gt; link esiste&lt;br /&gt;
						{&lt;br /&gt;
							i=1;&lt;br /&gt;
							while(datest!=0)//finchè simlink non ha successo&lt;br /&gt;
							{&lt;br /&gt;
								istr=(char *)malloc(32);&lt;br /&gt;
								pathnametmp=(char *)malloc(544);&lt;br /&gt;
								strcpy(pathnametmp,pathwithname2);&lt;br /&gt;
								sprintf(istr, &amp;quot;%d&amp;quot;, i);&lt;br /&gt;
								strcat(pathnametmp,istr);&lt;br /&gt;
								datest=symlink(pathwithname,pathnametmp);&lt;br /&gt;
								free(istr);&lt;br /&gt;
								free(pathnametmp);&lt;br /&gt;
								i=i+1;&lt;br /&gt;
							}&lt;br /&gt;
						}&lt;br /&gt;
					} &lt;br /&gt;
				} &lt;br /&gt;
			}&lt;br /&gt;
			free(pathwithname);&lt;br /&gt;
			free(pathwithname2);&lt;br /&gt;
		} &lt;br /&gt;
	}&lt;br /&gt;
	free(namelist);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){ &lt;br /&gt;
collectandlink(argv[1],argv[2]); &lt;br /&gt;
return 1; &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-Da fede&amp;amp;pirata&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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 CHAR 1&lt;br /&gt;
#define SPACE 0&lt;br /&gt;
&lt;br /&gt;
execs2(char *s,int argc)&lt;br /&gt;
{&lt;br /&gt;
				char *argv[argc+1];&lt;br /&gt;
				char *t=s;&lt;br /&gt;
				int status=SPACE;&lt;br /&gt;
				argc=0;&lt;br /&gt;
				while (*t) {&lt;br /&gt;
								switch(*t) {&lt;br /&gt;
												case ' ':&lt;br /&gt;
												case '\t':&lt;br /&gt;
												case '\n':&lt;br /&gt;
												case 0:&lt;br /&gt;
																if (status == CHAR) argc++;&lt;br /&gt;
																*t=0;&lt;br /&gt;
																status=SPACE;&lt;br /&gt;
																break;&lt;br /&gt;
												default:&lt;br /&gt;
																if (status == SPACE) printf(&amp;quot;%s\n&amp;quot;,t);&lt;br /&gt;
																if (status == SPACE) argv[argc]=t;&lt;br /&gt;
																status=CHAR;&lt;br /&gt;
																break;&lt;br /&gt;
								}&lt;br /&gt;
								t++;&lt;br /&gt;
				}&lt;br /&gt;
				argc++;&lt;br /&gt;
				argv[argc]=0;&lt;br /&gt;
				int i;&lt;br /&gt;
				for (i=0; i&amp;lt; argc+1; i++)&lt;br /&gt;
								printf(&amp;quot;%d %p\n&amp;quot;,i,argv[i]);&lt;br /&gt;
				execvp(argv[0],argv);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
execs(char *s)&lt;br /&gt;
{&lt;br /&gt;
				char *t=s-1;&lt;br /&gt;
				int argc=0;&lt;br /&gt;
				int status=SPACE;&lt;br /&gt;
				do {&lt;br /&gt;
								t++;&lt;br /&gt;
								switch(*t) {&lt;br /&gt;
												case ' ':&lt;br /&gt;
												case '\t':&lt;br /&gt;
												case '\n':&lt;br /&gt;
												case 0:&lt;br /&gt;
																if (status == CHAR) argc++;&lt;br /&gt;
																status=SPACE;&lt;br /&gt;
																break;&lt;br /&gt;
												default:&lt;br /&gt;
																status=CHAR;&lt;br /&gt;
																break;&lt;br /&gt;
								}&lt;br /&gt;
				} while (*t);&lt;br /&gt;
				execs2(s,argc);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char * argv[])&lt;br /&gt;
{&lt;br /&gt;
				char buf[1024];&lt;br /&gt;
				fgets(buf,1024,stdin);&lt;br /&gt;
				execs(buf);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aula</name></author>
	</entry>
</feed>