Почему моя команда ‘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/... в аргументы.

Interesting Posts

Использовать конкретный ключ в вызове ssh forwardagent?

Неблокированный опрос от двух труб?

rsync для удаленного сервера без пароля

Помощь в исправлении систем RHEL 6.x с воздушным потоком на удаленных объектах

Движение мыши перемещается, когда средняя кнопка удерживается

Постоянное приглашение для пароля WPA2 в Fedora

Гармонический текст в меню tmux

gpg шифрование: ошибка в расшифровке с подтвержденным ключом и точная команда как прошлые успешные передачи

Почему я получаю ошибку InitDevice :: CreateDevice, когда пытаюсь запустить «Пираты Карибского моря» с Вином?

нет вектора irq-обработчика

Где выходят выходные задания `at` и` cron`?

Импульсный звук: как отключить выходной канал?

возможно ли программно изменить рабочий каталог родительской оболочки?

Как создать гостевой KVM с графикой SPICE, но TLS отключен с помощью virt-install?

вставка данных в конкретный раздел конфигурационного файла с возможностью

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