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
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
Pages : 1