
Я пытаюсь создать bash one-liner для цикла по каталогам в текущем каталоге и tar-архивирования содержимого в уникальные tar-файлы, используя имя каталога в качестве имени файла tar. У меня есть работающие основы (нахождение имен каталогов и tar-архивирование их с этими именами), но мой цикл выдает некоторые сообщения об ошибках, и я не могу понять, откуда он берет команды, которые пытается запустить.
Вот наиболее работающий однострочный ответ:
for f in `ls -d */`; do `tar -czvvf ${f%/}.tar.gz $f`;done
«Странный» вывод:
-bash: drwxrwxr-x: command not found
-bash: drwxr-xr-x: command not found
-bash: drwxr-xr-x: command not found
-bash: drwxrwxr-x: command not found
Какую часть команды, которую я запускаю, я не понимаю и которая генерирует такой вывод?
решение1
Вам нужно удалить обратные кавычки вокруг вашей tar
команды. Вы также можете захотеть пропустить ls
через конвейер xargs
, чтобы убедиться, что bash правильно подхватывает все каталоги:
for f in `ls -d */ | xargs`; do tar -cvzf ${f%/}.tar.gz $f; done
Обратные кавычки захватывают вывод tar
и пытаются выполнить его как команду в каждой итерации цикла. Первое, что tar
печатается при использовании параметра -v, это разрешения для каждого файла (например, drwxrwxr-x
). В этом случае вы хотите, чтобы bashвыполнятькоманда tar, а не захват выходных данных.
решение2
бджлаубверно относительно обратных кавычек вокруг tar
, однако вам не нужно использовать ls
:
for file in */
сделает свое дело и будет правильно обрабатывать имена каталогов с пробелами.
решение3
Остальные ответы здесь хороши, но я хотел бы добавить еще один вариант на случай, если вам нужно получить только каталоги, а не символические ссылки и т. д.:
for f in `find -maxdepth 1 -type d` | do -cvzf ${f%/}.tar.gz $f; done
Надеюсь это поможет!