bash скрипт для распаковки архивов всех типов в указанную директорию

Автор demon_666_902, 15 июля 2013, 17:29:39

« назад - далее »

0 Пользователи и 2 гостей просматривают эту тему.

demon_666_902

Нашел следующий скрипт для распаковки архивов всех типов (при добавление в .bashrc все прекрасно работает при наличие архиваторов)
Открыть содержимое (спойлер)

unpack () {
   if [ -f $1 ] ; then
      case $1 in
         *.tar.bz2) tar xvjf $1 ;;
         *.tar.gz) tar xvzf $1 ;;
         *.tar.xz) tar xvJf $1 ;;
         *.bz2) bunzip2 $1 ;;
         *.rar) unrar x $1 ;;
         *.gz) gunzip $1 ;;
         *.tar) tar xvf $1 ;;
         *.tbz2) tar xvjf $1 ;;
         *.tgz) tar xvzf $1 ;;
         *.zip) unzip $1 ;;
         *.Z) uncompress $1 ;;
         *.7z) 7z x $1 ;;
         *.xz) unxz $1 ;;
         *.exe) cabextract $1 ;;
         *) echo "\`$1': Unknown method of file compression" ;;
      esac
   else
      echo "\`$1' no foud"
   fi
}
[свернуть]
Теперь решил его видоизменить, чтобы распаковка проходила в заданную директорию. Начал делать, вот что получается:
Открыть содержимое (спойлер)
#!/bin/bash

runUnPack (){
   dirTMP="/tmp/tMp123456"
   archiveName=${1##*/}
   if [[ $2 == 'create' ]]; then
      #Создаю временную директорию, в которую будем распаковывать
      mkdir $dirTMP
      # Копирую архив в нее
      cp $1 $dirTMP/
      # Захожу во временный каталог
      cd tmp123456
   fi
   
   ##Распаковывыю файлы в текую директорию
   eval $3
   echo "$3"
   
   if [[ $2 == 'create' ]]; then
      # Удаляю архив
      rm $archiveName
      # Перемещаю все файлы в целевую директорию
      mv * $4
      # Возвращаюсь в /tmp
      cd ../
      # Удаляю созданный каталог
      rm -r tmp123456
   fi
}


#UnPuck (){
   #Переменная, хранящая в себе путь, куда будем распаковывать архив
   PATHROOT=''

   # Текущая директория, в которой находится пользователь
   HOMEDIRECTORY=$(pwd)

   # Проверяем не пуст ли второй аргумент - целевая директория
   if [ -z "$2" ] ; then
      # Если пусто, то текущей директория является текущая директория в которой находится пользователь
      PATHROOT=$HOMEDIRECTORY;
   else
      # Если задана, то ставим целевую директорию для распаковки
      PATHROOT="$2"
   fi

   # Путь, где будем создавать временную директорию
   dirArchive="${1%/*}"
   dirRoot=$(dirname $PATHROOT)
   dirHome=$(dirname $HOMEDIRECTORY)

   # Имя архива
   archiveName=${1##*/}
   #diffDir = $(diff $dirRoot $dirHome)
   create='not';
   #echo "$dirRoot - $dirHome - $PATHROOT - $HOMEDIRECTORY"

   #if [[ -z $diffDir ]] ; then
      #create='create'
   #fi

   command='';

   # Если задан 1 аргумент - имя архива
   if [ -f $1 ] ; then
   case $1 in
   # Архив tar.bz2
   *.tar.bz2)
      command="tar xvjf $1 -C $PATHROOT"
   ;;

   # Архив tar.gz
   *.tar.gz)
      command="tar xvzf $1 -C $PATHROOT"
   ;;

   # Архив tar.xz
   *.tar.xz)
      command="tar xvJf $1 -C $PATHROOT"
   ;;

   # Архив tar.bz2
   *.bz2)
      command="bunzip2 $1"
   ;;

   # Архив rar
   (*.rar)
      command="unrar x $1"
   ;;

   # Архив gz
   (*.gz)
      command="gunzip $1 cd"

   ;;

   # Архив tar
   (*.tar)
      command="tar xvf $1 -C $PATHROOT"
   ;;

   # Архив tbz2
   (*.tbz2)
      command="tar xvjf $1 -C $PATHROOT"
   ;;

   # Архив tgz
   (*.tgz)
      command="tar xvzf $1 -C $PATHROOT"
   ;;

   # Архив zip
   (*.zip) 
      command="unzip -x $1"
   ;;

   # Архив Z
   (*.Z)
      command="uncompress $1"
   ;;

   # Архив 7z
   (*.7z)
      command="7z x $1"
   ;;

   # Архив xz
   (*.xz)
      command="unxz $1"
   ;;

   # Архив exe
   (*.exe)
      command="cabextract $1"
   ;;
   (*) echo "\`$1': Unknown method of file compression" ;;
   esac
   else
      echo "\`$1' no foud"

   fi
   
   # Возвращаюсь в каталог, в котором был
   cd $HOMEDIRECTORY

   
   runUnPack $1 "$create" "$command" $PATHROOT
