Bash: «Нет такого файла или каталога», несмотря на существующий каталог

#linux #bash #ubuntu

#linux #bash #ubuntu

Вопрос:

Я создаю пользовательскую команду, которая перемещает или дублирует файл в каталог корзины для мусора вместо его удаления. Я пытаюсь создать каталог, если его там уже нет, создать дубликат, если файл уже был выполнен, и просто переместить его, если это не так. Проблема в том, что я продолжаю получать сообщение об ошибке «нет такого файла или каталога» независимо от того, где я размещаю каталог корзины. Обратите внимание, что простое перемещение или копирование файла с помощью базовых команд Linux работает нормально, и что нахождение в root не устраняет проблему. Какие шаги я должен предпринять?

     #!/bin/bash
set -x
        mkdir -p /home/WASTEBASKIT #This makes a wastebasket directory if it doesn't already exist.
        if test -e "$1"; then 
                    if  test -e /home/WASTEBASKIT/"$1"; then #Checking for duplicate files.
                    cp "$1" "/home/WASTEBASKIT/$1.$$"
                 else
                    mv "$1" "/home/WASTEBASKIT"
                fi
        else
            printf '%sn' "File not found." #Error if a file is not there.
            fi
  

Вот результаты: mkdir -p /home/WASTEBASKIT

test -e config.sh

test -e /home/WASTEBASKIT/config.sh

cp config.sh.945 ‘ /home/WASTEBASKIT’

cp: не удается указать ‘config.sh.945’: нет такого файла или каталога

Комментарии:

1. Чего вы пытаетесь достичь cp "$1" "$1.$$" "/home/WASTEBASKIT" ?

2. Он дает альтернативное имя файла, чтобы исходный удаленный файл не перезаписывался.

3. Да, изменения заставляют его работать сейчас.

Ответ №1:

 cp config.sh.945 ' /home/WASTEBASKIT'
cp: cannot stat 'config.sh.945': No such file or directory
  

Проблема в этой строке:

 cp "$1" "$1.$$" "/home/WASTEBASKIT"
  

Вы пытаетесь скопировать два файла в /home/WASTEBASKIT , а именно $1 и $1.$$ . Последний не существует.

Измените его на:

 cp "$1" "/home/WASTEBASKIT/$1.$$"
  

Я предлагаю вам вместо этого создать уникальный файл, поскольку номера процессов не уникальны, поэтому вместо приведенной выше копии сделайте что-то вроде:

 newfile=$(mktemp "WASTEBASKIT/$1.XXXXXXX")
cp -p "$1" "$newfile"
  

Затем вы можете перечислить все копии с ls -t WASTEBASKIT помощью, чтобы получить их в историческом порядке, сначала самые новые, или с ls -tr WASTEBASKIT помощью, чтобы сначала получить самые старые.

Также обратите внимание: printf'%sn' "File not found." скорее всего, будет генерироваться ошибка, подобная printf%sn: command not found... . Вам нужно вставить пробел между командой printf и аргументом '%sn' .

Движущаяся часть также неверна, поскольку у вас есть пробел раньше /home . Это должно быть:

 mv "$1" /home/WASTEBASKIT
  

Ответ №2:

 mv "$1" " /home/WASTEBASKIT"
  

Первая проблема: пробелы имеют значение. Если вы ранее создали /home/WASTEBASKIT каталог, а затем выполнили эту команду копирования выше, она не скопирует файл в этот каталог — скорее всего, в конечном итоге файл в вашем домашнем каталоге будет вызван spaceWASTEBASKIT (если у вас уже нет каталога с таким именем, включая начальный пробел), и в этом случае он будетперейдет в этот каталог.

В любом случае, он не пойдет туда, куда вы хотите.

Во-вторых, приведенная ниже команда выполняет не то, что вы, кажется, думаете. Он попытается скопировать два файла в каталог, второй из которых, вероятно, даже не существует ( config.sh.945 в вашем случае):

 cp "$1" "$1.$$" "/home/WASTEBASKIT"
  

Если вы хотите создать файл с «уникальной» версией, чтобы не перезаписывать существующий, это будет:

 mv "$1" "/home/WASTEBASKIT/$1.$$" 
  

Обратите внимание на кавычки вокруг слова «уникально», поскольку нет гарантии $1.$$ , что они также могут отсутствовать в корзине для мусора — идентификаторы PID в конечном итоге в какой-то момент оборачиваются, а также делают это при перезагрузке.

Я подозреваю, что лучшим подходом (хотя и не пуленепробиваемым) было бы просто указывать в каждом файле дату и время, чтобы:

  • вы можете отсортировать дубликаты, чтобы установить порядок создания; и
  • без изменений даты дата / время не даст вам возможных дубликатов (если вы не делаете это чаще одного раза в секунду).

Такой подход был бы чем-то вроде:

 mv "$1" "/home/WASTEBASKIT/$(date -u  %Y%m%d_%H%M%S)$1"
  

или, делая дубликаты еще менее вероятными:

 mv "$1" "/home/WASTEBASKIT/$(date -u  %Y%m%d_%H%M%S)_${RANDOM}_$1"