Почему моя команда «RM» работает нормально в терминале на моем Mac, но не из скрипта Shell?

Златовласка позаботилась обо втором вопросе, но, как человека из Ubuntu, меня больше интересовал первый. Или, чтобы выразить это более ясно для всех, кто, как я, попал сюда, кажется, что «стандарт» - это Debian без графического интерфейса рабочего стола, а не с графическим интерфейсом по умолчанию, таким как «единство» Ubuntu, а Debian + GNOME - это Debian, упакованный с GNOME как графический интерфейс рабочего стола. Это мой предварительный вывод, основанный на том, что я нашел до сих пор, я вернусь и отредактирую это, если найду иное.

1
31.08.2018, 11:04
2 ответа

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

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

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

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

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

1
27.01.2020, 23:23

Ответ @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

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

2
27.01.2020, 23:23

Теги

Похожие вопросы