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


On ne peut pas mettre d'array dans un string!
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