NOTE SPARSE SU ALCUNE PARTICOLARITA' DI UNIX
per il newbie italiano che viene dal DOS
===========================================
by M. Andreoli


Queste piccole note sono scritte nella lingua originale dell'Autore,
il quale e' ben lieto di poterla finalmente usare senza vergogna.
[ A dire il vero, la lingua originale dell'Autore sarebbe il
napoletano, ma comunque muLinux funziona abbastanza bene, o no? ] 


Indice
----------

	o I metacaratteri
	o Strani comportamenti usando i metacaratteri
	o Periferiche
	o Giocare con i terminali tty [NEW]
	o Duplicare un floppy 
	o Copiare "parti" da una sorgente ad una destinazione
	o Spezzare in due un file e copiarlo su due floppy 
	o Un esercizio con "dd": che tipo di file e' questo? [NEW]
	o Copiare e cancellare files
	o Utilizzo delle pipe: tar e gzip
	o Sperimentare con i dischi RAM
	o File System in file: le "loop devices" [NEW]
	o Sperimentare con "netcat": file transfer

I metacaratteri (wild-card)
---------------------------

Caratteri jolly come * vengono (come si dice) "espansi" direttamente
dall'interprete dei comandi (la shell) e passati al comando eseguibile
come lista di parametri (in C: argv[1], argv[2], ....)

Esempio: 
Se una directory contiene i seguenti files { more, mount, mv, od }, un
comando come "ls *" viene espanso in:

	# ls more mount mv od


Strani comportamenti usando i metacaratteri
-------------------------------------------

Se nella stessa directory di prima, io imposto il comando:

	# cp *

questo viene interpretato come:

	# cp more mount mv od

col risultato che i file {more mount mv} vengono accorpati nel 
file "od", e forse non e' quello che volevo!

Per sequire operazioni aritmetiche, in UNIX e' disponibile il comando "expr":

		expr x op y

Nella stessa directory, un comando come:

	# expr 10 * 2

Verrebbe espanso in:
	
	# expr 10 more mount mv od 2

generando errore.


Per ovviare a questi inconvenienti, i caratteri speciali vanno "protetti"
dall'interpretazione (come la Bibbia?); esempio:

	# expr '10 * 2'	
	# expr 10 \* 2

Il doppio apice " non serve per proteggere quanto per "raccogliere",un po'
come le parentesi tonde in matematica.

Periferiche (devices)
-------------------