#}
[свернуть]
Возникла следующая проблема: при распаковке архива в указанную директорию я создаю временную в /tmp и распаковывая туда, а потом перемещаю в нужную. Но если пользователь все таки распаковывает в ту же директорию, где и архив лежит, то логично что этого делать не нужно и я никак не могу въехать, как проверить это (сравнить каталоги, куда распаковываем и где находится архив)... Знатоки, помогите, пожалуйста, ввиду моей неопытности написания bash-скриптов и, если есть альтернативы написанному, буду рад выслушать.
Единственная просьба: не нужно писать конструкций типа:
xarchiver -x /path/to/archive/archive.name --extract-to=/path/to/extract
Это у меня у самого на алиасе прибиндино как функция, но это не работает в обычном терминальном режиме без иксов, да и ктому же бесит открывающееся и гаснущее окно гуишного архиватора)))) Хотелось бы домучить скрипт)))

ZEN

Я бы вернулся к первому варианту скрипта и посмотрел параметры каждого архиватора. Обычно есть специальный ключ которым можно указать куда распаковывать. Например для tar ключ -C

*.tar) tar xvf $1 -C $2 ;;

в результате скрипт будет принимать два параметра. Первый параметр сам архив, второй каталог куда распаковать
Crimea is Ukraine

demon_666_902

там, где можно было я сделать - для tar есть, для остальных вроде я не нашел, не буду утверждать, что нет, может я плохо смотрел)))))
просто под tar'om я забыл поставить флаг что не нужно копировать ничего)))
пока что создается одна статическая папка, я переделал, чтобы создавалась она с рендомным именем, чтобы можно одновременно было запускать несколько копий скрипта! потом выложу весь код, как закончу!

ZEN

для 7z есть параметр
       -o{Directory}
              Set Output directory

unrar не имеет такого параметра, но вроде как rar архивы можно распаковывать с помощью 7z
для остальных архивов не смотрел, но думаю что выход тоже есть
Crimea is Ukraine

demon_666_902

Вот бета-версия скрипта (слабо протестирована из-за недостатка времени). Просьба - посмотрите его внутренность, может у вас будут какие-то замечания по поводу реализации или кто-может какие-то баги найдет ;-)
Открыть содержимое (спойлер)

#!/bin/bash

