Newsgroup: it.comp.os.linux.iniziare
Titolo: bash: eliminare il contenuto del file

crivere su un file ï¿œ semplice
 
echo abc > 123.txt
 
ma se volessi fare il cleaning, cioï¿œ eliminare il contenuto (non il 
file, ma solo il contenuto), cioï¿œ avere un file vuoto (0 byte)?

 crivere su un file ï¿œ semplice
 
cioï¿œ 'scrivere', pardon :-p

 file, ma solo il contenuto), cioè avere un file vuoto (0 byte)?
 
$ > 123.txt
 
oppure se vuoi essere più verboso (inutilmente) ma fare la stessa cosa:
 
$ cat /dev/null > 123.txt
 
-- 
Massimo Bacilieri AKA Crononauta


se non ti interessa la data di creazione anche
$rm 123.txt
$touch 123.txt
 

 $touch 123.txt
 
buono a sapersi

 $touch 123.txt
 
Azz tu per uccidere le zanzare tiri una granata nella stanza e aspetti 
il botto, vero? ;-)



Se servisse a farle fuori tutte si', volentieri.. le odio!
Per il rm e touch, dici che e' troppo oneroso?
Sono ignorante in merito, ma sono molto curioso e mi piace imparare.
Ciao diego

 Sono ignorante in merito, ma sono molto curioso e mi piace imparare.
 
maestra: Pierino cancella la lavagna.
pierino: Buttiamola dalla finestra e compriamone una nuova.
 

 Per il rm e touch, dici che e' troppo oneroso?
 
Dipende dalla situazione.
 
Vi possono essere situazioni in cui "> file" e`
piu` lento di "rm" + "altro".
 
Se poi hai diversi file, basta un solo "rm" per
farli fuori tutti (avendo, poi, una lista per
ricrearli, ovviamente).
 
Ad es. avendo 1000 file, da "file_0" a "file_999"
gia` esistenti (e magari piuttosto grandi) non
saprei cosa sia piu` veloce tra:
 
for i in `seq 0 999`
do
  > "file_$i"
done
 
e
 
rm file_*
for i in `seq 0 999`
do
  > "file_$i"
done
 
 
Se pero` hai uno o pochi file, di solito "> file"
e` meglio.
 
bye,
 
-- 
 
piergiorgio

 pierino: Buttiamola dalla finestra e compriamone una nuova.
 
adesso non diciamo sciocchezze. non stai buttando via nulla.
 

 ...Se l'OP chiede di cancellare il contenuto di un file **SENZA*** 
