Posts Tagged ‘linux’

NTFS and Debian

divendres, gener 15th, 2010

Long time ago it was a pain in the neck to use ntfs units with Debian. Now we have a third generation driver in a package called ntfs-3g, but there is something extra to have a unit (specially external ones) working with write permissions. I had an external hard disk LG formatted with NTFS, and I wanted to make it work with my Debian Squeeze.

apt-get install libfuse2 fuse-utils ntfs-3g ntfsprogs

though probably with only ntfs-3g would work.

After that, plug your unit in, discover its device name (for instance, $ dmesg | tail -20), and mount it with the following line:

mount -t ntfs-3g /dev/sdb1 /media/LG -o umask=0,nls=utf8

Ready :)

FAT32 with SD cards on GNU/Linux or GParted: FAT32 grayed out

dissabte, maig 2nd, 2009

If you are a GNU/Linux user, you may have forgotten that there is a lot of people behaving in a strange way, like using NTFS or FAT32. At least, I sometimes do. Today I got a pendrive already formatted (FAT32) and, when I plugged it in, I pretended to delete its contents. Debian told me «I can’t: it’s read only». It wasn’t read only, though. It had been  auto-mounted with standard methods. Since I wanted to delete all contents, I reckoned I could format it. Okay, it’s not one of the best practices because it’s a SD card and has a writing limit, but I just use it once a month.

debian:/home/edu# gparted

I umount /dev/sdf in order to format it, and… fat32 is grayed out. I can just use ext2, ext3, swap and reiserfs.

What nobody told me is that I need the dosfstools package:

debian:/home/edu# apt-get install dosfstools

And after that, everything worked fine. I now own a fat32 formatted 1Gb device.

Com fer servir Java, JDBC i GNU/Linux

dissabte, abril 25th, 2009

A la facultat ens han donat instruccions per a treballar amb Java i JDBC des de Windows. Com que alguns no fem servir aquest sistema inoperatiu per motius tant tècnics com ètics, m’hi he barallat una estoneta i he trobat com fer-ho amb GNU/Linux. No és complicat :)

Entorn

Java

Primer de tot ens cal l’entorn per desenvolupar aplicacions en Java

apt-get install sun-java6-jdk

Amb això no n’hi ha prou per fer un Hello World. GNU/Linux permet tenir diverses màquines virtuals instal·lades, i per defecte en ve una de lliure (cosa que ja em sembla bé). Volem desenvolupar en un entorn tan semblat a la facultat com sigui possible, així que ens toca canviar la màquina virtual i posar la privativa:

artoo:/home/edu# update-alternatives --config java

Hi ha 3 alternatives que proveeixin «java».

Selecció     Alternativa
-----------------------------------------------
1    /usr/bin/gij-4.3
+        2    /usr/lib/jvm/java-gcj/jre/bin/java
*         3    /usr/lib/jvm/java-6-sun/jre/bin/java

Premeu retorn per a mantenir l'opció per defecte[*], o introduïu un número de selecció:

Volem la 3.

Per treballar amb JDBC i PostgreSQL ens fa falta el driver adequat. A dia d’avui n’hi ha dos de disponibles, el 3 i el 4. Jo he necessitat el 4 perquè tinc màquina virtual versió >= 1.6
edu@artoo:~/facultat/bd/java$ java -version
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode, sharing)
edu@artoo:~/facultat/bd/java$

Ens baixarem un fitxer .jar, que ve a ser un tar.gz. El podem posar on vulguem, perquè després li direm al sistema on és. Jo he optat per fer-me un directori de treball per fer les pràctiques en /home/edu/facultat/bd/java :
edu@artoo:~/facultat/bd/java$ ls
classp             gestioSocis.java     HelloWorldApp.java
gestioSocis.class  HelloWorldApp.class
edu@artoo:~/facultat/bd/java$ ls classp/
postgresql.jar

Ara ja tenim els ingredients, i falta connectar-los. Caldrà exportar la variable d’entorn CLASSPATH. Pels veterans de C++, això ve a ser com quan compilem amb g++

g++ -c programa.cpp -I/includesdiversos

