Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 18/03/2010, à 22:10

congelli501

pipe vers tar

Bonjour smile,

Je souhaiterais pouvoir envoyer le résultat d'une commande vers un fichier d'une archive tar.

Plus simplement, faire quelque chose de ce genre:

echo "Contenu du fichier" | tar --ajouterStdinAuTar "/cheminDansLeTar/leNomDuFichier"

L'archive tar comporterais alors un nouveau fichier : leNomDuFichier situé dans le sous dossier cheminDansLeTar.

Je ne veux pas passer par un fichier sur le disque, car le fichier à archiver est très lourd (8 Go).

Le man de tar ne donne pas beaucoup d'espoir, mais existe-t-il une autre méthode ou une autre commande permettant de faire quelque chose de tel ?

Merci d'avance big_smile

Hors ligne

#2 Le 19/03/2010, à 10:31

genma

Re : pipe vers tar

Pour archiver gzip serait plus approprié :

Si aucun fichier n'est précisé, gzip tente de compacter les données en provenance de l'entrée standard :
    ls -laR $HOME | gzip > list.gz


"Lorsque tu as découvert le libre, tu sais que tu ne pourras plus jamais revenir en arrière".
Utilisateur d'Ubuntu depuis la version 4.10 !
Mon blog ?      https://blog.genma.fr
Mon twitter?     http://twitter.com/genma

Hors ligne

#3 Le 19/03/2010, à 14:06

credenhill

Re : pipe vers tar

hello
A un fichier archive.tar, tu veux ajouter des données qui sortent d'une commande  ? archive.tar est un fichier sur le disque ? si oui ca va être difficile de ne pas accéder le disque
il y a l'option -u
-u, --update
              only append files that are newer than copy in archive

Dernière modification par credenhill (Le 19/03/2010, à 14:07)

Hors ligne

#4 Le 19/03/2010, à 17:11

sputnick

Re : pipe vers tar

Pour placer une arbo dans une archive via pipes, voir pax ou cpio


Je sais, un peu partout, tout le monde s'entretue, c'est pas gai, mais d'autres s'entrevivent, j'irai les retrouver. Jacques Prévert
https://sputnick.fr

Hors ligne

#5 Le 20/03/2010, à 13:18

congelli501

Re : pipe vers tar

Bonjour,
Aucune de ces commandes ne me va : je ne veux pas ajouter des fichiers dont les noms sont précisés dans l'entré standard mais bien ajouter le contenu de l'entré standard.

J'ai finalement créer mon format de fichier qui correspond à ce que je veux faire.
Il est très limité:
- header de taille fixe (nombre de fichiers limités).
- Pas de gestion des droits.
- L'implémentation actuelle permet juste d'ajouter des fichiers, de les lister, de connaitre leur taille et de les extraire.

Mais il a l'avantage d'être rapide et simple.

Je vous poste le code de gestion des archives, si ça intéresse quelqu'un :

#!/bin/bash
# Script by Congelli501
# Version : 0.0.1

BLOC_SIZE=512 # 0.5k
HEADER_MAX_SIZE_BLOC=8 # 4k
HEADER=""
START_OF_HEADER_STRING="#C501tar_HEADER_v1.0.0#"
END_OF_HEADER_STRING="#END_OF_HEADER#"
HEADER_SEPARATOR="|"
CURRENT_ARCHIVE_SIZE_BLOC=0

# c501tarInit() # _private_
# Args:
#  - $1 : c501tar filename

function c501tarInit() # _private_
{
	FILENAME="$1"

	if [ ! -f "$FILENAME" ]; then
		echo "Error, c501tarInit() : \"$1\" does not exist !" >&2
		return 1
	fi

	CURRENT_ARCHIVE_SIZE_BLOC=$(du -sb "$FILENAME" | cut -d$'\t' -f1)
	(( CURRENT_ARCHIVE_SIZE_BLOC /= BLOC_SIZE ))
	
	# Verif
	firstBytes=$(dd if="$FILENAME" bs="$(echo "$START_OF_HEADER_STRING" | wc --bytes)" count=1 2> /dev/null)
	if [ "$firstBytes" != "$START_OF_HEADER_STRING" ]; then
		echo "Error, c501tarInit() : \"$1\" is not a valid c501tar file !" >&2
		return 1
	fi
	
	HEADER=""
	# Lecture de l'header
	while read LINE && [ "$LINE" != "$END_OF_HEADER_STRING" ] ; do
		if [ "$LINE" != "$START_OF_HEADER_STRING" ]; then
			HEADER="$HEADER""$LINE"$'\n'
		fi
	done < "$FILENAME"
	
	return 0
}

# c501tarCreate()
# Args:s
#  - $1 : c501tar filename

function c501tarCreate()
{
	FILENAME="$1"

	if touch "$FILENAME"; then
		dd if=/dev/zero of="$FILENAME" bs="$BLOC_SIZE" count=$HEADER_MAX_SIZE_BLOC 2> /dev/null
		echo -e "${START_OF_HEADER_STRING}\n${END_OF_HEADER_STRING}" | dd conv=notrunc of="$FILENAME" 2> /dev/null
	else
		echo "Error, c501tarCreate() : Can't create file \"$$1\" !" >&2
		return 1
	fi
}

# Ajout de fichiers...
# c501tarAddFile()
# Args:
#  - stdin: the file to add.
#  - $1 : c501tar filename
#  - $2 : filename to add in the c501tar, must no contain '$HEADER_SEPARATOR'