runUnPack (){
   dirTMP="/tmp/$RANDOM"
   echo $dirTMP
   archiveName=${1##*/}
   #echo "$create"
   if [[ $4 =~ $5 ]] || [[ $5 =~ $4 ]] && [[ $2 == 'not' ]]; then
      create='not'
   else
      create='create'
   fi
   
   echo $create
   
   if [[ $create == 'create' ]]; then
      echo 'is'
      #Создаю временную директорию, в которую будем распаковывать
      mkdir $dirTMP
      # Копирую архив в нее
      cp $1 $dirTMP/
      # Захожу во временный каталог
      cd $dirTMP
   fi
   
   ##Распаковывыю файлы в текую директорию
   eval $3
   echo "$3"
   
   if [[ $create == 'create' ]]; then
      # Удаляю архив
      rm $archiveName
      # Перемещаю все файлы в целевую директорию
      mv * $4
      # Возвращаюсь в /tmp
      cd ../
      # Удаляю созданный каталог
      rm -r $dirTMP
   fi
}


UnPuck (){
   #Переменная, хранящая в себе путь, куда будем распаковывать архив
   PATHROOT=''

   # Текущая директория, в которой находится пользователь
   HOMEDIRECTORY=$(pwd)

   # Проверяем не пуст ли второй аргумент - целевая директория
   if [ -z "$2" ] ; then
      # Если пусто, то текущей директория является текущая директория в которой находится пользователь
      PATHROOT=$HOMEDIRECTORY;
   else
      # Если задана, то ставим целевую директорию для распаковки
      PATHROOT="$2"
   fi

   # Путь, где будем создавать временную директорию
   dirArchive="${1%/*}"
   dirRoot=$(dirname $PATHROOT)
   dirHome=$(dirname $HOMEDIRECTORY)

   # Имя архива
   archiveName=${1##*/}
   #diffDir = $(diff $dirRoot $dirHome)
   create='create';
   #echo "$dirRoot - $dirHome - $PATHROOT - $HOMEDIRECTORY"

   #if [[ -z $diffDir ]] ; then
      #create='create'
   #fi

   command='';

   # Если задан 1 аргумент - имя архива
   if [ -f $1 ] ; then
   case $1 in
   # Архив tar.bz2
   *.tar.bz2)
      command="tar xvjf $1 -C $PATHROOT"
      create='not'
   ;;

   # Архив tar.gz
   *.tar.gz)
      command="tar xvzf $1 -C $PATHROOT"
      create='not'
   ;;

   # Архив tar.xz
   *.tar.xz)
      command="tar xvJf $1 -C $PATHROOT"
      create='not'
   ;;

   # Архив tar.bz2
   *.bz2)
      command="bunzip2 $1"
   ;;

   # Архив rar
   (*.rar)
      command="unrar x $1"
   ;;

   # Архив gz
   (*.gz)
      command="gunzip $1 cd"

   ;;

   # Архив tar
   (*.tar)
      command="tar xvf $1 -C $PATHROOT"
      create='not'
   ;;

   # Архив tbz2
   (*.tbz2)
      command="tar xvjf $1 -C $PATHROOT"
      create='not'
   ;;

   # Архив tgz
   (*.tgz)
      command="tar xvzf $1 -C $PATHROOT"
      create='not'
   ;;

   # Архив zip
   (*.zip) 
      command="unzip -x $1"
   ;;

   # Архив Z
   (*.Z)
      command="uncompress $1"
   ;;

   # Архив 7z
   (*.7z)
      command="7z x $1"
   ;;

   # Архив xz
   (*.xz)
      command="unxz $1"
   ;;

   # Архив exe
   (*.exe)
      command="cabextract $1"
   ;;
   (*) echo "\`$1': Unknown method of file compression" ;;
   esac
   else
      echo "\`$1' no foud"

   fi
   
   # Возвращаюсь в каталог, в котором был
   cd $HOMEDIRECTORY

   
   runUnPack "$1" "$create" "$command" "$PATHROOT" "$dirRoot"
}

[свернуть]

Сообщение объединено: 15 июля 2013, 20:36:17

Цитата: ZEN от 15 июля 2013, 19:43:48
для 7z есть параметр
       -o{Directory}
              Set Output directory

unrar не имеет такого параметра, но вроде как rar архивы можно распаковывать с помощью 7z
для остальных архивов не смотрел, но думаю что выход тоже есть
Ок посмотрю)) по мере поступления информации может полностью откажусь от распаковки во временную директорию!))

ogost

Цитата: demon_666_902 от 15 июля 2013, 17:29:39при распаковке архива в указанную директорию я создаю временную в /tmp и распаковывая туда, а потом перемещаю в нужную.
емнип, большинство архиваторов так и делают - сначала во временную, потом в нужную.

ZEN

Пока что не для всех архиваторов сделана распаковка в указанный каталог.  Для тех, где реализовано, в строках содержится "$target".
#!/usr/bin/bash
eval target=$2
if [[ ( -f $1 ) && ( -d $2 ) ]]
then
case $1 in
*.tar.bz2) tar xvjf $1 -C "$target" ;;
*.tar.gz) tar xvzf $1 -C "$target" ;;
*.tar.xz) tar xvJf $1 -C "$target" ;;
*.bz2) bunzip2 $1 ;;
*.rar) 7z x $1 -o"$target" ;;
*.gz) gunzip $1 ;;
*.tar) tar xvf $1 -C "$target" ;;
*.tbz2) tar xvjf $1 -C "$target" ;;
*.tgz) tar xvzf $1 -C "$target" ;;
*.zip) 7z x $1 -o"$target" ;;
*.7z) 7z x $1 -o"$target" ;;
*.Z) uncompress $1 ;;
*.xz) unxz $1 ;;
*.exe) cabextract $1 ;;
*) notify-send "$1 Unknown method of file compression" ;;
esac
else
echo "Usage:"
echo "$0 example.tar $HOME"
exit -1
fi
notify-send "$1 unpacking complete"
exit 0

Так что идею, надеюсь, передал. Дальше при наличии времени доработаю остальные (по правде говоря man к другим архиваторам даже не смотрел. Возможно с gunzip будут проблемы. Хотя стоит сначала проверить что из оставшихся может распаковывать 7z)
Crimea is Ukraine

ZEN

Вспомнил тут, что кроме написания скрипта самому, можно воспользоваться готовой консольной утилитой - atool.
Crimea is Ukraine