Cal dir-li on cercar fitxers que inclourem i que no venen de sèrie. Com si fos una variable d’entorn normal, fem:

export CLASSPATH=.:classp/postgresql.jar

i així li diem que busqui classes en el directori actual i en classp/postgresql.jar. Ara, per fi, ja podem fer les primeres proves amb JDBC.

Servidor i PostgreSQL

Necessitem un servidor Apache i PostgreSQL. L’opció més fàcil és fer servir LAMPP :

Instal·leu lampp en /opt/lampp Instruccions i paquet

Instal·leu el plugin per a PosgreSQL Instruccions i paquet

Els passos indicats a la web del plugin són:

  1. “tar xfz postgresql.tar.gz -C /tmp” Canvieu el nom de fitxer pel que hagueu baixat, és clar.
  2. “cd /tmp/postgresql-addon”
  3. “./INSTALL”

Per a iniciar el servidor POSGRESQL: /opt/lampp/lampp startpostgresql

Stop: /opt/lampp/lampp stoppostgresql

combinació usuari i contrasenya per defecte: User: root Password: lampp

És recomanable iniciar primer el servidor apache: /opt/lampp/lampp start i després el posgresql: /opt/lampp/lampp startpostgresql

Podeu veure una interfície web per a Posgres des del Firefox, tot anant a l’adreça: /localhost/phppgadmin

Com compilar amb Java

Farem un HelloWorld en un segon:

class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}

Aquest és el codi. Cal desar-lo en HelloWorldApp.java. És important respectar el nom de fitxer, que ha de ser igual al de la classe principal.

Doncs apa:

edu@artoo:~/facultat/bd/java$ javac HelloWorldApp.java
edu@artoo:~/facultat/bd/java$ java HelloWorldApp
Hello World!
edu@artoo:~/facultat/bd/java$

Proves amb JDBC

Per l’assignatura de Bases de Dades de la FIB, quadrimestre 08-09Primavera, fem servir el següent escenari (font)

CREATE TABLE socis
(dni char(9),
nom char(30) NOT NULL,
telefon char(9),
numVISA char(12),
ciutatResidencia char(20) DEFAULT 'Barcelona',
PRIMARY KEY (dni));
 
CREATE TABLE tipus
(tipus char(15),
numMaxInscripcions integer NOT NULL,
PRIMARY KEY (tipus));
 
CREATE TABLE activitats
(tipusActivitat char(15),
dataInici integer,
descripcio char(50) UNIQUE,
dni char(9),
preu integer CHECK (preu > 10),
lloc char(20),
ciutat char(20),
PRIMARY KEY (tipusActivitat, dataInici),
FOREIGN KEY (tipusActivitat) REFERENCES tipus (tipus),
FOREIGN KEY (dni) REFERENCES socis);
 
CREATE TABLE inscripcions
(tipusActivitat char(15),
dataInici integer,
dni char(9),
formaPagament char(20),
dataPagament integer,
CHECK (dataInici < dataPagament),
PRIMARY KEY (tipusActivitat, dataInici, dni),
FOREIGN KEY (tipusActivitat, dataInici) REFERENCES activitats,
FOREIGN KEY (dni) REFERENCES socis);

Amb les dades a continuació (font):

INSERT INTO socis VALUES (10, 'Carme', 101,NULL, 'Hospitalet');
INSERT INTO socis VALUES (11, 'Nuria', 111, 111111, 'Hospitalet');
INSERT INTO socis VALUES (12, 'Josep', 121, 121121, 'Hospitalet');
INSERT INTO socis VALUES (13, 'Jordi', 131, 131131, 'Barcelona');
INSERT INTO socis VALUES (14, 'Imma', 141, 141141, 'Barcelona');
INSERT INTO socis VALUES (15, 'Roger', 151, 151151, 'Barcelona');
INSERT INTO socis VALUES (16, 'Oriol', 161, 161161, 'Barcelona');
INSERT INTO socis VALUES ('17', 'Mireia', 101,101101, 'Palleja');
INSERT INTO socis (dni, nom, telefon, numVISA) VALUES (19, 'Joan', 333, 333333);
INSERT INTO socis (dni, nom, telefon, ciutatResidencia) VALUES (20, 'Joan', 333, 'Sant Just');
 
