Имитация действия команды mv

13

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

Если бы я использовал apt-get, я мог бы использовать -sфлаг, чтобы выполнить симуляцию, которая фактически делала бы что угодно.

Имеет ли mvаналогичную функцию, которая имитирует перемещение файлов, но на самом деле ничего не делает?

starbeamrainbowlabs
источник
2
В man mvя вижу только -iфлаг, который спрашивает перед перезаписью
Кев Ински
2
mvУ команды ничего нет simulate, но я могу написать функцию, которая делает такую ​​проверку. Как это решение?
Сергей Колодяжный
2
И как вы ожидаете, что симуляция будет выглядеть? Простая печать по одной строке для каждого измененного файла, например, «Переименовано a.txt в b, txt» или «Перемещено /home/you/a.txt в /home/you/Documents/a.txt»?
Byte Commander
@ByteCommander Что-то в этом роде, да. Я просто параноидально ошибаюсь, когда перемещаю свои личные ssl-сертификаты, чтобы организовать их.
starbeamrainbowlabs
4
-nВариант mvгарантирует , что Вы не можете перезаписать любые файлы по ошибке, а не ответ , но всегда полезно знать.
Arronical

Ответы:

2

Этот скрипт должен сделать свое дело. Он также может обрабатывать несколько исходных файлов / каталогов. Используйте его так же, как вы использовали бы mv- mvsim source... dest. Обратите внимание, что он не обращает внимания на параметры и не отфильтровывает их (он просто обрабатывает их как имена файлов) и может плохо работать с символическими ссылками.

#!/bin/bash

