Почему моя команда ‘rm’ отлично работает в терминале на моем Mac, а не из сценария оболочки?

У меня есть каталог, имя которого содержит пробелы. Мне нужно удалить содержимое этого конкретного каталога. Я экранирую пробелы в имени каталога с \ перед удалением содержимого. Команда rm отлично работает с терминала, но не работает, если я использую ее в сценарии Shell. Нет такого файла или каталога ошибка.

Например, у меня есть следующая структура каталогов Users/Neeraj/Documents/temp dir/dir with spaces/a.txt Мне нужно удалить все внутри каталога “dir с пробелами”. Код в моих сценариях оболочки выглядит так

 #!/bin/sh TEMP_DIR="$HOME/Documents/temp dir/dir with spaces" TEMP_DIR=$(echo $TEMP_DIR | sed 's/ /\\ /g') COMMAND="rm -r $TEMP_DIR/*" echo "Command: $COMMAND" rm -r "$TEMP_DIR"/* 

Когда я запускаю этот скрипт, я не получаю такого файла или каталога, в то время как та же команда работает нормально, если я просто скопирую его и запустлю из терминала.

Выход:

 Command: rm -r /Users/Neeraj/Documents/temp\ dir/dir\ with\ spaces/* rm: /Users/Neeraj/Documents/temp\ dir/dir\ with\ spaces/*: No such file or directory 

Как правильно это сделать?

Примечание : я использую macOS

2 Solutions collect form web for “Почему моя команда ‘rm’ отлично работает в терминале на моем Mac, а не из сценария оболочки?”

Ответ @Olorins – правильный ответ на этот вопрос, но я хочу добавить еще немного информации, почему он не работает:


Вы можете использовать любой из них:

 rm "dir with spaces" rm dir\ with\ spaces dir="dir with spaces"; rm "$dir" 

Но это не сработает:

 dir="dir\ with\ spaces"; rm "$dir" # the backslash will be taken literally inside quotes rm $dir # this should work, shouldn't it? Please read below. 

Последний вариант был для меня неинтуитивен в начале. Но bash расширяет содержимое переменной, добавляя кавычки перед выполнением .

Вы можете использовать set -x чтобы увидеть, что на самом деле выполняется:

 ( var="a\ b"; set -x; echo $var; ) + echo 'a\' b a\ b 

Хотя вывод выглядит хорошо, пространство все еще не экранировано, потому что \ окружен одинарными кавычками.

Вы используете как кавычки, так и обратную косую черту. Использование только цитирование будет работать нормально.

Этого должно быть достаточно:

 TEMP_DIR="$HOME/Documents/temp dir/dir with spaces" COMMAND="rm -r $TEMP_DIR/*" echo "Command: $COMMAND" rm -r "$TEMP_DIR"/* 

В этом случае предполагается, что shell обрабатывает и обратные слеши, и кавычки, чтобы предотвратить разбиение имени каталога. Когда вы используете оба, shell сохранила пробелы и обратный слеш внутри кавычек, поэтому rm фактически получает .../temp\ dir/dir\ with\ spaces/... в аргументах, где он должен был получить .../temp dir/dir with spaces/... вместо этого.

Когда вы копируете напечатанную команду, shell видит обратную косую черту без дополнительного цитирования, поэтому она сохраняет пробелы, защищенные обратной косой чертой, и удаляет обратную косую черту, поэтому rm получает .../temp dir/dir with spaces/... в аргументы.

  • Почему соляризованная цветовая схема в vim выглядит иначе, чем в iTerm2?
  • Ожидайте в bash скрипт?
  • Экран GNU показывает пустой терминал до изменения размера windows
  • Выполнить команды, разделенные точкой с запятой, переданные флагу -e st (Simple Terminal)
  • Как открыть терминал при запуске скрипта оболочки?
  • Цвета в терминале и VIM с подсистемой Windows
  • Linux: как я могу открыть программу с графическим интерфейсом, например google-chrome, из командной строки, чтобы она оставалась открытой даже после закрытия teminal
  • Control + C не останавливает какие-либо процессы в Linux. Он просто отображает текст ^ C и ничего не делает
  • Mac Terminal: Повторите несколько предыдущих команд последовательно
  • Терминальные команды не работают
  • Сохранение вывода команды поиска в переменную
  • Interesting Posts

    Debian: Как получить текущее имя загруженного ядра?

    NFSv3 работает, но не NFSv4 на Armbian

    Traceroute не работает в Linux, на Windows он делает

    davfs2 сохраняет файлы в кэше дольше

    Почему непривилегированные пользователи не могут вкладывать монтирования FUSE, но они могут монтировать FUSE внутри NFS с помощью root_squash?

    извлекать каждый n-й символ из строки

    Eclipse Mars не будет запускаться на ArchLinux с Gnome

    Переустановка / дом из другого раздела при новой установке без копирования

    Создание динамически управляемых веб-сайтов с помощью Mason (Perl) с httpd на текущей версии OpenBSD

    Нет ручного ввода для человека

    Прокси-сервер активации Systemd?

    Как я могу указать требования OS-условной сборки в файле спецификации RPM?

    Каков синтаксис файлов /etc/yum.repos.d/*.repo официальных репозиториев RHEL?

    Отсутствует вход для сенсорного экрана в приложении, когда запускается Ubuntu

    Debian Jessie не может установить расширение GNOME, не обнаружен собственный соединитель узла

    Linux и Unix - лучшая ОС в мире.