INSERT INTO tipus VALUES ('capDAny', 200);
INSERT INTO tipus VALUES ('cine', 10);
INSERT INTO tipus VALUES ('teatre', 6);
INSERT INTO tipus VALUES ('discoteca', 30);
INSERT INTO tipus VALUES ('excursio', 30); 
INSERT INTO tipus VALUES ('sopar', 2);
INSERT INTO tipus VALUES ('opera', 6);
INSERT INTO tipus VALUES ('concert', 6);
 
INSERT INTO activitats VALUES ('cine', 124, 'One Milion Baby', 10, 17, 'Cinesa Diagonal', 'Barcelona');
INSERT INTO activitats VALUES ('cine', 224, 'Magnolias de Acero', 11, 16, 'La Farga', 'Hospitalet');
INSERT INTO activitats VALUES ('capDAny', 1224, 'Festa Roc Blanc', 12, 100, 'Plaça Major', 'Vic');
INSERT INTO activitats VALUES ('sopar', 425, 'Aniversari Josep', 12, 80, 'Can Jubany', 'Calldetenes'); 
INSERT INTO activitats VALUES ('teatre', 424, 'El Ratoli Viatger', 10, 15, 'Teatre Atlantida', 'Ripoll');
INSERT INTO activitats VALUES ('opera', 2345, 'La Flauta Magica', NULL, NULL, 'Liceu', 'Barcelona');
INSERT INTO activitats VALUES ('concert', 3234, 'La Casa de Vent i de Fusta', 10, NULL, NULL, 'Barcelona');
 
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 124, 10, 'amex');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('sopar', 425, 10, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('capDAny', 1224, 10, 'amex');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 124, 11, 'visa');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('sopar', 425, 11, 'visa');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('capDAny', 1224, 11, 'visa');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('sopar', 425, 12, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 224, 13, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 224, 14, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 224, 15, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 224, 16, 'sdfjñs');
INSERT INTO inscripcions VALUES ('teatre', 424, 10, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 11, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 12, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 13, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 14, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 15, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 16, 'VISA', 435);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 10);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 11);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 12);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 13);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 14);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 15);

La facultat ens facilita també un codi plantilla amb les línies indispensables per establir una connexió:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.sql.*;
import java.util.Properties;
 
public class gestioSocis
   {
   public static void main (String args[])
     {
	try
	   {
	   // carregar el driver al controlador
	   Class.forName ("org.postgresql.Driver");
	   System.out.println ("Driver de PostgreSQL carregat correctament.");
 
 
	   // connectar a la base de dades
	   // cal modificar el username, password i el nom de la base de dades
	   // en el servidor postgresfib, SEMPRE el SSL ha de ser true
	   Properties props = new Properties();
	   props.setProperty("user","elMeuNomUsuari");
	   props.setProperty("password","elMeuPassword");
	   props.setProperty("ssl","true");
	   props.setProperty("sslfactory", "org.postgresql.ssl.NonValidatingFactory"); 
	   Connection c = DriverManager.getConnection("jdbc:postgresql://postgresfib.fib.upc.es:5432/laMevaBaseDeDades", props);
	   c.setAutoCommit(false);
	   System.out.println ("Connexio realitzada correctament.");
 
 
	   // canvi de l'esquema per defecte a un altre esquema
		 Statement s = c.createStatement();
		 s.executeUpdate("set search_path to elMeuEsquema;");
		 s.close();					
	   System.out.println ("Canvi d'esquema realitzat correctament.");
 
 
	   // consultar tots les socis que viuen a Hospitalet
	   // Dir quantes inscripcions té cada un 
	   String cR = "Hospitalet";
	   String consSocis="select dni,nom from socis "+
                         "where ciutatResidencia = '"+cR+"';";
	   System.out.println (consSocis);
	   s = c.createStatement();
	   ResultSet r = s.executeQuery (consSocis);
 
           String consInscr="select count(*) as numInscr "+
                      "from inscripcions i where i.dni = ? ;";
	   System.out.println (consInscr);
 	   PreparedStatement ps = c.prepareStatement(consInscr); 
 	   ResultSet rs = null;
	   int quantsSocis = 0;
	   String dni=" ";
	   String nom=" ";
	   while (r.next())
	   	   {
	   	   quantsSocis = quantsSocis + 1;
	   	   dni = r.getString("dni");
	   	   nom = r.getString("nom");
	   	   System.out.print ("El soci amb dni "+dni+" i nom ");
	   	   if (nom==null) { System.out.print ("null"); }
                     else { System.out.print (nom); }
		     ps.setString(1,dni);
		     rs = ps.executeQuery();
		     rs.next();
		     System.out.print("te ");
		     System.out.print (rs.getInt("numInscr"));
		     System.out.println(" inscripcions");
		     rs.close();
	   	   }
           r.close();
           System.out.println ("Nombre de socis consultats "+quantsSocis);
	   s.close();
 
	   // Inserir una activitat 
 
	   s = c.createStatement();
	   String inserirAct="insert into activitats "+
                      "values ('concert', 3250, 'El fantasma del museu', 10, 120, 'Romea', 'Barcelona')";
	   s.executeUpdate(inserirAct);
	   System.out.println ("Una activitat inserida");
           s.close();
 
	   // Rollback i desconnexió de la base de dades
	   c.rollback();
	   c.close();
	   System.out.println ("Rollback i desconnexio realitzats correctament.");
	   }
 
	catch (ClassNotFoundException ce)
	   {
	   System.out.println ("Error al carregar el driver");
	   }	
	catch (SQLException se)
	   {
	   System.out.println (se.getSQLState());
	   System.out.println (se.getMessage());	   
	   }
  }
}

