Резервная копия сценария оболочки

Единственный известный мне способ сделать то, о чем вы просите, это использовать chattr (1 ), имя которого предполагает изменение атрибутов файлов.

В разделе атрибутов вы можете прочитать:

"Файл с атрибутом 'i' не может быть изменен :его нельзя удалить или переименовать, нельзя создать ссылку на этот файл, большую часть метаданных файла нельзя изменить, и файл нельзя открыт в режиме записи. Только суперпользователь или процесс, обладающий возможностью CAP _LINUX _IMMUTABLE, может устанавливать или очищать этот атрибут».

--практический случай:

: lsattr example.file
------------------- example.file
: ls -lh example.file 
-rw------- 1 tntx tntx 15 Dec 23 20:43 example.file
: su -
Password:
root@foo: chattr +i example.file
root@foo: exit
logout
: lsattr example.file 
----i-------------- example.file
: cat example.file 
testing chattr
: echo "adding text" >> example.file 
ksh93: example.file: cannot create [Operation not permitted]

Same with vi:
Read-only file, not written; use ! to override.
:w!
Error: example.file: Operation not permitted.

And then trying to mv:
: mv example.file example.file2 
mv: cannot move 'example.file' to 'example.file2': Operation not permitted

What about cp:
: ls -lh example.file*
-rw------- 1 tntx tntx 15 Dec 23 20:43 example.file
-rw------- 1 tntx tntx 15 Dec 23 21:02 example.file2
: /usr/bin/lsattr example.file*
----i-------------- example.file
------------------- example.file2

Таким образом, это не удается, потому что вы можете заблокировать файл, чтобы он был доступен только для чтения пользователем, но вы можете свободно копировать (1 )и редактировать в новом файле.

0
15.03.2021, 15:33
2 ответа

Давайте проигнорируем кавычки, синтаксис и т.д. замечания, а также тот факт, что тег Kali -linux неуместен, потому что он здесь неуместен, а Kali предназначена для опытных пользователей.

#!/bin/bash 
echo "Menu" 
echo "1. Backup file"
echo "2. Quit" 
echo "Enter Choice" 
read Choice

Итак, ваш выбор теперь либо 1, либо 2(, либо множество других различных входных данных, которые мы просто игнорируем)

case "$Choice" in 
       1) while : 
               echo "Enter file name" 
               read file name 
               do 

Вы прочитали 2 переменные fileи name, ни одна из которых не используется в остальной части скрипта. Вы, вероятно, имели в виду что-то вроде этого:

       (1) while read -p "Enter file name" filename ; do
            

if [ -f $filename]всегда верно, потому что filenameпусто в вашем скрипте. Если бы вы прочитали filenameвместо file name, результат был бы

.
bash: [: missing `]'

Перед ]необходимо вставить пробел. (можно и процитировать)

               if [ -f "$filename" ] ; then
                      current_time=$(date "+%Y.%m.%d")
                      back_up="Backup"
                      new_file="$filename.$back_up.$current_time" # quotes
                      echo "New file name is: $new_file"
                      cp $new_file $HOME 

Вы вводите имя файла (, скажем foo), и копируете foo.Backup.2021.03.15в свой домашний каталог. Этот файл существует? вероятно, нет, потому что вы получите сообщение cp: cannot stat foo.Backup.2021.03.15: No such file or directoryИтак, вы, вероятно, хотите скопировать foo.

cp "$filename"  "$HOME/$new_file"

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

                   echo "Copying $filename to $HOME/$new_file"
                   cp "$filename"  "$HOME/$new_file"
              else 
                      echo "file does not exists"
              fi 
            done 
             ;;

Вам нужно будет прервать этот цикл while -с помощью ^D. Надеюсь, вы не ожидали, что второй оператор case выйдет из вашего цикла.

         2) echo "Program Terminated" 
                 exit;;
esac

Надеюсь, это поможет.

1
18.03.2021, 22:24

Предположим, что пользователь действительно хочет сделать резервную копию файла, если он запускает ваш скрипт. Это означает, что интерактивное меню не нужно.

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

Итак,мы получаем

#!/bin/bash

if [ "$#" -eq 0 ]; then
    cat >&2 <<END_USAGE
This script backs up files and places backups in your
home directory with a timestamp as filename suffix.

Usage:

    $0 file [...]

END_USAGE
    exit 1
fi

printf -v suffix 'backup.%(%Y.%m.%d)T' -1

for pathname do
    if [ ! -f "$pathname" ]; then
        printf '"%s" is not found or is not a regular file, ' "$pathname"
        printf 'will not back it up\n'
        continue
    fi >&2

    printf -v newname '%s.%s' "${pathname##*/}" "$suffix"

    if cp -i "$pathname" "$HOME/$newname"; then
        printf 'backed up "%s" as "%s" in your home directory\n' \
            "$pathname" "$newname"
    else
        printf 'failed backing up "%s" as "%s" in your home directory\n' \
            "$pathname" "$newname" >&2
    fi
done

Единственная причина, по которой bashвыполняет это, состоит в том, чтобы иметь возможность использовать printf -vв нескольких местах, и чтобы избавиться от необходимости запускать dateдля получения метки времени (это будет работать с bashверсия 4.2 или более поздняя ).

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

Если заданные аргументы командной строки($#больше нуля ), они повторяются.

В каждой итерации мы проверяем, существует ли данный аргумент в виде обычного файла (или символической ссылки на обычный файл ), и в противном случае переходим к следующему.

Затем создается новое имя файла с использованием переменной suffix(, созданной ранее ), и базового имени текущего значения pathname.

Мы запускаем копирование с помощью cp -i, чтобы у пользователя была возможность отказаться от перезаписи файла на тот случай, если этот резервный файл уже существует.

Тестирование:

$./script script
backed up "script" as "script.backup.2021.03.15" in your home directory
$./script scriptantoeh
"scriptantoeh" is not found or is not a regular file will not back it up
$./script file{1..3}
"file1" is not found or is not a regular file will not back it up
"file2" is not found or is not a regular file will not back it up
"file3" is not found or is not a regular file will not back it up
$./script script
overwrite /home/myself/script.backup.2021.03.15? y
backed up "script" as "script.backup.2021.03.15" in your home directory
1
18.03.2021, 22:24

Теги

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