Ingvar16 писал(а): ↑05.11.2011 18:14
Забэкслешил:
Код: Выделить всё
#!/bin/sh
ORIG_DIR=`pwd`
ARCHNAME=`echo $@ | sed 's/\.rar//g'`
mkdir -p $ARCHNAME
cd $ARCHNAME
unrar x $ORIG_DIR/$ARCHNAME.rar
find . -name "*.djvu" | xargs -i -t echo mv \"{}\" \"$ARCHNAME/{}.djvu\"
find . -name "*.pdf" | xargs -i -t echo mv \"{}\" \"$ARCHNAME/{}.pdf\"
find . -name "*.doc" | xargs -i -t echo mv \"{}\" \"$ARCHNAME/{}.doc\"
cd $ORIG_DIR
передаю имя файла в текущем каталоге c *.rar:
$ bash unrar.sh Ivanova.rar
Создаёт папку с именем архива,распаковывает туда архив,но внутри djvu не переименовывает в $ARCHNAME.
Этот скрипт.. написан, мягко говоря, странно.
Ошибки (или то, что может привести к весьма "интересным" последствиям):
1. Смысл $@ мне не понятен. Если вы используете $@, значит вы предполагаете наличие нескольких аргументов коммандной строки (те нескольких архивов)? Но что тогда, интересно, должно означать `cd $ARCHNAME` ? Вы пишите $@ без кавычек, но, если аргументы будут содержать символы из IFS (пробелы, например), то эта одна строка ($ARCHNAME) будет разделена на несколько аргументов при вызове `mkdir` (.. и тд). Те, если у вас файл называется 'a b.rar', то будут созданы директории 'a' и 'b', вместо 'a b'. И, наконец, использование $@ без кавычек или даже в `echo "$@"` просто бессмысленно, тк echo все равно все соединит в одну строку, разделенныую пробелами. Те, чтобы сделать обработку нескольких аргументов, вам нужно что-то типа
Это будет работать для любых символов в именах файлов, кроме новой строки. Тем не менее, использование такой конструкции здесь все равно бессмысленно, если не менять остальной скрипт, который явно предполагает, что в ARCHNAME имя только одного архива.
2. Все переменные используются без кавычек. Это значит, что, если в имени директории или файлов оказываются, опять же, символы из IFS, то вы получаете больше, чем одно слово (word). Те совсем не то, что вам нужно.
3. Кавычки, передаваемые xargs-у, не нужны. Что вы хотите ими экранировать и от кого? `mv` запускает не shell, а сам xargs, те экранировать от shell-а смысла нет. А сам xargs, хоть и разделяет строку на аргументы по blank символами (видимо, это пробел и табуляция), но он это делает, во-первых, для входных данных (в данном случае, - это конвеер от find, и кавычки, соответственно, должны быть там), а, во-вторых, с опцией '-i' он этого вообще не делает (те в данном случае кавычки не нужны). В вашем же варианте, кавычки просто добавляются к имени файла при вызове mv (те получается вызов `mv "file" ...`, но файла "file" нету, есть только файл file (без кавычек в имени)).
4. Вызов mv в xargs, если предположить, что исходный файл он найдет, будет переименовывать вот так:
Код: Выделить всё
file.djvu -> "$ARCHNAME"/file.djvu.djvu (но мы уже в "$ARCHNAME" !)
Те. он все равно не заработает, тк _папка_ назначения "$ARCHNAME" не существует. Не говоря уже про '.djvu.djvu'. Другими словами, в вызове `mv` написана глупость -)
Кое-что незначительное:
1. Смысл ORIG_DIR не понятен. Если вы используйте абсолютные пути, так используйте их везде. А, если относительные, то зачем вам понадобился ORIG_DIR ?
2. Для удаления '.rar' в случае одного аргумента нет смысла использовать sed - "${1%.rar}" должно работать в sh.
3. Говорят, опция xargs-а '-i' устарела, используйте '-I' (xargs(1)).
4. В конструкции вида
Код: Выделить всё
find . ... | xargs -IREPL ... cmd some_path/REPL
аргумент команды cmd будет иметь вид
тк find выводит полный путь относительно пути поиска (те точка в данном случае).
5. И, наконец, запуск _таких_ скриптов без опции оболочки '-e' может для вас закончиться чем-нибудь типа
в худшем случае. А еще лучше к '-e' добавить '-f'.
Другими словами, этот скрипт проще переписать, чем исправить -)
Ingvar16 писал(а): ↑05.11.2011 18:14
Кроме того,мне нужно распаковать и обработать
все архивы в папке.
$ bash unrar.sh *.rar ничего не распаковывает (только создаёт пустые папки)
изменение скрипта,задачей обработки *.rar,тоже выдаёт что-то непонятное (его уносит на другие директории):
Код: Выделить всё
#!/bin/sh
for FILE_NAME in *.rar
do
ORIG_DIR=`pwd`
ARCHNAME=`echo $@ | sed 's/\.rar//g'`
mkdir -p $ARCHNAME
cd $ARCHNAME
unrar x $ORIG_DIR/$ARCHNAME.rar
find . -name "*.djvu" | xargs -i -t echo mv \"{}\" \"$ARCHNAME/{}.djvu\"
find . -name "*.pdf" | xargs -i -t echo mv \"{}\" \"$ARCHNAME/{}.pdf\"
find . -name "*.doc" | xargs -i -t echo mv \"{}\" \"$ARCHNAME/{}.doc\"
cd $ORIG_DIR
done
А этот вариант.. Вы уж извините, но вы сами-то понимаете, что написали ?
Что же касается, как все это исправить.. Честно говоря, я так и не понял, что же должны делать вызовы `find | xargs` в вашем скрипте, но работающая распаковка выглядит примерно так:
Код: Выделить всё
#!/bin/sh -ef
IFS='
'
ARCHNAME="$(echo "$*" | sed 's/\.rar$//')"
mkdir -pv $ARCHNAME
echo "$ARCHNAME" | xargs -IREPL unrar x REPL.rar REPL
Чтобы распаковать все .rar файлы, запускайте так: