2010-12-15 5 views
1
TMP="$$.FILE" 

#Process puts contents into TMP 

cat "$TMP" | sort | head > "$TMP" 

Je me suis déjà assuré que le fichier n'était pas vide pour commencer. Sans le > "$TMP", il sort quelque chose, mais quand il est à nouveau stocké dans le même fichier, c'est vide. Quelle pourrait être la raison?Pourquoi le fichier est-il vide?

Répondre

2

Ces processus s'exécutent tous en parallèle, donc la commande head tronque le fichier avant que cat ne puisse le lire.

Pour obtenir le résultat souhaité, vous devez écrire la sortie de tri dans un fichier différent, puis déplacer celle-ci par-dessus l'original.

cat "$TMP" | sort | head > "$TMP".new 
mv "$TMP".new "$TMP" 
+0

+1 - Merci – Strawberry

+0

'sorte "$ TMP" | HEAD> "$ TMP" .new && mv "$ TMP" .new "$ TMP"' gardera de désorganiser le fichier! s'il y a une erreur (et il donne 'cat' un repos). –

3

Vous ne pouvez pas écrire et lire dans un fichier en même temps. Voici à peu près ce qui se passe:

  1. > "$TMP" provoque l'ouverture du fichier en écriture, ce qui tronque également le fichier.
  2. cat "$TMP" lit maintenant le fichier vide.
  3. Le fichier reste vide.

Les commandes qui prétendent modifier un fichier en place effectuent en fait un peu de brassage de fichiers temporaires sous les couvertures. Par exemple, sed -i va traiter un fichier d'entrée et enregistrer les résultats à input.tmp, puis à mv input.tmp input à la fin pour écraser l'original. Vous devriez suivre ce modèle.

+0

Je vois, donc ce qui est une solution autour d'elle? Créer un autre fichier TMP? – Strawberry

1

Le dernier canal tronque le fichier lu par le premier canal, avant que quoi que ce soit ne se produise réellement. Donc ce qui se passe est cat essaie de lire un fichier que l'appel à head immédiatement tronqué. C'est la cause des problèmes ici; l'opérateur > est un opérateur shell qui signifie « tronquer ce fichier tout de suite et ensuite le processus écrire sa sortie standard dans le fichier.

Sur le même sujet, vous n'avez pas besoin cat ici.

Essayez ceci:

TMP="$$.FILE"  
sort <"$TMP" | head > "$TMP.tmp" 
mv "$TMP.tmp" "$TMP"