cancellare il file è perché ha qualche buona ragione per farlo, 
probabilmente perché vuole preservare l'inode, e mi vengono in
mente tantissime situazioni dove questo è necessario (giusta 
l'osservazione di rootkit). Per cui ``rm... touch...'' è una /boutade/
e tu stai semplicemente offendendo l'intelligenza del gruppo
continuando su questa linea. 
 
Altolà! Ferma le macchine e collega il cervello prima di ripartire.
 
Se l'OP chiede di cancellare il contenuto di un file **SENZA*** 
cancellare il file è perché ha qualche buona ragione per farlo, 
probabilmente perché vuole preservare l'inode, e mi vengono in
mente tantissime situazioni dove questo è necessario (giusta 
l'osservazione di rootkit). Per cui ``rm... touch...'' è una /boutade/
e tu stai semplicemente offendendo l'intelligenza del gruppo
continuando su questa linea. 
 
L'intelligernza su USENET è tanto rara...
 
 
 


 
quando un file si elimina, equivale a buttarlo via, secondo la mia opinione

 e` meglio.
 
molto meglio!!!
 

 L'intelligernza su USENET è tanto rara...
 
pienamente d'accordo
 


 
 
 
Sono restato incuriosito da questa tesi
E quindi poichè la curiosità è un sfizio da togliersi subito ecco i fatti:
 
 
  function create_1M { for i in $(seq 0 $1);do perl -e 'print 
"0"x(1024*1024)' > file_$i; done }
 
function t1() { for i in $(seq 0 $1); do > file_$i;done }
 
function t2() { rm file_*; for i in $(seq 0 $1); do > file_$i;done }
 
mkdir tmp && cd tmp
 
create_1M 5000  # crea 5000 file da 1M
time t1 5000
 
real	0m0.560s
user	0m0.052s
sys	0m0.480s
 
create_1M 5000
time t2 5000
 
real	0m0.651s
user	0m0.264s
sys	0m0.384s
 
 
Per fare le cose per bene occorrerebbe ripetere i test piu volte 
compreso sul numero dei files e sulla loro grandezza
 
 
 
 
 
 

 quindi secondo te per fare una modifica è meglio ricreare il file da capo?
 
se sul file ci spari uno stream non lo stai modificando, lo stai
sovrascrivendo in toto. 
se ci scrivi con accesso random allora lo stai modificando. 
detto questo, che dal punto di vista efficienza costi meno cancellare e
ricreare un file vuoto rispetto a sovrascrivere un file esistente non è
una opinione mia. poi ripeto, ci possono essere decine di ragioni per cui
un file non si può cancellare.
 

 L'intelligernza su USENET è tanto rara...
 
Pare di si, leggendo questo post.
 
bye,
 
-- 
 
piergiorgio

 nome ad altre applicazioni; le conseguenze potrebbero essere disastrose
 
Ma il significato della parola "dipende" e`
sconosciuto da queste parti?
 
Ovviamente vi sono casi in cui una cosa e`
meglio dell'altra.
 
Poi, tu, sei sicuro che "> file" non faccia
proprio un "rm" + "touch"?
 
Detto altrimenti, sei sicuro che "> file"
sia un'operazione atomica?
 
bye,
 
-- 
 
piergiorgio

 compreso sul numero dei files e sulla loro grandezza
 
Dipende anche da che FS c'e` sotto.
 
bye,
 
-- 
 
piergiorgio


Certo, i test sono a parità di filesystem
 

 Lo è, è solo una open oppure truncate
 
Sei sicuro? Voglio dire, hai una documentazione
attendibile su questo?
 
Non sto scrivendo il contrario, cioe` non sto
sostenendo che non sia atomica, ma l'esperienza
mi dice che spesso e volentieri le cose _non_
sono come ci si aspetta siano...
 
bye,
 
-- 
 
piergiorgio

 Certo, i test sono a parità di filesystem
 
Intendo che, come hai scritto tu, cioe` che
si devono testare diversi file, con dimensioni
diverse, allo stesso modo si dovrebbero testare
filesystem diversi.
 
Alcuni FS hanno "rm" particolarmente lento o
particolarmente veloce.
 
bye,
 
-- 
 
piergiorgio

Addi' 27 nov 2013, Piergiorgio Sartor scrive:

Al riguardo sapete dirmi una cosa curiosa: file grossi (qualche giga,
sono iso di dvd oppure film di 1 o 2 giga) certe volte con rm vengono
cancellati istantaneamente, altre ci mettono molto e si sente il disco
fisso girare. Perche'?
 
-- 
Tanti saluti
 


Si,ma al di la del filsystem buttiamo fuori un po di logica
 
Fare questi passi
 
unlink + open + close
 
 
oppure
 
 
truncate (o open truncate + close)
 
 
 
capisci che la truncate da sola è certo piu veloce
Nel primo caso la open deve pure creare l' inode che unlink ha 
cancellato e che la truncate non ha bisogno di fare se il file esiste già
 
 
 
 
 
 

 In linux la open su un file è atomica e anche truncate
 
"open" e "truncate" si, ma sappiamo cosa fa bash?
 
Se uno vuole essere sicuro dell'atomicita`, deve
assicurarsi della cosa.
Quindi "truncate" come comando o procedure simili.
Affidarsi a bash, perche` "sembra logico" e` un
po' rischioso.
 
bye,
 
-- 
 
piergiorgio

 fisso girare. Perche'?
 
Su ext?
Che io sappia devi farsi il giro degli inode
per vedere cosa de-allocare.
 
Ora, se la lista e` in gia` in RAM (cache),
sicuramente e` piu` veloce.
 
Potrei anche sospettare che il livello di
indirezione negli inode possa pesare.
Questo e` un pensiero libero, pero`... :-)
 
bye,
 
-- 
 
piergiorgio

 cancellato e che la truncate non ha bisogno di fare se il file esiste già
 
Certo, ho scritto forse il contrario?
 
Non discuto che una chiamata a "truncate()" sia
piu` veloce di "unlink()", "creat()" ed "open()"
(se vogliamo anche "creat()").
 
Quello che ho scritto (in questo post) e` che, in
funzione del FS, e` possibile che "rm" ("unlink()")
abbia prestazioni completamente diverse.
 
Questo non ha nulla a che vedere con il fatto che
"truncate()" sia piu` appropriata prestazionalmente.
 
bye,
 
-- 
 
piergiorgio


quale filesystem ?
 
Cosi su due piedi mi viene i  mente una tabella dei free sectors molto 
frammentata ma mi sembra alquanto strano
 
 

 altro
 
Ho fatto un "grep" di "truncate" sui sorgenti
di bash 4.2 ed ha trovato:
 
$ find . -type f -name \*.[ch] -print0 | xargs -0 grep truncate
./redir.c:     will fail.  Make sure that we do not truncate an existing
file.
./bashhist.c:     Note that the history file is automatically truncated
to the
./variables.c:      d = xd;			/* truncate */
./variables.c:   numeric, truncate the history file to hold no more than
that many
./variables.c:	      history_truncate_file (get_string_value
("HISTFILE"), hmax);
./lib/readline/history.h:extern int history_truncate_file PARAMS((const
char *, int));
./lib/readline/histfile.c:history_truncate_file (fname, lines)
./lib/readline/histfile.c:  /* Don't try to truncate non-regular files. */
./lib/readline/histfile.c:      goto truncate_exit;
./lib/readline/histfile.c:      goto truncate_exit;
./lib/readline/histfile.c:      goto truncate_exit;
./lib/readline/histfile.c:      goto truncate_exit;
./lib/readline/histfile.c:      goto truncate_exit;
./lib/readline/histfile.c:     number of lines we want to truncate to,
so we don't need to do
./lib/readline/histfile.c:     truncate to. */
./lib/readline/histfile.c:      ftruncate (file, chars_read - (bp -
buffer));
./lib/readline/histfile.c: truncate_exit:
./lib/readline/histfile.c:    if (ftruncate (file, buffer_size+cursize)
== -1)
 
"ftruncate()" e` usata per la "histfile" in "readline",
ma non in "redir.c".
 
Riguardo "unlink()":
 
$ find . -type f -name \*.[ch] -print0 | xargs -0 grep unlink
./subst.h:extern void unlink_fifo_list __P((void));
./subst.h:extern void unlink_fifo __P((int));
./subst.h:extern void unlink_new_fifos __P((char *, int));
./redir.c:      unlink (filename);
./redir.c:      unlink (filename);
./redir.c:  if (unlink (filename) < 0)
./execute_cmd.c:  /* don't unlink fifos if we're in a shell function;
wait until the function
./execute_cmd.c:    unlink_fifo_list ();
./execute_cmd.c:	  unlink_fifo_list ();
./execute_cmd.c:  unlink_fifo_list ();
./execute_cmd.c:	  unlink_fifo_list ();
./execute_cmd.c:	  unlink_fifo_list ();
./execute_cmd.c:      unlink_fifo_list ();
./execute_cmd.c:	  unlink_fifo_list ();
./execute_cmd.c:        unlink_fifo_list ();
./sig.c:  unlink_fifo_list ();
./sig.c:  unlink_fifo_list ();
./sig.c:  unlink_fifo_list ();
./shell.c:  unlink_fifo_list ();
./shell.c:      unlink_fifo_list ();
./subst.c:/* Named pipes must be removed explicitly with `unlink'.  This
keeps a list
./subst.c:   of FIFOs the shell has open.  unlink_fifo_list will walk
the list and
./subst.c:   unlink all of them. add_fifo_list adds the name of an open
FIFO to the
./subst.c:unlink_fifo (i)
./subst.c:      unlink (fifo_list[i].file);
./subst.c:unlink_fifo_list ()
./subst.c:	  unlink (fifo_list[i].file);
./subst.c:      unlink_fifo_list ();
./subst.c:      unlink_fifo (i);
./subst.c:    unlink_fifo (i);
./subst.c:unlink_fifo (fd)
./subst.c:unlink_fifo_list ()
./subst.c:    unlink_fifo (i);
./subst.c:      unlink_fifo_list ();
./subst.c:      unlink_fifo (i);
./subst.c:    unlink_fifo (i);
./subst.c:      unlink_fifo_list ();
./eval.c:      unlink_fifo_list ();
./lib/sh/rename.c:      if (unlink (to) < 0 && errno != ENOENT)
./lib/sh/rename.c:  if (unlink (from) < 0 && errno != ENOENT)
./lib/sh/rename.c:      unlink (to);
./lib/readline/util.c:  unlink(fnbuf);
./examples/loadables/unlink.c:/* unlink - remove a directory entry */
./examples/loadables/unlink.c:unlink_builtin (list)
./examples/loadables/unlink.c:  if (unlink (list->word->word) != 0)
./examples/loadables/unlink.c:      builtin_error ("%s: cannot unlink:
%s", list->word->word, strerror (errno));
./examples/loadables/unlink.c:char *unlink_doc[] = {
./examples/loadables/unlink.c:struct builtin unlink_struct = {
./examples/loadables/unlink.c:	"unlink",		/* builtin name */
./examples/loadables/unlink.c:	unlink_builtin,		/* function implementing
the builtin */
./examples/loadables/unlink.c:	unlink_doc,		/* array of long
documentation strings. */
./examples/loadables/unlink.c:	"unlink name",		/* usage synopsis;
becomes short_doc */
./examples/loadables/ln.c:  /* If -f was specified, and the destination
exists, unlink it. */
./examples/loadables/ln.c:  if ((flags & LN_UNLINK) && exists && unlink
(dst) != 0)
./examples/loadables/ln.c:      builtin_error ("%s: cannot unlink: %s",
dst, strerror (errno));
./examples/loadables/ln.c:	"file.  The -f option means to unlink any
existing file, permitting",
./builtins/mkbuiltins.c:  unlink (to);
./builtins/mkbuiltins.c:  unlink (from);
 
Ci sono tre chiamate in "redir.c".
 
bye,
 
-- 
 
piergiorgio

 abbia prestazioni completamente diverse.
 
 
Certo, sono d'accordo
Ogni file system organizza lui la lista dei blocchi liberi, la tabella 
degli inode e la sua organizzazione per quanto riguarda la lista dei 
blocchi allocati


 frammentata ma mi sembra alquanto strano
 
Moltissimo: certe volte anche oltre il 40%. Anch'io pensavo alla
frammentazione e anche Piergiorgio mi sembra che dice la stessa cosa,
anche se parla di inode.
 
-- 
Tanti saluti
 

 stupito se facesse in altro modo
 
Come da altro post, ho "greppato" i sorgenti.
 
Ovviamente _non_ e` una prova, ma gli
indizi circostanziali puntano verso
"unlink()" + "open()"...
 
bye,
 
-- 
 
piergiorgio

 Prova a cercare O_TRUNC
 
$ find . -type f -name \*.[ch] -print0 | xargs -0 grep O_TRUNC
./redir.c:  flags &= ~O_TRUNC;
./bashhist.c:	      file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
./make_cmd.c:      temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
./lib/sh/tmpfile.c:#define BASEOPENFLAGS	(O_CREAT | O_TRUNC | O_EXCL |
O_BINARY)
./lib/readline/histfile.c:  if (bp > buffer && ((file = open (filename,
O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
./lib/readline/histfile.c:      /* BeOS ignores O_TRUNC. */
./lib/readline/histfile.c:  mode = overwrite ?
O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
./lib/readline/histfile.c:  mode = overwrite ?
O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
./examples/loadables/tee.c:  fflags = append ? O_WRONLY|O_CREAT|O_APPEND
: O_WRONLY|O_CREAT|O_TRUNC;
./examples/loadables/getconf.c:#ifdef _PC_NO_TRUNC
./examples/loadables/getconf.c:  { "_POSIX_NO_TRUNC",		PATHCONF,
_PC_NO_TRUNC		},
./examples/loadables/getconf.c:    case _PC_NO_TRUNC:
./examples/loadables/getconf.c:#ifdef _POSIX_NO_TRUNC
./examples/loadables/getconf.c:      return _POSIX_NO_TRUNC;
./examples/loadables/getconf.h:#define _PC_NO_TRUNC             8
 
Nota che in "redir.c" c'e` "~O_TRUNC" (not O_TRUNC), dal codice:
 
  /* If the file was not present (r != 0), make sure we open it
     exclusively so that if it is created before we open it, our open
     will fail.  Make sure that we do not truncate an existing file.
     Note that we don't turn on O_EXCL unless the stat failed -- if
     the file was not a regular file, we leave O_EXCL off. */
  flags &= ~O_TRUNC;
 
Pare sia una cosa diversa.
 
bye,
 
-- 
 
piergiorgio


Un altro metodo:
 
echo '> pippo' | strace bash -s 2> file.log
grep pippo file.log
 
 
 
 
 

On 2013-11-27 21:01, Piergiorgio Sartor wrote:
[...]
 
Attenzione, attenzione, in "make_cmd.c" c'e`
quanto segue:
 
  switch (instruction)
    {
 
    case r_output_direction:            /* >foo */
    case r_output_force:                /* >| foo */
    case r_err_and_out:                 /* &>filename */
      temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
      break;
 
Questo cambia tutto, e` molto probabile che
sia effettivamente "O_TRUNC".
 
bye,
 
-- 
 
piergiorgio

 grep pippo file.log
 
Buono questo, hai provato?
 
open("pippo", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
 
Questo conferma la tua ipotesi.
 
bye,
 
-- 
 
piergiorgio


si, anche a me (una ubuntu x64) da lo stesso risultato
 

 ...
 
Altolà! Ferma le macchine e collega il cervello prima di ripartire.
 
Se l'OP chiede di cancellare il contenuto di un file **SENZA*** 
cancellare il file è perché ha qualche buona ragione per farlo, 
probabilmente perché vuole preservare l'inode, e mi vengono in
mente tantissime situazioni dove questo è necessario (giusta 
l'osservazione di rootkit). Per cui ``rm... touch...'' è una /boutade/
e tu stai semplicemente offendendo l'intelligenza del gruppo
continuando su questa linea. 
 
L'intelligenza su USENET è tanto rara...
 

 L'intelligenza su USENET è tanto rara...
 
Evidentemente...
 
bye,
 
-- 
 
piergiorgio

 sia un'operazione atomica?
 
Sto facendo una hash dei tuoi post e la sto rinormalizzando per
ricavare dei terni da giocare al lotto, perché stai dando i numeri.
E se vinco non ti spetta nessuna percentuale.
 
 
 
 

 (non so quale dei due metodi usi la shell ma suppongo truncate)
 
E non serve la sfera di vetro o leggere i sorgenti per essere sicuro 
che sia proprio così. 
Che poi sia una operazione atomica non lo credo ma non importa,
questo fatto della operazione atomica è un'altra /boutade/
 
PS sto usando troppi francesismi, mi dite un'altra parola che 
significhi "stronzata"? ;-)

 nome ad altre applicazioni; le conseguenze potrebbero essere disastrose
 
Attento, stai andando su una strada scivolosa che non porta da 
nessuna parte. Smettila di fare masturbazioni mentali.
 
Un file temporaneo è un file temporaneo e basta, il suo nome non 
c'entra una cippa di cazzo, non significa niente e non dovrebbe 
succedere niente se un'altra applicazione lo usa; se invece questa 
ultima assunzione non è verificata hai dei grossi problemi di 
sicurezza a monte e fare trucchetti con cat non serve a niente.
 

 E se vinco non ti spetta nessuna percentuale.
 
Figurati,
 
bye,
 
-- 
 
piergiorgio

 significhi "......."? ;-)
 
"mallin.shetland"
 
bye,
 
-- 
 
piergiorgio

 od errori, ti prego di correggermi.
 
Non tanto inesattezze (che ci sono) od errori, solo il fatto che trovo
la questione noiosa, fuorviante, sterile, fuori tema, non rispondente 
al tema dell'OP.
 
Mi sono ripetuto? Ho detto due volte che la questione è OT È voluto, 
lo ho fatto apposta.
 
L'errore grosso è che "cat > $file" fa un rm e poi sovrascrive il file; 
quale coglione programmerebbe così il programma più semplice di UNIX, 
l'unico programma utile a  qualcosa che può essere scritto senza bug,
contravvenendo al principio "un programma fa una sola cosa e la fa bene"?
 
 

 ----
 
Buonanotte, ho di meglio da fare.
 

 contravvenendo al principio "un programma fa una sola cosa e la fa bene"?
 
Questo e` OT.
 
bye,
 
-- 
 
piergiorgio

 file, ma solo il contenuto), cio� avere un file vuoto (0 byte)?
 
Ho fatto una lettura veloce del thread, non mi pare ci sia questa
soluzione:
 
echo abc >123.txt
ll
totale 4
-rw-r--r-- 1 root root 4 28 nov 10:44 123.txt
 
echo "" >123.txt
ll
totale 4
-rw-r--r-- 1 root root 1 28 nov 10:46 123.txt
 
non credo che la redirezione cancelli il file (fatta con ">>" accoda
al file) per cui credo possa andare.
-- 
Ciao
Andrea Malfatti

 ...
 
Il comando giusto è:
 
echo -n > afile
 
Non cambia molto perché è proprio la redirezione che cancella il file quindi
tanto vale ``> afile'' più sintetico e più veloce (salvo smentite).
 
PS Ho già detto che sono questioni di lana caprina?

 sovrascrivendo in toto.
 
a anche in tal caso non mi pare che vanga fatta una cancellazione 
preventiva; parlo in generale...
 

 succedere niente se un'altra applicazione lo usa;
 
se lo usa per scrivervi innocentemente qualcosa (magari qualche bel 
codice che verrà interpretato, dall'applicazione principale, come 
comando distruttivo) non succede niente?
 

Addì  giovedì 28 novembre 2013 21:25 alex scrisse:

Effettivamente le mie parole sono ambigue e portano a fraintendimenti
altrimenti tu non meriteresti nessuna risposta.
 
Ora come si chiama il file non conta, cosa contiene non conta, quali
sono i suoi permessi conta poco, e qui la cosa importante, sta a te 
garantire che non ci siano problemi se un'altra applicazione usa il 
tuo stesso file. E questa è anche la mia imprecisione quel "dovrebbe"
in realtà significava: "non deve e sta a te fare in modo che non succeda
niente".
 
Ora ripeto: sta a te fare garantire che non ci siano problemi; ma creare,
cancellare e ricreare subito dopo un file temporaneo è il metodo migliore
per cercare guai. Sia ben chiaro che un file temporaneo deve essere 
creato una sola volta e distrutto dopo il suo uso; se ti servono due file
in momenti diversi è meglio, se possibile, aprirne uno, usarlo, troncarlo e
riutilizzarlo invece di metterti ad aprire e chiudere file a casaccio. questo è il senso del thread, tutte le altre cose che hai detto sono 
masturbazioni mentali.
 
 


 
eh già

 A prescindere...
 
mah.


 
 
 
Non per niente la directory /tmp ha il flag t impostato
 
Per le altre directory esistono i permessi ed i lock
 
 
[CUT]
 
 

 Per le altre directory esistono i permessi ed i lock
 
appunto

 Per le altre directory esistono i permessi ed i lock
 
Okay pero` io penso che se creo un file temporaneo vuol dire che per la
sua natura quando lo script termina non mi dovrebbe piu` servire, per
cui alla fine dello script lo cancello sempre, cioe`:
 
FILE_TEMP=$(mktemp)
.
.
.
rm ${FILE_TEMP}
 
Ti pare il mio un ragionamento corretto o dimentico/sbaglio qualcosa?
 
 
 
 
 
 


Questa è una tecnica ma non è molto sicura se il file temporaneo ha dei 
dati sensibili (esiste un certo tempo seppur piccolo tra la close e la rm)
 
Una  tecnica migliore è di aprirlo e fare un unlink sul descrittore del 
file
In questo modo il file non ha una entry nella directory a cui appartiene 
ma continua ad esistere in quanto è aperto
Quando verrà fatta la close il kernel automaticamente eliminerà il file
 
E' comunque una tecnica da usare a livello di C non a livello di bash
 
 
 
 
 
 
 

 E' comunque una tecnica da usare a livello di C non a livello di bash
 
.. e comunque io ne ho imparata una per me nuova. Grazie :-)
 

Addì  Sat, 30 Nov 2013 10:12:12 -0600 enoquick scrisse:

C'è lo sticky bit ma è solo un palliativo. Serve a poco. 
La tendenza attuale è usare le varie directory $HOME/tmp eventualmente
creando un utente di sistema per usare la sua directory privata per i 
file temporanei. Prevedo che la /tmp cadrà in obsolescenza ma non so 
mai sparirà. Certo alcune tecniche citate sono utili ma prima di tutto
non servono se non si adottano le precauzioni di base, cioè usare file
temporanei non prevedibili e in directory sicure e con i permessi giusti
e come seconda cosa qui non siamo su comp.os.unix.C.devel o simili, 
qua discutiamo della bash e sinceramente, anche se alcune cose sono 
giuste, enoquick, il resto sono masturbazioni mentali.
 


Facebook: Massimo Bacilieri

 dati sensibili (esiste un certo tempo seppur piccolo tra la close e la rm)
 
Scusa eh ma se uno mette dei dati sensibili in /tmp, ovvero in una 
cartella di "pubblico" accesso, è un cretino fatto e finito, a 
prescindere da tutto il resto!


 ...
 
Quoto e approvo
 

 impredicibili.
 
e non hai capito.
Creare un file, significa occupare un'area del file-system, dandole un nome.
Se io cancello quel file, rilascio quella locazione, che diventa 
disponibile per altri processi, che sfortunatamente potrebbero creare un 
file lo stesso nome (quel file non esiste quindi me lo posso creare), 
perchè no!
Per questo, o si provvede ricrearlo immediatamente, o se ne cancella 
solo il contenuto, con tutti i pro (sicurezza) e i contro (prestazioni 
minori)

 minori)
 
Non ti capisco proprio. La gente normale si masturba con Jenna Jameson, 
tu ti masturbi coi file temporanei.
 
De gustibus...


mi sembra che lo faccino più gli altri

 mi sembra che lo faccino più gli altri
 
fantozzi, facci lei...
 

 rm ${FILE_TEMP}
 
Questa mattina mi e` capitato di dover usare un file temporaneo e mi e`
venuta in mente una cosa:
 
facendo come ho scritto sopra il file viene cancellato nell'ultima
istruzione prima della chiusura ma se per qualche motivo (ad
esempio l'utente preme Ctrl + C) lo script si chiude in modo anomalo,
allora il file temporaneo rimane intatto.
 
Per ovviare ho trovato questa soluzione:
--------------------------------------------------
 
#!/bin/bash
 
trap 'unlink ${FILE_TEMP} ; exit' 0   1     2              3        15
# ==>                      Segnali:   HUP   INT (Ctl-C)    QUIT     TERM
# Cancella il file temporaneo se lo script viene interrotto
 
FILE_TEMP=$(mktemp)
sleep 12
unlink ${FILE_TEMP} ## rimuove il file temporaneo
 
--------------------------------------------------
 
Vi pare corretta o ci sono controindicazioni?
 
 

Addi' 17 dic 2013, M_M scrive:

Scusa ma se trap deve intervenire (cancellandolo) solo su ctrl-C, non ti
basta fare:
------------------
#!/bin/bash
 
trap 'unlink ${FILE_TEMP}' INT
 
FILE_TEMP=$(mktemp)
sleep 12
unlink ${FILE_TEMP}
------------------------
 
N.B. pero' che io te lo dico solo perche' l'avevo chiesto anch'io e sono
arrivato a questa conclusione, ma non fidarti troppo eh.
 
Per curiosita', mi dici perche' preferisci unlink a rm? anzi io li' ci
ho messo "rm -v" cosi' me lo dice.
 
-- 
Tanti saluti
 

 prescindere da tutto il resto!
 
Se non sbaglio (lo premetto perche` come tu sai non sono molto forte in
Bash ..), nulla vieterebbe di proteggere il file da occhi indiscreti con
 
umask 177
FILE_TEMP=$(mktemp)
 
 
 

 ho messo "rm -v" cosi' me lo dice.
 
Io manco conoscevo il comando unlink e l'ho scoperto in questo thread in
un messaggio di enoquick. Avevo salvato un file di prova che
l'utilizzava e che ora, visto che e` breve, ho ricliclato per postare
qui. :-)
 
 
 
 

 generalizzato.
 
Pero` vedo che usando 
trap 'unlink ${FILE_TEMP} ; exit' 0 1 2 3 15
anche senza, come invece ho fatto, mettere alla fine dello script un
comando per la rimozione del file temporaneo, quando lo script finisce
ed esce, il file viene cancellato.
 
 

Addi' 17 dic 2013, M_M scrive:

Si' ma infatti c'e' differenza, dando help trap si dovrebbe capire.
 
Io l'avevo fatto cosi' perche' dovevo uscire sempre e solo con ^C dal
download, e senza trap il ^C mi interrompeva lo script e quindi la riga
col rm non mi veniva eseguita mai.
Tu invece vuoi che sia eseguita anche senza ^C, quando esce normalmente
dopo i 12 secondi.
 
Guarda, ti copio lo script (che uso per vedere se l'adsl e' giu' e/o
lenta, perche' me lo chiedono gli altri che qui a casa sono collegati
col Mac e col Virus al mio stesso router)
-----------------
#!/bin/bash
 
NUM=7.3.0
URLO="
http://cdimage.debian.org/debian-cd/$NUM/i386/iso-dvd/de\
 
bian-$NUM-i386-DVD-1.iso"
cd /tmp/
trap 'echo
echo "                       Ora cancello il dvd da /tmp"
echo
rm -v /tmp/debian-$NUM-i386-DVD-1.iso' INT
 
wget $URLO
---------------------
 
Ebbene, se io aggiungo "rm -v /tmp/debian-$NUM-i386-DVD-1.iso" come
ultima riga dopo wget, allora dopo ^C cerca di cancellare l'iso che e'
gia' stata cancellata da trap. Guarda adesso l'ho aggiunta:
 
                       Ora cancello il dvd da /tmp
 
"/tmp/debian-7.3.0-i386-DVD-1.iso" rimosso
rm: impossibile rimuovere "/tmp/debian-7.3.0-i386-DVD-1.iso": File o dir
ectory non esistente
 
-- 
Tanti saluti
 


Non ho mai accennato al comando unlink (che è una brutta copia di rm)
ma alla omonima chiamata di sistema
 
 
 


rm -f <file>
 
se il file non esiste non viene emesso nessun messaggio di errore
 

Addi' 17 dic 2013, enoquick scrive:

Grazie buono a sapersi, ora capisco perche' lo usano spesso in alcuni
script.
 
-- 
Tanti saluti
 

 ma alla omonima chiamata di sistema
 
Scusa, avrei dovuto scrivere "l'ho scoperto in questo thread tramite un
messaggio di enoquick".
 
Avevi ben specificato che si tratta di una chiamata di sistema che si
usa in C.
 
Sono poi io che cercando ulteriori informazioni in rete su "unlink" ho
fatto la conoscenza di tale comando per Bash.
 
Ho letto prima il man, poi l'ho provato e il suo "porco" lavoro, cioe`
cancellarmi il file temporaneo. lo fa: cancella tramite libc che fa una
chiamata al sistema.
 
Dal 
coreutils.info
:
 
`unlink': Remove files via the unlink syscall
 
Mi sono chiesto perche` scrivi " è una brutta copia di rm" .
Forse perche` e` limitato alla cancellazione di file e non di directory?
A me e` sembrato che metterlo a cancellare il temp quando si esce, fosse
"la morte sua" :-)


Non servono le scuse, ho solo voluto fare una precisazione
 
Quanto al comando unlink è una rm molto semplificata
Non cancella le directory, non  ha praticamente opzioni e come argomenti 
accetta solo un file
Ha solo il vantaggio di essere più veloce di rm in quanto deve fare 
semplicemente una sola cosa
Forse il termine brutta copia non è appropriato, diciamo un rm 
semplificato all' osso
 
Anche rm,come unlink,  usa la chiamata di sistema unlink per cancellare 
un file non directory; in unix non esiste altro modo
 
 
 
 
 

 script.
 
A scopo didattico, una soluzione pulita (ma inutilmente complicata) sarebbe:
 
if [ -e $nomefile ]; then rm $nomefile; fi
 
che ottiene comunque esattamente lo stesso effetto di rm -f.


 che ottiene comunque esattamente lo stesso effetto di rm -f.
 
Adesso usero' rm -f, finora m'era rimasto un sacro terrore dai primi
tempi e non l'avrei mai usata. Certo che metterci il -f quando si da' a
mano non serve, a meno di dover cancellare molti file readonly.
 
-- 
Tanti saluti
 

 evitare l'eco in console dell'eventuale messaggio d'errore.
 
C'è una differenza, però.
La riga che ho citato - ribadisco: a scopo didattico - è equivalente a 
rm -f quando tratti un *singolo file*.
 
Se devi cancellare più file, o ricorrere dentro le dir, ecco che non 
funziona più, poiché dovresti fare un ciclo per testare ogni singolo 
file e cancellarlo uno per uno, una cosa mostruosa, tipo:
 
for f in *; do
if [ -e $f ]; then rm $f; f
done
 
e non abbiamo risolto la ricorsione... (e abbiamo comunque dei rischi 
relativi all'espansione di $f, che per esperienza ho visto riservare 
spiacevoli sorprese quando i nomi contengono p.e. degli spazi).
 
rm -rf *
invece risolve tutto in un colpo solo e senza rischi.



Per evitare le sorprese dati input esterni come i nomi di file andrebbe 
il tutto quotato
 
esempio:
 
rm -f "$f"
 
 

Addi' 19 dic 2013, Crononauta scrive:

Pero' negli script avevo l'esigenza di creare una directory di
parcheggio, ma di svuotarla (per evitare che mi venissero accodati i
file da creare) se per caso ci fosse gia'. Facevo cosi':
--------
if [ -d /tmp/FAsub ]; then
rm -r /tmp/FAsub
fi
mkdir /tmp/FAsub
-------
 
Adesso faro': rm -rf /tmp/FAsub; mkdir /tmp/FAsub
 
Cioe': perche' tu fai tutto il ciclo for? vuoi conservare intatta la
struttura di tutto il ramo di directory e subdirectory?
Perche' in questo caso in altri script facevo cosi':
------------
if [ -d mio_ramo ]; then
tree -dif --noreport mio_ramo > /tmp/pippo
rm -r mio_ramo
for j in $(cat /tmp/pippo); do mkdir $j; done
fi
---------
 
Che e' piu' o meno del genere criticato proprio in questo thread per
azzerare un file.
 
-- 
Tanti saluti
 

 azzerare un file.
 
infatti è un delirio :-p


 rm -f "$f"
 
* (tutti i file) *non è* un input esterno però.
 
for i in *; do echo $i; done
funziona perfettamente anche con gli spazi nel nome, perché * è un 
operatore di directory.
I problemi ce li hai se vuoi usare quel $i per altre funzioni, allora 
inciampi nell'espansione della variabile.
Ovvero for i in *; do rm $i; done
*non* funziona se ci sono spazi nel nome. Ma attento, le virgolette non 
sono la panacea. Se infatti ci fosse un nome con delle virgolette (è 
lecito), otterresti risultati impredicibili. Quindi occhio...
