Pages : 1
#1 Le 18/03/2010, à 22:10
- congelli501
pipe vers tar
Bonjour ,
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
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
Pages : 1