function c501tarAddFile()
{
	FILENAME="$1"

	if ! c501tarInit "$FILENAME"; then
		echo "Error, c501tarAddFile() : c501tarInit() failed !" >&2
		return 1
	fi

	filenameToAdd="$2"
	
	fileToAddSize=$(( dd of="$FILENAME" conv=notrunc bs=$BLOC_SIZE seek="$CURRENT_ARCHIVE_SIZE_BLOC" ) 2>&1 | tail -n 1 | cut -d ' ' -f 1)
	# On conpléte l'archive jusqu'à atteinde $BLOC_SIZE...
	(( bytesToAdd = BLOC_SIZE - (fileToAddSize % BLOC_SIZE) ))
	dd if=/dev/zero bs=1 count="$bytesToAdd" >> "$FILENAME" 2> /dev/null
	
	HEADER="$HEADER""${filenameToAdd}${HEADER_SEPARATOR}${CURRENT_ARCHIVE_SIZE_BLOC}${HEADER_SEPARATOR}${fileToAddSize}"$'\n'
	
	# Ecriture du header
	newHeaderSizeBytes=$(echo "$HEADER" | wc --bytes)
	(( maxHeaderSizeBytes = HEADER_MAX_SIZE_BLOC * BLOC_SIZE ))
	
	if [ "$newHeaderSizeBytes" -le "$maxHeaderSizeBytes" ]; then # =<
		dd conv=notrunc if=/dev/zero of="$FILENAME" bs=$BLOC_SIZE count=$HEADER_MAX_SIZE_BLOC 2> /dev/null
		echo -e "${START_OF_HEADER_STRING}\n${HEADER}${END_OF_HEADER_STRING}" | dd conv=notrunc of="$FILENAME" 2> /dev/null
	else
		echo "Error, c501tarAddFile() : Header too big !" >&2
		return 1
	fi
}

# c501tarListFiles()
# Args:
#  - $1 : c501tar filename
#  - stdout: the file list.

function c501tarListFiles()
{
	FILENAME="$1"
	
	if ! c501tarInit "$FILENAME"; then
		echo "Error, c501tarListFiles() : c501tarInit() failed !" >&2
		return 1
	fi
	
	while read LINE; do
		if [ -n "$(echo "$LINE" | grep "$HEADER_SEPARATOR")" ]; then	
			echo "$LINE" | cut -d"$HEADER_SEPARATOR" -f1
		fi
	done < <( echo "$HEADER" )
}

# getFileSize()
# Args:
#  - $1 : c501tar filename
#  - $2 : file to search
#  - stdout: the file size.

function getFileSize()
{
	FILENAME="$1"
	
	if ! c501tarInit "$FILENAME"; then
		echo "Error, getFileSize() : c501tarInit() failed !" >&2
		return 1
	fi
	
	tarFileName="$2"
	
	while read LINE; do
		if [ -n "$(echo "$LINE" | grep "${tarFileName}${HEADER_SEPARATOR}")" ]; then	
			echo "$LINE" | cut -d"$HEADER_SEPARATOR" -f3
			return 0
		fi
	done < <( echo "$HEADER" )
}

# getHumanSize()
# Args:
#  - $1 : file size (bytes)
#  - stdout: the human-readable file size

function getHumanSize()
{
	unitTbl=('B' 'Kio' 'Mio' 'Gio' 'Tio' 'Pio' 'Eio' 'Zio' 'Yio')

	size="$1"
	nbDiv=0
	
	while [ "$size" -gt "1000" ]; do
		(( nbDiv++ ))
		(( size /= 1024 ))
	done
	
	echo "$size ${unitTbl[$nbDiv]}"
}

# getFile()
# Args:
#  - $1 : c501tar filename
#  - $2 : filename in c501tar
#  - stdout: the file

function getFile()
{
	FILENAME="$1"
	
	if ! c501tarInit "$FILENAME"; then
		echo "Error, getFile() : c501tarInit() failed !" >&2
		return 1
	fi
	
	tarFileName="$2"
	tarFilePosBloc=0
	tarFileSize=0
	
	while read LINE; do
		if [ -n "$(echo "$LINE" | grep "${tarFileName}${HEADER_SEPARATOR}")" ]; then
			tarFilePosBloc=$(echo "$LINE" | cut -d"$HEADER_SEPARATOR" -f2)
			tarFileSize=$(echo "$LINE" | cut -d"$HEADER_SEPARATOR" -f3)
		fi
	done < <( echo "$HEADER" )
	
	if [ "$tarFilePosBloc" -ne 0 ]; then	
		# On prend les blocs
		(( blocCount = tarFileSize / BLOC_SIZE ))
		dd if="$FILENAME" bs="$BLOC_SIZE" count="$blocCount" skip="$tarFilePosBloc" 2> /dev/null
	
		(( leftBytesCount = tarFileSize - blocCount * BLOC_SIZE ))
		(( leftBytesPos = (tarFilePosBloc + blocCount) * BLOC_SIZE ))
		dd if="$FILENAME" bs=1 count="$leftBytesCount" skip="$leftBytesPos" 2> /dev/null
	else
		echo "Error, getFile() : file not found !" >&2
		return 1
	fi
}

FILENAME="mytar.c501tar"

# Création
c501tarCreate "$FILENAME"

# Ajout de fichiers
echo "Je suis un fichier !!!" | c501tarAddFile "$FILENAME" file1
echo "Je suis un fichier !!!" | c501tarAddFile "$FILENAME" file2
echo "Je suis un fichier !!!" | c501tarAddFile "$FILENAME" file3
c501tarAddFile "$FILENAME" "Lucid.iso" < Bureau/lucid-desktop-amd64.iso

# Liste des fichier
c501tarListFiles "$FILENAME"

# Lecture de la taille
getHumanSize $(getFileSize "$FILENAME" file1)
getHumanSize $(getFileSize "$FILENAME" Lucid.iso)

# Exctration
getFile "$FILENAME" "file1" > file1
getFile "$FILENAME" "Lucid.iso" > Lucid.iso

Hors ligne