El que passa és que està preparat per connectar-se des dels laboratoris de la uni, i a casa vull treballar en local. M’ho modifico:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.sql.*;
import java.util.Properties;
 
public class gestioSocis
   {
   public static void main (String args[])
     {
	try
	   {
	   // carregar el driver al controlador
	   Class.forName ("org.postgresql.Driver");
	   System.out.println ("Driver de PostgreSQL carregat correctament.");
 
 
	   // connectar a la base de dades
	   // cal modificar el username, password i el nom de la base de dades
	   // en el servidor postgresfib, SEMPRE el SSL ha de ser true
	   Properties props = new Properties();
	   props.setProperty("user","root");
	   props.setProperty("password","lampp");
	   //props.setProperty("ssl","true");
	   //props.setProperty("sslfactory", "org.postgresql.ssl.NonValidatingFactory"); 
	   Connection c = DriverManager.getConnection("jdbc:postgresql://localhost/javafib", props);
	   c.setAutoCommit(false);
	   System.out.println ("Connexio realitzada correctament.");
 
 
	   // canvi de l'esquema per defecte a un altre esquema
		 Statement s = c.createStatement();
		 s.executeUpdate("set search_path to public;");
		 s.close();					
	   System.out.println ("Canvi d'esquema realitzat correctament.");
 
 
	   // consultar tots les socis que viuen a Hospitalet
	   // Dir quantes inscripcions té cada un 
	   String cR = "Hospitalet";
	   String consSocis="select dni,nom from socis "+
                         "where ciutatResidencia = '"+cR+"';";
	   System.out.println (consSocis);
	   s = c.createStatement();
	   ResultSet r = s.executeQuery (consSocis);
 
           String consInscr="select count(*) as numInscr "+
                      "from inscripcions i where i.dni = ? ;";
	   System.out.println (consInscr);
 	   PreparedStatement ps = c.prepareStatement(consInscr); 
 	   ResultSet rs = null;
	   int quantsSocis = 0;
	   String dni=" ";
	   String nom=" ";
	   while (r.next())
	   	   {
	   	   quantsSocis = quantsSocis + 1;
	   	   dni = r.getString("dni");
	   	   nom = r.getString("nom");
	   	   System.out.print ("El soci amb dni "+dni+" i nom ");
	   	   if (nom==null) { System.out.print ("null"); }
                     else { System.out.print (nom); }
		     ps.setString(1,dni);
		     rs = ps.executeQuery();
		     rs.next();
		     System.out.print("te ");
		     System.out.print (rs.getInt("numInscr"));
		     System.out.println(" inscripcions");
		     rs.close();
	   	   }
           r.close();
           System.out.println ("Nombre de socis consultats "+quantsSocis);
	   s.close();
 
	   // Inserir una activitat 
 
	   s = c.createStatement();
	   String inserirAct="insert into activitats "+
                      "values ('concert', 3250, 'El fantasma del museu', 10, 120, 'Romea', 'Barcelona')";
	   s.executeUpdate(inserirAct);
	   System.out.println ("Una activitat inserida");
           s.close();
 
	   // Rollback i desconnexió de la base de dades
	   c.rollback();
	   c.close();
	   System.out.println ("Rollback i desconnexio realitzats correctament.");
	   }
 
	catch (ClassNotFoundException ce)
	   {
	   System.out.println ("Error al carregar el driver");
	   }	
	catch (SQLException se)
	   {
	   System.out.println (se.getSQLState());
	   System.out.println (se.getMessage());	   
	   }
  }
}

i es fa la màgia

edu@artoo:~/facultat/bd/java$ java gestioSocis
Driver de PostgreSQL carregat correctament.
Connexio realitzada correctament.
Canvi d'esquema realitzat correctament.
select dni,nom from socis where ciutatResidencia = 'Hospitalet';
select count(*) as numInscr from inscripcions i where i.dni = ? ;
El soci amb dni 10 i nom Carme te 5 inscripcions
El soci amb dni 11 i nom Nuria te 5 inscripcions
El soci amb dni 12 i nom Josep te 3 inscripcions
Nombre de socis consultats 3
Una activitat inserida
Rollback i desconnexio realitzats correctament.
edu@artoo:~/facultat/bd/java$

shell: some useful commands

dissabte, març 28th, 2009

The Linux shell offers lots of commands, but there are a few used every day. For a standard user, the shell isn’t really important. We can do (almost) whatever using GUIs, but there are some actions that are to be done with a shell. It’s powerful, faster, and easier. How do you put in a text file all permissions of all files in a given directory? How do you modify a line matching a pattern all system wide? We shall have a look at the frequently used commands:

more, less

You can use more for paging through text one screenful at a time. There is another command, less, that does the same but faster. more came first, but while it only used to allow moving forward through the text, the less command let the user go backwards. Nowadays, we can use both commands as synonyms.

$ ls -l /etc/ | more

$ ls -l /etc/ | less

$ less file.text

$ more file.text

Warning: type q to quit less or more.

cat

It’s kind of more. It outputs the contents of a file.

$ cat text.file

sort

Another filter that sorts lines of text files. The manual is quite large, so let’s see a few quick examples:

$ sort /etc/htpasswd

Shows on stdout (the screen, by default), the /etc/htpasswd  sorted alphabetically by lines.

$ sort -t: -k3 -n /etc/passwd

Performs a numeric sort  (-n) by the 3rd field (-k3). Two fields are separated by  ‘:’ (-t:).

$ ls -l /etc | sort -k5 -n -r | less

Orders the output of ls -l /etc by  the 5th field (the file’s size, as man ls says) descending (-r). We use the field separator by default (one or more white spaces).

cut

Selects parts of lines of the input file.

$ cut -d: -f3,5 /etc/passwd

Shows the 3rd and 5th field of all lines of /etc/passwd, having ‘:‘ as a field separator (-d:). Notice that with the sort command, we used -t to choose the separator.

$ ls -l /etc/passwd | cut -c2-10

Only outputs the file permissions, as they are on columns 2 to 10 in ls -l /etc/passwd.

head

Selects the first lines or characters in a file. We can use it after a pipe ( | ) or as a usual command:

$ cat /etc/passwd/ | head -2

Outputs the 2 first lines of /etc/passwd

$ head -2 /etc/passwd

idem :)

You have learnt the cut usage, haven’t you? Then mix your knowledge:

$ sort /etc/passwd | head -2 | cut -d: -f1

Shows the 2 first user id of the system, having the file sorted alphabetically.

tail

Opposite of head. Outputs the last lines or characters of files.

$ ls -l /etc | tail -2