Sono del tipo "a carattere" (esempio: il modem, il mouse) o "a blocchi"
(esempio il CD, l'hard disk, etc.) a seconda se l'accesso e' sequenziale
o random.

Si puo' accedere ad una periferica attraverso i files speciali che
si trovano nella directory /dev. Esempio:

		/dev/hd*	hd=hard-disk
		/dev/tty*	tty=terminali a carattere
		/dev/ttyS*	porte Seriali (mouse, modem)
		/dev/fd*	fd=floppy disk
		/dev/sd*	sd=SCSI device
		

Con fd0H1722, ad esempio, ci si riferiche al primo (0) floppy, (H) alta
densita', formattato a 1722K.

Poiche' "file" e "device" possono essere trattati quasi ovunque
con comandi analoghi, nel seguito spesso i due nomi verranno confusi.


Le periferiche "a blocchi" sui quali sia stato predisposto un "file system",
possono essere "montate" in un "punto di montaggio" e quindi entrare
a far parte a pieno titolo dell' "albero" delle directory.

Ad esempio, col comando:

		# mount /dev/fd0H1722 /a

il floppy potra' essere acceduto semplicemente con un "cd /a".

Giocare con i terminali tty
--------------------------------

Ad ognuna delle console aperte corrisponde un device dal nome /dev/tty*.
Ad esempio: la prima e' /dev/tty1, la seconda /dev/tty2, e via di seguito.
Al terminale corrente (dove e' connesso lo standard input) corrisponde
/dev/tty.

E' possibile inviare caratteri su una delle console aperte in maniera
molto semplice. Esempio:

	# echo hello > /dev/tty3
	# date > /dev/tty3
	# cat /etc/profile > /dev/tty5

Se invece voglio accedere in lettura ad una data console, posso utilizzare
i devices del tipo /dev/vcs*, uno per ogni tty*.

Se, ad esempio, voglio vedere cosa e' stato digitato su tty1, basta
che batto:

	# cat /dev/vcs1


Duplicare un floppy (diskcopy del DOS)
------------------------------------

Con UNIX, puoi copiare l'intero contenuto di una periferica
in un file, mediante un comando del tipo:

	# cat /dev/fd0H1440 > myfloppy

Dopodiche', basta inserire il floppy destinazione, ed eseguire:

	# cat myfloppy > /dev/fd0H1440


Copiare parti predefinite da una "sorgente" ad una "destinazione" 
-----------------------------------------------------------------

Per questo tipo di attivita' e' utile il comando "dd", molto versatile.
Con dd ( a differenza che col copy del DOS) si e' in grado di copiare
blocchi di dati da una parte all'altra e di controllare sia la quantita' 
di roba trasportata sia il punto esatto dove iniziare la copia.


Esempio 1:


	# dd if=/dev/fd0 of=myfile skip=200 bs=1k count=2

Questo comando copia il floppy sul file "myfile", usando blocchi da 1k 
(bs=block size), ma soltanto 2 blocchi (count=2) e saltando i
primi 200 (skip=200).


Esempio 2:

	# dd if=/dev/ttyS0

Copia "a video" (cioe' nello stdout) tutto cio' che proviene da COM1,
finquando non si interrompe con control-C.

Spezzare in due un file e copiarlo su due floppy 
------------------------------------------------

Si puo' farlo, per esercizio, con "dd":

	# dd if=myfile bs=1k count=1440 of=part.1
	# dd if=myfile bs=1k skip=1440 of=part.2
	# cat part.1 > /dev/fd0H1440 { cambia il floppy}
	# cat part.2 > /dev/fd0H1440

Per riunire le due "parti" basta prelevarle dai floppy e battere:

	# cat part.1 part.2 > myfile
	# rm part.1 part.2

Vedi anche il mio script /usr/bin/mkfloppy.


Un esercizio con "dd": che tipo di file e' questo?
-------------------------------------------------

Supponiamo di avere un certo file X senza una preciso suffisso che
ne indichi il tipo e di voler scoprire che razza di dati vi sono
contenuti. Nel mondo UNIX questo e' generalmente il compito del
comando "file". Ad esempio, se io batto:

		# file DOSTOOLS.zip

ottengo come risposta:

	 "Zip archive data, at least v2.0 to extract"

Il comando "file" estrare alcuni gruppi di byte e ne confronta il valore
binario con un data-base di "valori magici" (/etc/magic).

Ad esempio: un file compresso con pkzip ha i primi due byte settati come "PK",
mentre un file con estensione .tar ha 5 bytes settati come "ustar", 
a partire dal byte 257.

In questo modo, se io faccio:

		dd if=X.zip bs=1c count=2

ottengo "PK", e se faccio:
		
		dd if=X.tar bs=1c skip=257 count=5

ottengo "ustar".
Spulciando in /etc/magic (ma purtroppo in muLinux questo file e' assente)
si possono fare molte altre piccole scoperte del genere. E' proprio in
questa maniera che e' stata implementata la versione "rustica" di "file"
in muLinux.
 

Copiare e cancellare files: comandi cp e rm
-------------------------------------------

Il comando "cp" si aspetta sempre che l'ultimo parametro impostato sia
la destinazione. La copia ricorsiva si attiva con -r.

Analogamente, "rm". Aggiungendo -v si ottiene la lista dei files su cui
si sta operando.

Esempi:

	# cp -vr /bin /sbin /tmp
	
	Copia ricorsiva delle directory /bin e /sbin in /tmp.

	# cp -vr /bin/* /tmp

	In questo caso in /tmp non verra' creata la sottodir. /tmp/bin.

	# rm -r /

	Senza commento :))


Utilizzo delle pipe: tar e gzip
--------------------------------

Comandi molto usati quali "tar" (accorpa file e directory) e "gzip" (il
compressore standard GNU) possono ricevere/produrre "materiale" direttamente
dagli "standard input/output" e quindi lavorano molto bene via "pipe",
cioe' senza produrre file intermedi. In genere, in LINUX, l'omissione
del nome del file fa si che i comandi si attendano l'input proprio in
questo modo. In qualche caso, si puo' fare esplicito riferimento allo
standard input mediante il simbolo "-" (come fa tar), o con altri tipi 
di switch (come il -c di gzip).


Esempio 1: produzione di un TGZ

	# tar -cf- /usr/doc | gzip -c > doc.tgz

	In questo caso tar crea ("-c") un archivio di tutto il sottoalbero
	/usr/doc e lo copia sullo stdout ("f-"), dove verra' prelevato
	da gzip, compresso ancora nello stdout ("-c") e raccolto in doc.tgz.


Esempio 2: decompressione in / di un TGZ

	# gzip -dc doc.tgz | (cd /;  tar -xf- )


	Questa e' la procedura inversa della precedente. gzip decomprime
	il file doc.tgz ("-d"); lo copia sullo stdout ("-c"), dove tar
	lo raccoglie ("f-") e lo espande ("-x") nei singoli files di cui
	e' costituito. I files vengono creati a partire dalla directory
	specificata con -C (in questo caso /, il punto piu' alto dell'albero).

Per la cronaca, tar prevede lo switch "-z", in grado di fare il lavoro
che normalmente compete a gzip.



Sperimentare con i Dischi RAM
------------------------------

Si puo' sperimentare con i file-system (creazione, montaggio, copia, etc)
anche senza disporre di vere partizioni su hard-disk.
Per far questo si possono utilizzare i "dischi ram", accedibili mediante
i files /dev/ram0, /dev/ram1, etc.

Evitare, comunque, l'uso dei primi 4, perche' gia' usati (normalmente) da 
muLinux, e non superare i 4M di dimensione.

Esempio 1:

	# mkdir /ram 			{ crea il punto di montaggio /ram }
	# mkfs.ext2 /dev/ram5 1440	{ crea un fs EXT2 di 1,44M }
	# mount /dev/ram5 /ram		{ lo monta in /ram}

Esempio 2:

	# mkdir /ram 			{ crea il punto di montaggio /ram }
	# cat /dev/fd0H1440 > /dev/ram5 { copia il floppy (DOS) in RAM }
	# mount -t dos /dev/ram5 /ram	{ monta in /ram il fs ottenuto }


Nel Esempio-2, il fs non viene creato ma semplicemente replicato a partire
da quello del floppy (nel nostro caso, un fs DOS).


File System in un file: le "loop devices"
-----------------------------------------

Il comando "mkfs.ext2" puo' creare un file system EXT2 (nativo di
Linux) anche in un semplice file, piuttosto che in una partizione
predisposta. Per far questo occorre innanzitutto creare il file della
dimensione voluta (ad esempio 300K) tutto pieno di zeri con 
questo comando:

		# dd if=/dev/zero of=my_fs bs=1k count=300

dopodicche' possiamo crearvi il file system:

		# mkfs.ext2 -F my_fs 

Per poter accedere ad un qualsiasi file-system di UNIX, occorrera'
"montarlo" da qualche parte. Bene, questo si fa alla solita maniera:

		# mount -o loop my_fs /mnt

Notare l'opzione "-o loop" che dice al kernel di usare le
features relative a questa particolare estensione di "mount".
Batti "df" se vuoi vedere il nuovo fs montato, lo spazio disponibile,etc.

Ora possiamo andare su /mnt, creare files, directory, copiarvi
sopra i nostri dati,  proprio come se fosse un qualsiasi dispositivo rigido.
Alla fine, possiamo "smontarlo" con 

		# umount /mnt

e depositare il file "my_fs" da qualche parte, magari dopo averlo compresso
con gzip. 

L'intero file system di muLinux si sarebbe potuto creare in questo modo e,
invero, esistono dei floppy Linux fatti proprio cosi'. 


Sperimentare con "netcat": file transfer
-----------------------------------------------------

Il programmino "nc" (vedi nc -h) e' alla base della maggior parte
delle attivita' TCP/IP di muLinux. Poiche' io lo considero una meraviglia
della natura, voglio descrivere qui come sia possibile con "nc"
effettuare un "file transfer" tra due macchine UNIX in una rete LAN.

Ovviamente, se non hai installato muLinux in una LAN, in almeno due
postazioni (che nel seguito chiamero' host A e host B), puoi anche
saltare questa parte.

-- client & server

nc puo' essere usato per sperimentare la filosofia client/server
programmando la Shell di UNIX, invece che in C:

ecco come attivare un server (-l = listening) che ascolta la porta 5555:

	host-A> nc -l -p 5555

Ecco invece come attivare un client sull'host-B sulla stessa porta:

	host-B> nc A 5555

Con questa semplice procedura A e B sono ora collegati attraverso
la porta 5555. Battendo qualcosa sulla tastiera, da entrambi i lati,
i caratteri vengono trasferiti da una parte all'altra (e' quello che
in UNIX si chiamerebbe TALK).

E' con trucchetti del genere che in muLinux sono stati implementati
il server web PYGMY, il telnet, il sendmail, etc.


-- file transfer

Se si vuole trasferire un file con questa tecnica, si puo' farlo
agevolmente mediante lo stdin/stdout.

Nell'esempio che segue, l'host A archivia una parte del suo file system,
lo comprime con gzip e lo spedisce verso la porta. L'host B lo
raccoglie dalla porta, lo decomprime e crea nel suo file system l'insieme
dei files in esso contenuti. La directory trasferita e' /usr/doc.


	host-A> tar -cf- /usr/doc | gzip -9c | nc -l -p 5555
	host-B> nc A 5555 | gzip -dc | tar -C/ -xvf- 

Come si vede, la directory /usr/doc viene trasferita da A a B
attraverso la rete, in formato compresso. Al termine dell'operazione
in B abbiamo creato il sottoalbero /usr/doc!

Per quest'uso di "tar" e "gzip" vedi le Sezioni precedenti.

Se come host-B hai a disposizione soltanto un client Windows con un
browser come Netscape, potrai tentare comunque un trasferimento di
questo genere, col seguente trucchetto:

	Imposta sul browser il seguente url:

		http://A:5555/

Il file dovrebbe comparire (sotto forma di pupazzetti, se e' un binario)
direttamente nella finestra del browser. Non ti resta che salvarlo
con qualche nome. Non ho provato, ma dovrebbe funzionare.

[ ... ]
	
