Helpers - компьютеры, интернет, программирование

rm не может удалить файлы по подстановочному знаку из скрипта, но работает из командной строки

Я столкнулся с действительно глупой проблемой со сценарием оболочки Linux. Я хочу удалить все файлы с расширением «.bz2» в каталоге. В сценарии я вызываю

rm "$archivedir/*.bz2"

где $archivedir — путь к каталогу. Должно быть довольно просто, не так ли? Каким-то образом ему удается выйти из строя с этой ошибкой:

rm: cannot remove `/var/archives/monthly/April/*.bz2': No such file or directory

Но в этом каталоге есть файл с именем test.bz2, и если я изменю свой скрипт на

echo rm "$archivedir/*.bz2"

и скопируйте/вставьте вывод этой строки в окно терминала, файл будет успешно удален. Что я делаю не так?

26.04.2009

  • Как правильно это сделать, если переменная содержит подстановочный знак? Произнесите archivedir="/var/foo/*.bz2". 21.08.2012

Ответы:


1

TL;DR

Цитата только переменная, а не весь ожидаемый путь с подстановочным знаком

rm "$archivedir"/*.bz2

Пояснение

  • В Unix программы обычно сами не интерпретируют подстановочные знаки. Оболочка интерпретирует подстановочные знаки без кавычек и заменяет каждый аргумент подстановочного знака списком совпадающих имен файлов. если $archivedir может содержать пробелы, то rm $archivedir/*.bz2 может не выполнять то, что вы

  • Вы можете отключить этот процесс, заключив подстановочный знак в кавычки, используя двойные или одинарные кавычки или обратную косую черту перед ним. Однако это не то, что вам нужно здесь - вы хотите, чтобы подстановочный знак был расширен до списка файлов, которым он соответствует.

  • Будьте осторожны при написании rm $archivedir/*.bz2 (без кавычек). Разделение слов (т. е. разбиение командной строки на аргументы) происходит после замены $archivedir. Поэтому, если $archivedir содержит пробелы, вы получите дополнительные аргументы, которых вы не предполагали. Скажем, архивный каталог /var/archives/monthly/April to June. Тогда вы получите эквивалент записи rm /var/archives/monthly/April to June/*.bz2, которая пытается удалить файлы "/var/archives/monthly/April", "to" и все файлы, соответствующие "June/*.bz2", что не является тем, что вы хотеть.

Правильное решение - написать:

rm "$archivedir"/*.bz2
26.04.2009
  • Ничего себе, я понятия не имел, что оболочка выполняет операции с подстановочными знаками вместо реальных программ файловой системы. Это хорошо знать! 26.04.2013
  • Интересное объяснение, но оно не объясняет, почему оно работает при выполнении непосредственно в командной строке. 11.02.2014
  • Запуск sudo rm /var/lib/OnlyRootCanList/* не будет работать, если текущему пользователю не разрешено перечислять файлы в этом каталоге. В таких случаях команда find будет работать лучше. например find . -name "*.jpg" | xargs rm 26.05.2015

  • 2

    Ваша исходная линия

    rm "$archivedir/*.bz2"
    

    Можно переписать как

    rm "$archivedir"/*.bz2
    

    для достижения того же эффекта. Расширение подстановочных знаков не происходит должным образом в вашей существующей настройке. Перемещая двойную кавычку в начало пути к файлу (что является законным), вы избегаете этого.

    26.04.2009

    3

    Чтобы немного расширить это, bash имеет довольно сложные правила для работы с метасимволами в кавычках. В целом

    • почти ничего не интерпретируется в одинарных кавычках:

       echo '$foo/*.c'                  => $foo/*.c
       echo '\\*'                       => \\*
      
    • замена оболочки выполняется внутри двойных кавычек, но метасимволы файла не раскрываются:

       FOO=hello; echo "$foo/*.c"       => hello/*.c
      
    • все внутри обратных кавычек передается подоболочке, которая их интерпретирует. Переменная оболочки, которая не экспортируется, не определяется в подоболочке. Итак, первая команда выводит пустое сообщение, а второе и третье — «до свидания»:

      BAR=bye echo `echo $BAR`
      BAR=bye; echo `echo $BAR`
      export BAR=bye; echo `echo $BAR`
      

    (И заставить это печатать так, как вы хотите, в SO требуется несколько попыток, по-видимому, невозможно...)

    26.04.2009

    4

    Кавычки заставляют строку интерпретироваться как строковый литерал, попробуйте удалить их.

    26.04.2009

    5

    Я видел подобные ошибки при вызове сценария оболочки, такого как ./shell_script.sh, из другого сценария оболочки. Это можно исправить, вызвав его как sh shell_script.sh.

    09.09.2011
  • Это просто карго-культовое программирование. Нет никаких причин, по которым неправильная оболочка может вызвать эту конкретную ошибку. -1 25.11.2014

  • 6

    Почему бы не просто rm -rf */*.bz2? У меня работает на OSX.

    26.12.2017
    Новые материалы

    Интуитивное понимание тензоров в машинном обучении
    Тензор является важной концепцией во многих научных областях, таких как математика, физика, обработка сигналов и компьютерное зрение, и это лишь некоторые из них. В математике тензор — это..

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

    Почему объяснимость так важна прямо сейчас?
    По мере того, как системы искусственного интеллекта и инструменты на основе машинного обучения распространяются в нашей повседневной жизни, как практики, так и критики все чаще заявляют о..

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

    ИИ для чайников: руководство для начинающих по пониманию будущего технологий
    Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..