Команда rm в скрипте bash не работает с переменной

Я создаю сценарий bash для создания резервных копий баз данных mysql. На самом деле, я бы хотел удалить старые.

Итак, я создаю свой скрипт с переменной для обеспечения устойчивости.

Весь скрипт фактически работает, единственное, что не работает, – это удаление старых. Я думал, что это будет самая легкая часть.

Во всяком случае, вот мой код, может кто-нибудь рассказать мне, что случилось? И команда rm возвращает меня: rm: impossible de supprimer « /path/to/backup/files/*.gz »: Aucun fichier ou dossier de ce type Что означает rm: impossible to delete « /path/to/backup/files/*.gz »: no files or directory of this type

Но что действительно странно, во-первых, я нашел скрипт в учебнике

Во-вторых, если я запустил «rm /path/to/backup/files/*.gz» в команде оболочки, это будет работать и удалять все .gz-файлы (как предполагалось)

 #!/bin/bash USER="***" PASSWORD="****" OUTPUT="/path/to/backup/files" rm "$OUTPUT/*.gz" databases=`mysql --user=$USER --password=$PASSWORD -e "SHOW DATABASES;" | tr -d "| " | grep -v Database` for db in $databases; do if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] && [[ "$db" != "performance_schema" ]] ; then echo "Dumping database: $db" mysqldump --force --opt --user=$USER --password=$PASSWORD --databases $db > $OUTPUT/`date +%Y%m%d`.$db.sql gzip $OUTPUT/`date +%Y%m%d`.$db.sql fi done 

Спасибо,

3 Solutions collect form web for “Команда rm в скрипте bash не работает с переменной”

Альтернативным способом является объединение rm с поиском и / или xargs. Это несколько альтернатив:

 find $output -name *.gz -type f -delete find $output -name "*.gz" -type f -exec rm '{}' \; find $output -name *.gz -type f -print0 | xargs -0 rm 

PS: тип f означает поиск файлов.

По умолчанию поиск ищет все поддиры. Вы можете ограничить операцию поиска текущим каталогом, если требуется, с помощью параметра maxdepth:

 find $output -maxdepth 1 -name "*.gz" -type f -exec rm '{}' \; 

Если вам нужно продолжать работать с rm и переменной, это сработало для меня в одной строке:

 out="/home/gv/Desktop/PythonTests/appsfiles";rm $out/*.txt rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/a.txt'? y rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/a ver 1.txt'? y rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/b.txt'? y rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/c.txt'? y rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/d.txt'? y 

 rm "$OUTPUT/*.gz" 

Командная строка оболочки сообщает оболочке выполнить /bin/rm с двумя аргументами: rm и /path/to/backup/files/*.gz .

Пространство " и $ являются специальными символами в синтаксисе языка оболочки. Пространство используется для разграничения аргументов команды " , используется для цитирования других специальных символов (не все, например, по-прежнему специальные), как это * выше, а $ is используется для некоторых расширений (например, расширение параметра $OUTPUT которое вы используете здесь).

rm после запуска попытается удалить этот файл /path/to/backup/files/*.gz . Если этот файл не существует (как и в случае с вами), он сообщит об ошибке.

Когда вы пишете:

 rm /path/to/backup/files/*.gz 

или

 rm "$OUTPUT"/*.gz 

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

Поэтому, если /path/to/backup/files содержит /path/to/backup/files a.gz и b.gz , оболочка фактически вызовет rm с тремя аргументами: rm , /path/to/backup/files/a.gz и /path/to/backup/files/b.gz который больше похож на то, что вы хотите здесь.

Обратите внимание, что $OUTPUT по-прежнему нужно указывать, так как иначе он может быть разбит, если он содержит символы $IFS или также может быть подвержен глобализации, если он содержит какие-либо подстановочные знаки (например, * выше).

Также неплохо привыкнуть к написанию:

 rm -- "$OUTPUT"/*.gz 

Здесь $OUTPUT начинается с / , поэтому это нормально, но в тот день, когда вы меняете $OUTPUT на -foo- например, он перестанет работать, поскольку этот -foo-/... будет использоваться rm качестве параметров.

Если сценарий не предназначен для интерактивности, вы можете добавить параметр -f в rm . Это приведет к отключению всех пользовательских запросов и удалению ошибки, если нет соответствующего файла (большинство оболочек, когда glob не имеет соответствия, передает шаблон как есть для приложения, а rm -f не жалуется, когда его попросят удалить файл, который не существует в первую очередь).

Попытайтесь получить эти файлы, а затем удалить их:

 ARCS=`ls $OUTPUT | grep "\.gz$"` for _arch in $ARCS; do rm -f $_arch done 
  • Как я могу объединить переменную оболочки с другими другими параметрами в моих командных строках?
  • Сценарий Bash для заполнения шаблона
  • Использование «$ {a: -b}» для назначения переменных в скриптах
  • Как установить переменную среды оболочки из файла autotools .am?
  • Отложить переменное расширение до подоболочки
  • Создать переменную на основе порядка, в котором файл находится в алфавитном списке файлов
  • dirname и basename против расширения параметров
  • Как передать переменную в sftp?
  • Каков наиболее эффективный способ grep для двух совершенно разных вещей и присвоения значений отдельным переменным?
  • Использование eval в файле make
  • Передать переменную с помощью EOF и использовать переменную хоста
  • Linux и Unix - лучшая ОС в мире.