if [ $# -lt 2 ]; then
    echo "Too few arguments given; at least 2 arguments are needed."
    exit 1
fi

lastArg="${@:$#}"

i=1
for param in "$@"; do
    if [ ! -e "$param" -a $i -lt $# ]; then
        echo "Error: $param does not exist."
        exit 1
    elif [ "$param" = "$lastArg" -a $i -lt $# ]; then
        echo "Error: $param is the same file/directory as the destination."
        exit 1
    fi
    ((i++))
done

if [ $# -eq 2 ]; then # special case for 2 arguments to make output look better
    if [ -d "$1" ]; then
        if [ -d "$2" ]; then
            echo "Moves directory $1 (and anything inside it) into directory $2"
            exit 0
        elif [ ! -e "$2" ]; then
            echo "Renames directory $1 to $2"
            exit 0
        else
            echo "Error: $2 is not a directory; mv cannot overwrite a non-directory with a directory."
            exit 1
        fi
    else
        if [ -d "$2" ]; then
            echo "Moves file $1 into directory $2"
        elif [ -e "$2" ]; then
            echo "Renames file $1 to $2, replacing file $2"
        else
            echo "Renames file $1 to $2"
        fi
        exit 0
    fi
elif [ ! -e "$lastArg" ]; then
    echo "Error: $lastArg does not exist."
    exit 1
elif [ ! -d "$lastArg" ]; then
    echo "Error: $lastArg is not a directory; mv cannot merge multiple files into one."
    exit 1
fi

argsLeft=$#
echo "Moves..."
for param in  "$@"; do
    if [ $argsLeft -eq 1 ]; then
        echo "...Into the directory $param" # has to be a directory because -f $lastArg was dealt with earlier
        exit 0
    fi
    if [ -d "$param" ]; then
        if [ ! -d "$lastArg" ]; then
            echo "Error: $lastArg is not a directory; mv cannot overwrite a non-directory with a directory."
            exit 1
        fi
        if [ $argsLeft -eq $# ]; then
            echo "The directory ${param} (and anything inside it)..."
        else
            echo "And the directory ${param} (and anything inside it)..."
        fi
    else
        if [ $argsLeft -eq $# ]; then
            echo "The file ${param}..."
        else
            echo "And the file ${param}..."
        fi
    fi
    ((argsLeft--))
done

Несколько примеров:

$ ls
dir1  dir2  file1  file2  file3  mvsim
$ ./mvsim file1 file2
Renames file file1 to file2, replacing file file2
$ ./mvsim file1 newfile
Renames file file1 to newfile
$ ./mvsim file1 dir1
Moves file file1 into the directory dir1
$ ./mvsim file1 file2 file3 dir1
Moves...
The file file1...
And the file file2...
And the file file3...
...Into the directory dir1
$ ./mvsim file1 file2 dir1 dir2
Moves...
The file file1...
And the file file2...
And the directory dir1 (and anything inside it)...
...Into the directory dir2
$ ./mvsim file1 file2 file3 # error - file3 isn't a directory
Error: file3 is not a directory; mv cannot merge multiple files into one.
$ ./mvsim -f -i file1 dir1 # options aren't parsed or filtered out
Error: -f does not exist.
insert_name_here
источник
Благодарность! Я принимаю это как ответ на сценарий, который написал Серг, потому что он охватывает более 2 аргументов. maybeвыглядит хорошо, но я чувствую, что это более безопасный вариант в настоящее время.
starbeamrainbowlabs
10

Функция ниже предназначена для подробной проверки mvсинтаксиса. Обратите внимание, что он работает только для 2 аргументов, SOURCE и DESTINATION, и не проверяет наличие -tфлага.

Функция должна быть помещена в ~/.bashrc. Чтобы использовать его немедленно, откройте новый терминал или запуститеsource ~/.bashrc

mv_check()
{
    # Function for checking syntax of mv command 
    # sort of verbose dry run
    # NOTE !!! this doesn't support the -t flag
    # maybe it will in future (?)

    # check number of arguments  
    if [ $# -ne 2   ]; then
        echo "<<< ERROR: must have 2 arguments , but $# given "
        return 1
    fi

    # check if source item exist
    if ! readlink -e "$1" > /dev/null 
    then
        echo "<<< ERROR: " "$item" " doesn't exist"
        return 1
    fi

    # check where file goes

    if [ -d "$2"  ]
    then
        echo "Moving " "$1" " into " "$2" " directory"
    else
        echo "Renaming "  "$1" " to " "$2" 
    fi

}

Вот несколько тестовых прогонов:

$> mv_check  TEST_FILE1  bin/python                                                                                      
Moving  TEST_FILE1  into  bin/python  directory
$> mv_check  TEST_FILE1  TEST_FILE2                                                                                      
Renaming  TEST_FILE1  to  TEST_FILE2
$> mv_check  TEST_FILE1  TEST_FILE 2                                                                                     
<<< ERROR: must have 2 arguments , but 3 given 
$> mv_check  TEST_FILE1  TEST_FILE\ 2                                                                                    
Renaming  TEST_FILE1  to  TEST_FILE 2
$> mv_check  TEST_FILE1  "TEST_FILE 2"                                                                                   
Renaming  TEST_FILE1  to  TEST_FILE 2
$> mv_check  TEST_FILE1                                                                                                  
<<< ERROR: must have 2 arguments , but 1 given 
Сергей Колодяжный
источник
1
Вы должны добавить ay / n, чтобы продолжить и вызвать фактический mv. ;)
Часов
6

На github есть программа под названием возможно, которая может быть тем, что вы ищете.

Согласно их описанию проекта, maybe

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

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

maybeнужен Python для запуска, но это не должно быть проблемой. Его легко установить или собрать с помощью менеджера пакетов Python.

Процесс установки и использование программы описаны на домашней странице проекта. К сожалению, в настоящее время у меня нет доступа к системе Linux, поэтому я не могу предоставить вам ни одного примера использования программы.

maddin45
источник
Как хорошо все это звучит, согласно документации: «никогда не используйте maybeдля запуска ненадежного кода»!
grooveplex
@grooveplex Вы не доверяете внедрению в mvвашей системе?
maddin45
да, я понимаю, но это означало хедз-ап
grooveplex