Оболочка не перенаправляет вывод tar в файл.

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

Вот мой bash скрипт

#!/bin/bash# установить формат даты и имя дампаDATE=$(date +»%Y%m%d-%H%M»)DUMPFILE=$DATE.dump# путь к каталогу логов и имя выходного лог-файла LOGDIR=/opt/mongodb/backups/logsDBLOG=$DATE-dump.log# сделать резервное копирование базы данных и вывести в файл дампа, перенаправить вывод в логdocker exec -i mongodb sh -c «mongodump —archive» > $DUMPFILE 2> $LOGDIR/$DBLOG# архивировать файл дампа и загрузки файловARCHIVENAME=$DATE.tgzARCHIVELOG=$DATE-archive.logtar -czvf $ARCHIVENAME /opt/mongodb/$DUMPFILE /opt/mongodb/files &> $LOGDIR/$ARCHIVELOG

Где я застрял, скрипт правильно выводит лог дампа. Однако, когда доходит до конца, я получаю

./backup.sh: line 20: /opt/mongodb/backups/logs/20250328-0942-archive.log: No such file or directory

Я попытался использовать абсолютный путь вместо переменной:

tar -czvf $ARCHIVENAME /opt/mongodb/$DUMPFILE /opt/mongodb/files &> /opt/mongodb/backups/logs/$ARCHIVENAME

Но я получаю ту же ошибку. Я полагаю, что это либо мое плохое понимание перенаправлений, tar, либо синтаксическая ошибка. Любая помощь будет оценена.

РЕДАКТИРОВАТЬ: Каждый раз, когда я запускаю скрипт, создается файл с именем “‘ ‘”. Если запустить

cat ‘ ‘

Я вижу, что файл содержит лог, так что вывод действительно перенаправляется в файл, просто не в желаемой манере.

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

Строка, продолжающаяся на следующей строке с помощью обратного слэша, не должна содержать ничего после обратного слэша, даже пробел.

Так как у вас есть пробел после обратного слэша, пробел цитируется, так что вы, по сути, говорите

some-command &> ‘ ‘

Следующая строка после этого пытается запустить несуществующий лог-файл как команду. Это и генерирует сообщение об ошибке “No such file or directory”.

Я предполагаю, что вы или ваш редактор добавили пробел после в строке, из-за чего происходит перенаправление в (‘ ‘) вместо файла.

.

Ответ или решение

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

Теория: Понимание перенаправления ввода/вывода в Shell

Перенаправление потоков ввода/вывода в командной оболочке Bash является одной из ключевых операций, позволяющей управлять тем, куда отправляется вывод команд и откуда эти команды получают свои данные. Символы > и 2> используются для перенаправления стандартного вывода и стандартного вывода ошибок соответственно. Например, 2> используется для того, чтобы перенаправить поток ошибок в другой файл.

Когда вы используете &> (или сокращенное &>) в Bash, это символ означает объединение стандартного вывода и вывода ошибок в одно место. Но наиболее важно здесь то, что перенаправление требует, чтобы за символами перенаправления следовал корректный целевой файл или поток, в противном случае может возникнуть ошибка.

Пример: Рассмотрение ошибки в вашем коде

В предоставленном коде мы имеем следующий фрагмент:

tar -czvf $ARCHIVENAME /opt/mongodb/$DUMPFILE /opt/mongodb/files &> $LOGDIR/$ARCHIVELOG

До этой строки возникает ошибка: ./backup.sh: line 20: /opt/mongodb/backups/logs/20250328-0942-archive.log: No such file or directory.

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

Применение: Исправление и отладка проблемы

Для корректного выполнения вашего сценария избегайте пробелов после обратного слэша. Обновите ваш код, убрав пробелы следующим образом:

tar -czvf $ARCHIVENAME /opt/mongodb/$DUMPFILE /opt/mongodb/files &> $LOGDIR/$ARCHIVELOG

Кроме того, убедитесь, что все каталоги, включая $LOGDIR, существуют и имеют правильные права доступа для записи. Вы можете добавить в ваше скрипт предусловия для автоматического создания каталогов, если они не существуют:

#!/bin/bash# Установка форматов даты и имен файловDATE=$(date +»%Y%m%d-%H%M»)DUMPFILE=$DATE.dump# Директория логов и имя файла вывода логовLOGDIR=/opt/mongodb/backups/logs# Создаем директорию логов, если она не существуетmkdir -p $LOGDIRDBLOG=$DATE-dump.log# Делаем бэкап базы данных и выводим в dump-файл, перенаправляем вывод в логdocker exec -i mongodb sh -c «mongodump —archive» > $DUMPFILE 2> $LOGDIR/$DBLOG# Архивируем dump-файл и файлы загрузокARCHIVENAME=$DATE.tgzARCHIVELOG=$DATE-archive.logtar -czvf $ARCHIVENAME /opt/mongodb/$DUMPFILE /opt/mongodb/files &> $LOGDIR/$ARCHIVELOG

Заключение

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

Друзья помогите этому контенту стать доступнее в социальных сетях.

Не проходи мимо жмакни по кнопке возможно кому то еще он будет полезен!