Comment puis-je obtenir la taille de stdin?

8

Je suis sur le point de compresser un grand répertoire et je veux savoir exactement quelle sera la taille du fichier résultant.

J'ai essayé d'utiliser du:

$ tar -cv dir | du -h -
du: cannot access '-': No such file or directory

J'ai ensuite essayé d'utiliser la version de fichier de '-':

$ tar -cv dir | du -h /dev/stdin
1.0K

Je suis certain que ce nombre n'est pas exact. Comment puis-je obtenir la taille de stdin?

strugee
la source

Réponses:

10

tl; dr :tar -cv dir | wc -c - | cut -d' ' -f 1 | awk '{print $1/1000"K"}'

dune compte pas réellement la taille du fichier lui-même. Il demande simplement au noyau d'interroger le système de fichiers, qui garde déjà une trace de la taille du fichier. C'est pourquoi c'est si rapide. Pour cette raison, et le fait que vous comptiez un flux, pas un fichier, dune fonctionne pas. Je suppose que 1.0Kc'est une taille codée en dur pour /dev/std*dans le noyau.

La solution est d'utiliser wc -c, qui compte les octets lui-même au lieu d'interroger le noyau:

$ tar -cv dir | wc -c

Si vous souhaitez une sortie similaire à du -h:

$ tar -cv dir | wc -c | awk '{print $1/1000"K"}'

Le awktransforme le nombre en un résultat lisible par l'homme.

strugee
la source
8
Notez que si vous omettez simplement wcle superflu, -vous n'avez pas non plus besoin de la cutcommande suivante .
Janis
1
1.0K est la taille de bloc de stdin.
Cody Allan Taylor
6

Avec GNU, tarvous pouvez simplement faire:

tar --totals -c . >/dev/null

... qui rendra la sortie comme ...

Total bytes written: 5990400 (5.8MiB, 5.5GiB/s)

... sur stderr. De même, avec n'importe quel tar (ou flux) que vous pouvez utiliser ddpour fournir un rapport sur le nombre d'octets. Cela peut être préférable ou non wc, mais par dddéfaut à une taille de bloc de 512 octets - qui est identique à tarla taille de bloc de. Si le PIPE_BUF de votre système est suffisamment grand, vous pouvez même étendre ddla taille de bloc de la correspondance avec tarla taille d'enregistrement de - qui est de 20 blocs ou 10240 octets. Comme ça:

tar -c . | dd bs=bx20 >/dev/null
585+0 records in
585+0 records out
5990400 bytes (6.0 MB) copied, 0.0085661 s, 699 MB/s

Cela peut ou non offrir une solution plus performante que wc.

Dans les deux ddet les tarcas d' utilisation vous ne devez pas disposer réellement du cours d' eau, cependant. Je redirige vers /dev/nullci-dessus - mais j'aurais pu aussi facilement rediriger vers un fichier et toujours recevoir le rapport sur sa taille au moment où il a été écrit.

mikeserv
la source
Dans le cas où le fichier est écrit sur le disque, il ne serait pas utile de déterminer séparément la taille puisque ces informations sont stockées avec le fichier. (+1) pour le gain de performance attendu de dd(par rapport à wc).
Janis
1
@Janis - peut-être vrai dans le cas le plus simple - mais imaginez plutôt que ddla sortie est transmise - à un compresseur, par exemple - et pour une raison quelconque, vous trouvez souhaitable de connaître à la fois la taille brute de l'archive et celle compressée. Il est également utile d'obtenir un rapport instantané sur le nombre d'enregistrements - ce tarn'est pas seulement une archive, mais un format de flux. Il peut être utilisé autrement que simplement en enregistrant dans un groupe de fichiers dans un autre fichier. Il est souvent utile pour bloquer un flux avant de le modifier. À chacune de ces limites d'enregistrement se trouve un bloc entier de NUL.
mikeserv
5

Je suggère:

tar cf - dir | wc -c

Un simple c(aucun interligne -n'est requis) est utilisé pour créer une tararchive, fspécifie un fichier de sortie et -indique qu'il s'agit d' une sortie standard . (Notez que si vous voulez juste la taille et il y a beaucoup de fichiers sous dir vous pouvez plutôt Omettre tar« s vpour des raisons de performance.)

Janis
la source
@mikeserv; Je semble me rappeler que j'ai travaillé avec tars dans le passé où la spécification d'un fichier tar (donc fet -) était nécessaire. - Je viens de le chercher; sans f -le tarsupposé /etc/mt0par défaut.
Janis
1
Je l'ai cherché dans un livre que j'ai utilisé comme manuel à l'époque, et je pense qu'il était basé sur SysV R4. Peu de gens se souviennent certainement de ce /etc/mt0qui signifie réellement - "bande magnétique" ;-) Je serais intéressé par le tarcomportement de Solaris (parce que Solaris est l'un des systèmes d'exploitation contemporains connus pour contenir encore des choses très anciennes /bin).
Janis
@mikeserv; PS: Le livre mentionne "UNIX Programmers Manual Volumes 1, 2A, 2B" d' AT & T comme source (mais pas de date de manuel ni de version UNIX, cependant; mais cela doit être du début des années 1980, 1983, ou plus).
Janis
Avez-vous déjà vu ça ? Sans rapport - mais je viens de le trouver aujourd'hui et j'ai pensé que cela pourrait vous plaire.
mikeserv
Je ne comprends pas très bien en quoi cette réponse est différente de la mienne. est-ce la présence du -fdrapeau tar?
strugee
1

Le libellé de votre question se prête aux tar ... | wc -créponses ci-dessus. J'ai lu à l'origine votre question en supposant silencieusement que vous vouliez que la taille soit signalée lors de la création du fichier tar (peut-être que la sortie de tar était alors acheminée via une liaison réseau?).

Dans ce cas, je suggère pv- visionneuse de tuyaux. J'en ai vu des références mais je n'ai pas encore eu l'occasion de jouer avec.

Références

Jeff Schaller
la source