shows the two last lines of the ls -l /etc output. Is it useful? Not really, yet. Use sort:

$ ls -l /etc  | sort -k5 -n | tail -2

Shows the 2 biggest files in /etc

tr

This is one of the most useful commands. It just translates characters. e.g: you want to replace all ‘a’ chars in a file for ‘z’, or e.g: you wish to delete all ‘b’ in a file (replace ‘b’ with ‘BLANKSPACE’):

$ tr aeiou AEIOU < /etc/passwd

the < character means: «redirect /etc/passwd to the standard input of the tr command». This line replaces all lower-case vowels to upper-case. a->A, e->E and so on. The first letter in «aeiou» corresponds to the first letter in «AEIOU». Thus, if you want to replace a,e,i,o,u with ‘V’, do:

$ tr aeiou VVVVV < dummyfile

or

$ tr aeiou V < dummyfile

This line doesn’t modify the /etc/passwd or the dummyfile. If you wish so, you have to redirect the output to the file you want to save the changes in, like that:

$ tr aeiou VVVVV < dummyfile > dummyout.

DON’T DO IT WITH /etc/passwd

wc

As simple as «word-count», but powerful: it can count lines, words and characters of the input. Example:

$ wc -c /etc/passwd

How many characters does /etc/passwd contain?

$ ls -l /etc | wc -l

how many files and directories are in /etc ?

uniq

reports or ommits repeated lines in a list. «compacts» them. e.g: We have a file containing:

edu@debian:~$ cat dummyfile
Hi,
Hi,
This is a script of Family Guy.
Have a good day,
Have a good day,
Have a good day,

Edu

Eduard Gamonal

edu@debian:~$

Its got repeated lines. I like counting things and I wish to know how many repeated lines are there.

edu@debian:~$ cat dummyfile | uniq -c
2 Hi,
1 This is a script of Family Guy.
3 Have a good day,
1
1 Edu
1
1 Eduard Gamonal
1
edu@debian:~$

Funny, but not really useful. What if instead of a dummy file we had a list of processes running on our system?

$ ps -e | cut -c25- | sort | uniq -c

For each running command , outputs the processes that are executing it. ps -e shows the command name from the 25th column on (notice the last hyphen in -c25- ).

It may seem complex sometimes, and the user my spend half an our to type a correct command, but after that we have the output we wanted and we can use it, since it’s text in a shell, not in a window.

Shell, find it! Some examples of the find command line tool

dilluns, març 16th, 2009

Have you lost something? You may fall in love with the find command. GNU Find tells you where a file is, given a condition. You shall use regular expressions and parameters related to lots of file features, like last access date, last modification date, its i-node, the file format of the device where it’s being saved, etc.

The syntax is find dir1 … dirM cond1 .. condN. It will search the directory tree rooted at each diri, for i = 1 to M, all files matching conditions cond1 to condN evaluated from left to right.

Let’s see some examples:

  1. find /bin -links +1
    Searches files in /bin and its subdirectories having 1 or more hard links.
  2. find /bin -links +1 -type f
    Idem, but only matches regular files (-type f).
  3. find -size +8k -printf ‘%p %s\n’
    If no directory root is given, the default is . (the working one). This command seeks files whose size is at least 8KB and writes its name and size.
  4. find . -name core -exec rm -i {} \; -print
    Looks for files called «core» (-name core), asks for confirmation to delete them (-exec rm -i {} \;) and, after all, prints their name (-print). Notice that you can run any command with «-exec». In rm -i, -i stands for «Ask for a confirmation», and «{}» means «the file matching the conditions». «-exec» must be closed with «\;».
  5. find /usr/include -name ‘*.h’ -exec grep -H SIGCHLD {} \;
    Looks from /usr/include on all files with the extension .h (-name ‘*.h’, with quotes to avoid the shell understanding the * as a metacharacter and letting the find command use it) and having the string «SIGCHLD». That is, for each file that has matched the conditions, «grep -H SIGCHLD» is run.
  6. find -atime +1 -type f -exec mv {} TMP \;
    Moves files that haven’t been accessed today (-atime +1) to the dir called TMP, in our working directory.

Thanks FIB.


Entra