LinuxForum.Fans
Тема

Пишем скрипты в Linux (обучение на примерах)

Автор: forkostya 29 сообщений 153348 просмотров
#1427

Автор: Кузнецов Константин

Пишем скрипты в Linux (обучение на примерах)

Содержание:
1. Введение
2. Обучение написанию сценариев на внутреннем языке BASH (Перевод с англ.)
3. Используемая и рекомендуемая литература

----------------------------------------------------------------------------------

1. Введение

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

Материал из Википедии — свободной энциклопедии
Скриптовый язык (англ. scripting language, в русскоязычной литературе принято название язык сценариев) — язык программирования, разработанный для записи «сценариев», последовательностей операций, которые пользователь может выполнять на компьютере. Простые скриптовые языки раньше часто называли языками пакетной обработки (batch languages или job control languages). Сценарии обычно интерпретируются, а не компилируются (хотя часто сценарии компилируются каждый раз перед запуском).
В прикладной программе, сценарий (скрипт) — это программа, которая автоматизирует некоторую задачу, которую без сценария пользователь делал бы вручную, используя интерфейс программы.

----------------------------------------------------------------------------------

2. Обучение написанию сценариев на внутреннем языке BASH
оригинал: http://www.linuxconfig.org/Bash_scripting_Tutorial

Это руководство предполагает отсутствие предварительных знаний о методике написания сценариев (далее скриптов) с помощью внутреннего языка Bash. С помощью данного руководства вы обнаружите в скором времени, что написание скриптов очень простая задача. Давайте начнем наше обучение с простого сценария, выполняющего вывод строки "Hello World!" (в перев. с англ. - Всем привет!)

1) Сценарий "Всем привет"
Вот ваш первый пример bash-скрипта:

#!/bin/bash
echo "Hello World"
Переходим в директорию, содержащую наш файл hello_world.sh и делаем его исполняемым:
text
$ chmod +x hello_world.sh

Запускаем скрипт на выполнение

text
$ ./hello_world.sh

2) Простой архивирующий bash-скрипт

#!/bin/bash
tar -czf myhome_directory.tar.gz /home/user
text
$ ./backup.sh
tar: Removing leading '\' from member names
$ du -sh myhome_directory.tar.gz
41M myhome_directory.tar.gz

3) Работа с переменными
В данном примере мы объявляем простую переменную и выводим её на экран с помощью команды echo

#!/bin/bash
STRING="HELLO WORLD!!!"
echo $STRING
text
$ ./hello_world.sh
HELLO WORLD!!!

Наш архивирующий скрипт с переменными:

#!/bin/bash
OF=myhome_directory_$(date +%Y%m%d).tar.gz
IF=/home/user
tar -czf $OF $IF
text
$ ./backup.sh
tar: Removing leading '\' from member names
$ du -sh *tar.gz
41M myhome_directory_20100123.tar.gz

3.1) Глобальные и локальные переменные

#!/bin/bash
# Объявляем глобальную переменную
# Такая переменная может использоваться в любом месте этого скрипта
VAR="global variable"
function bash {
# Объявляем локальную переменную
# Такая переменная действительна только для функции, в которой её объявили
local VAR="local variable"
echo $VAR
}
echo $VAR
bash
# Обратите внимание, что глобальная переменная не изменилась
echo $VAR
text
$ ./variables.sh
global variable
local variable
global variable

4) Передаем аргументы в скрипт

#!/bin/bash
# Используйте предопределенные переменные для доступа к аргументам
# Выводим аргументы на экран
echo $1 $2 $3 ' -> echo $1 $2 $3'

#Мы так же можем получить доступ к аргументам через специальный массив args=("$@")
# Выводим аргументы на экран
echo ${args[0]} ${args[1]} ${args[2]} ' -> args=("$@"); echo ${args[0]} ${args[1]} ${args[2]}'

# Используйте переменную $@ для вывода всех аргументов сразу
echo $@ ' -> echo $@'

Используйте переменную $# для вывода количества переданный в скрипт аргументов
echo Number of arguments passed: $# ' -> echo Number of arguments passed: $#'
text
$ ./arguments.sh Bash Scripting Tutorial
Bash Scripting Tutorial -> echo $1 $2 $3
Bash Scripting Tutorial -> args=("$@"); echo ${args[0]} ${args[1]} ${args[2]}
Bash Scripting Tutorial -> echo $@
Number of arguments passed: 3  -> echo Number of arguments passed: $#

5) Выполнение в скрипте команд оболочки

#!/bin/bash
# используйте обратные кавычки " ` ` " для выполнения команды оболочки
echo `uname -o`
# теперь попробуем без кавычек
echo uname -o
text
$ uname -o
GNU/Linux
$ ./bash_backtricks.sh
GNU/Linux
uname -o

Как видим, во втором случае вывелась сама команда, а не результат её выполнения

6) Читаем пользовательский ввод (интерактивность)

#!/bin/bash
echo -e "Hi, please type the word: \c "
read word
echo "The word you entered is: $word"
echo -e "Can you please enter two words? "
read word1 word2
echo "Here is your input: \"$word1\" \"$word2\""
echo -e "How do you feel about bash scripting? "
# read command now stores a reply into the default build-in variable $REPLY
read
echo "You said $REPLY, I'm glad to hear that! "
echo -e "What are your favorite colours ? "
# -a makes read command to read into an array
read -a colours
echo "My favorite colours are also ${colours[0]}, ${colours[1]} and ${colours[2]}:-)"
text
$ ./read.sh
Hi, please type the word: something
The word you entered is: something
Can you please enter two words?
Debian Linux
Here is your input: "Debian" "Linux"
How do you feel about bash scripting?
good
You said good, I'm glad to hear that!
What are your favorite colours ? 
blue green black
My favorite colours are also blue, green and black  :-)

7) Использование ловушки

#!/bin/bash
# объявляем ловушку
trap bashtrap INT
# очищаем экран
clear;
# функция ловушки выполняется, когда пользователь нажимает CTRL-C:
# На экран будет выводиться => Executing bash trap subrutine !
# но скрипт будет продолжать выполняться
bashtrap()
{
echo "CTRL+C Detected !...executing bash trap !"
}
# скрипт будет считать до 10
for a in `seq 1 10`; do
echo "$a/10 to Exit."
sleep 1;
done
echo "Exit Bash Trap Example!!!"
text
$ ./trap.sh
1/10
2/10
3/10
4/10
5/10
6/10
CTRL+C Detected !...executing bash trap !
7/10
8/10
9/10
CTRL+C Detected !...executing bash trap !
10/10
Exit Bash Trap Example!!!

Как видим, сочетание клавишь Ctrl-C не остановило выполнение скрипта.

8) Массивы
8.1) Объявляем простой массив

#!/bin/bash
# Объявляем простой массив с 4 элементами
ARRAY=( 'Debian Linux' 'Redhat Linux' Ubuntu Linux )
# Получаем количество элементов в массиве
ELEMENTS=${#ARRAY[@]}

# выводим в цикле каждый элемент массива
for (( i=0;i<$ELEMENTS;i++)); do
echo ${ARRAY[${i}]}
done
text
$./arrays.sh
Debian Linux
Redhat Linux
Ubuntu
Linux

8.2) Заполняем массив значениями из файла

#!/bin/bash
# Объявляем массив
declare -a ARRAY
# Команда exec <filename перенаправляет ввод со stdin на файл. С этого момента весь ввод, вместо
# stdin (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать
# содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.
exec 10<bash.txt
let count=0

while read LINE <&10; do

ARRAY[$count]=$LINE
((count++))
done

echo Number of elements: ${#ARRAY[@]}
# Вывод значений массива
echo ${ARRAY[@]}
# закрываем файл
exec 10>&-
text
$ cat bash.txt
Debian Linux
Redhat Linux
Ubuntu
Linux
$ ./arrays.sh
Number of elements: 4
Debian Linux Redhat Linux Ubuntu Linux

9) Условия "если-то-иначе"
9.1) Простое использование "если-иначе" условий
Обратите внимание на пробелы в квадратных скобках, без которых условие работать не будет.

#!/bin/bash
directory="./BashScripting"

# проверяем наличие директории
if [ -d $directory ]; then
echo "Directory exists"
else
echo "Directory does not exists"
fi
text
$ ./if_else.sh
Directory does not exists
$ mkdir BashScripting
$ ./if_else.sh
Directory exists

9.2) Вложенные "если-иначе" условия

#!/bin/bash
# Объявляем переменную со значением 4
choice=4
# Выводим на экран
echo "1. Bash"
echo "2. Scripting"
echo "3. Tutorial"
echo -n "Please choose a word [1,2 or 3]? "
# Выполняем, пока переменная равна четырем
# Зацикливание
while [ $choice -eq 4 ]; do

# читаем пользовательский ввод
read choice
# вложенное "если-иначе" условие
if [ $choice -eq 1 ] ; then

echo "You have chosen word: Bash"

else

if [ $choice -eq 2 ] ; then
echo "You have chosen word: Scripting"
else

if [ $choice -eq 3 ] ; then
echo "You have chosen word: Tutorial"
else
echo "Please make a choice between 1-3 !"
echo "1. Bash"
echo "2. Scripting"
echo "3. Tutorial"
echo -n "Please choose a word [1,2 or 3]? "
choice=4
fi
fi
fi
done
text
$ ./nested.sh
1. Bash
2. Scripting
3. Tutorial
Please choose a word [1,2 or 3]? 
5
Please make a choice between 1-3 !
1. Bash
2. Scripting
3. Tutorial
Please choose a word [1,2 or 3]? 
4
Please make a choice between 1-3 !
1. Bash
2. Scripting
3. Tutorial
Please choose a word [1,2 or 3]? 
3
You have chosen word: Tutorial

Таким образом сначала тело цикла "while" выполняется, т.к. переменная choice изначально равна четырем. Потом читаем в неё пользовательский ввод, и если ввод не равен 1,2 или 3 то делаем нашу переменную снова равную 4, в связи с чем тело цикла повторяется (снова необходимо вводить 1,2 или 3).

10) Сравнения
10.1) Арифметические сравнения

-lt <
-gt >
-le <=
-ge >=
-eq ==
-ne !=
#!/bin/bash
# Объявляем переменные с целочисленными значениями
NUM1=2
NUM2=2
if [ $NUM1 -eq $NUM2 ]; then
echo "Both Values are equal"
else
echo "Values are NOT equal"
fi
text
$ ./equals.sh
Both Values are equal

#!/bin/bash
# Объявляем переменные с целочисленными значениями
NUM1=2
NUM2=3
if [ $NUM1 -eq $NUM2 ]; then
echo "Both Values are equal"
else
echo "Values are NOT equal"
fi
text
$ ./equals.sh
Values are NOT equal

#!/bin/bash
# Объявляем переменные с целочисленными значениями
NUM1=2
NUM2=1
if [ $NUM1 -eq $NUM2 ]; then
echo "Both Values are equal"
elif [ $NUM1 -gt $NUM2 ]; then
echo "$NUM1 is greater then $NUM2"
else
echo "$NUM2 is greater then $NUM1"
fi
text
$ ./equals.sh
2 is greater then 1

10.2) Символьно-текстовые сравнения

= одинаковые
!= не одинаковые
< меньще чем
> больше чем
-n s1 переменная s1 не пустая
-z s1 переменная s1 пустая
#!/bin/bash
# Объявляем символьную переменную S1
S1="Bash"
# Объявляем символьную переменную S2
S2="Scripting"
if [ $S1 = $S2 ]; then
echo "Both Strings are equal"
else
echo "Strings are NOT equal"
fi
text
$ ./statement.sh
Strings are NOT equal

#!/bin/bash
# Объявляем символьную переменную S1
S1="Bash"
# Объявляем символьную переменную S2
S2="Bash"
if [ $S1 = $S2 ]; then
echo "Both Strings are equal"
else
echo "Strings are NOT equal"
fi
text
$ ./statement.sh
Both Strings are equal

11) Проверка файлов

-b filename Block special file
-c filename Special character file
-d directoryname Check for directory existence
-e filename Check for file existence
-f filename Check for regular file existence not a directory
-G filename Check if file exists and is owned by effective group ID.
-g filename true if file exists and is set-group-id.
-k filename Sticky bit
-L filename Symbolic link
-O filename True if file exists and is owned by the effective user id.
-r filename Check if file is a readable
-S filename Check if file is socket
-s filename Check if file is nonzero size
-u filename Check if file set-ser-id bit is set
-w filename Check if file is writable
-x filename Check if file is executable
#!/bin/bash
file="./file"
if [ -e $file ]; then
echo "File exists"
else
echo "File does not exists"
fi
text
$ ls
file.sh
$ ./file.sh
File does not exists
$ touch file
$ ls
file  file.sh
$ ./file.sh
File exists

Аналогично для примера мы можем использовать "в то время как" петли, чтобы проверить, если файл не существует. Этот сценарий будет спать, пока файл не существует. Обратите внимание на Bash отрицатель "!" что сводит на нет (инвертирует) -e опцию.

12) Циклы
12.1) Цикл For

#!/bin/bash
# for цикл
for f in $( ls /var/ ); do
echo $f
done
Запуск for-цикла из командной строки bash:
text
$ for f in $( ls /var/ ); do echo $f; done 
text
$ for f in $( ls /var/ ); do echo $f; done
backups
cache
crash
games
lib
local
lock
log
mail
opt
run
spool
tmp
www

12.2) While цикл

#!/bin/bash
COUNT=6
# while цикл
while [ $COUNT -gt 0 ]; do
echo Value of count is: $COUNT
let COUNT=COUNT-1
done
text
$ ./while_loop.sh
Value of count is: 6
Value of count is: 5
Value of count is: 4
Value of count is: 3
Value of count is: 2
Value of count is: 1

12.3) Until цикл

#!/bin/bash
COUNT=0
# until цикл
until [ $COUNT -gt 5 ]; do
echo Value of count is: $COUNT
let COUNT=COUNT+1
done
text
$ ./until_loop.sh
Value of count is: 0
Value of count is: 1
Value of count is: 2
Value of count is: 3
Value of count is: 4
Value of count is: 5

12.4) Циклы с неявными условиями
В следующем примере условием while-цикла является наличие стандартного ввода.
Тело цикла будет выполняться пока есть чему перенаправляться из стандартного вывода в команду read.

#!/bin/bash
# Данный скрипт будет искать и удалять пробелы
# в файлах, заменяя их на подчеркивания
DIR="."
Управление циклом с командой read путем перенаправления вывода в цикле.
find $DIR -type f | while read file; do
# используем POSIX-класс [:space:] чтобы найти пробелы в именах файлов
if [[ "$file" = *[[:space:]]* ]]; then
# замена пробелов подчеркиваниями
mv "$file" `echo $file | tr ' ' '_'`
fi;
done
text
$ ls -1
script.sh
$ touch "file with spaces"
$ ls -1
file with spaces
script.sh
$ ./script.sh
$ ls -1
file_with_spaces
script.sh

13) Функции

#!/bin/bash
# Функции могут быть объявлены в любом порядке
function function_B {
echo Function B.
}
function function_A {
echo $1
}
function function_D {
echo Function D.
}
function function_C {
echo $1
}
# Вызываем функции
# передаем параметр в функцию function A
function_A "Function A."
function_B
# передаем параметр в функцию function C
function_C "Function C."
function_D
text
$ ./functions.sh
Function A.
Function B.
Function C.
Function D.

14) Оператор выбора - Select

#!/bin/bash
PS3='Choose one word: '
# select
select word in "linux" "bash" "scripting" "tutorial"
do
echo "The word you have selected is: $word"
# Прерываем, в противном случае цикл будет бесконечный.
break
done
exit 0
text
$ ./select.sh
1) linux
2) bash
3) scripting
4) tutorial
Choose one word: 4
The word you have selected is: tutorial

15) Оператор выбора - Case

#!/bin/bash
echo "What is your preferred programming / scripting language"
echo "1) bash"
echo "2) perl"
echo "3) phyton"
echo "4) c++"
echo "5) I do not know !"
read case;
# простая структура case-выбора
# обратите внимание, что в данном примере $case - всего лишь переменная
# и не обязана так называться. Это лишь пример
case $case in
1) echo "You selected bash";;
2) echo "You selected perl";;
3) echo "You selected phyton";;
4) echo "You selected c++";;
5) exit
esac
text
$ ./case.sh
What is your preferred programming / scripting language
1) bash
2) perl
3) phyton
4) c++
5) I do not know !
4
You selected c++

----------------------------------------------------------------------------------

3. Используемая и рекомендуемая литература

Более подробную информацию можно получить из различных источников, например отсюда
оригинал: http://www.linuxconfig.org/Bash_scripting_Tutorial
http://ruslandh.narod.ru/howto_ru/Bash-Prog-Intro/
http://bug.cf1.ru/2005-03-17/programming/bash/abs-book.html

#3727

а как вписать в автозагрузку скрипт который лежит /home/oleg/scripts имя скрипта conky.sh ?

#3804

Vartonst, вариантов масса, способ зависит от используемого ПО.
Один из них: добавить в ~/.xsession (или .xinitrc)

text
/home/oleg/scripts/conky.sh &

только не в конец, а перед запуском оконного менеджера.
К несчастью, я не уверен, что всё пойдёт гладко, ибо наверняка вы используете gdm ): (или kdm)
Anyway, http://en.gentoo-wiki.com/wiki/HOWTO_Autostart_Programs здесь Вы наверняка найдёте решение

#27264
ДимOn написал:
А покажите пример скрипта, как с клиента подключиться к ssh-серверу, перенести на машину клиента определенные файлы и отключиться.

Нашел способ, так как авторизация по ключу не очень подходит, то делаем так:
Сначала ставим sshpass

text
aptitude install sshpass

А теперь скрипт, для синхронизации

text
#!/bin/sh
sshpass -p пароль_к_ssh rsync -e ssh --progress -thvr имя_пользователя@IP:/Указываем_путь_откуда/ /Указываем_путь_куда/
#30727

в crontab стоит бэкап баз демоном rsync.
как запихнуть, что он делает, все в $(date +...).log? кроме --log-file='/...'

#30734

а чем --log-file не устраивает?

#30743
6OTuHO4Er написал:
в crontab стоит бэкап баз демоном rsync.
как запихнуть, что он делает, все в $(date +...).log? кроме --log-file='/...'

..... 1>/var/log/aaa.log 2>/var/log/aaa.errors.log

#134183

Добрый день! Пока не умею писать скрипты. В общем передо мной стоит задача - настроить бэкап БД постгреса со следующими параметрами:

  • чтобы бэкап имел максимально сжатие
  • Кол-во хранимых бэкапов в определенном каталоге не превышал определенного кол-ва
  • Имя бэкапа задавалось исходя из текущей даты, например: - postgres_YYYY-MM-DD

Может кто поможет с этим делом?

#134184

Или может кто нибудь переделает этот скрипт?

text
#!/bin/bash
date=`date "+%Y_%m_%d"`;                                                 # Получим текущую дату в устраивающем нас формате и запишем ее в переменную $date
days_open_store='14';                                                   # Сколько дней хранить незашифрованные бэкапы
days_crypt_store='60';                                             # Сколько дней хранить зашифрованные бэкапы
dir_crypt=/media/remote_share                                   # Каталог для зашифрованных бэкапов, надо чтобы был смонтирован.
dir_open=/local_backup                                                   # Каталог для незашифрованных бэкапов (нужны, чтобы можно было быстро восстановить упавшую дазу одынце)
gpgdir=/backup/gpg_dir                                                             # Каталог, где лежит .gpg-файл с открытым ключом, которым будут шифроваться бэкапы
gpgkey='0xABCDEFGH';                                                     # PGP_ID ключа для зашифровки бэкапов
# GnuPG compessing & trust options
gpgzip='--compress-algo zip --compress-level 9 --trust-model always --batch'; # Параметры шифрования
rar_bin=/bin/rar                                                                 # Путь к бинарю к консольным никсовым RAR-ом
# Command and options for PostgreSQL Dump
pgdump_binc='/usr/bin/pg_dump -i -h localhost -p 5432 -U postgres -F c -b -o -v -f'; # Часть команды для генерации сжатых дампов
pgdump_bin='/usr/bin/pg_dump -h localhost -U postgres '; # Часть команды для генерации обычных SQL-дампов
mysqldump_bin='mysqldump -u_backuper -hlocalhost -pPASSWD'; # Часть команды для дампинга MySQL

echo "=== BackUp script for Server === [$date]"; mkdir $dir_open/$date mkdir $dir_crypt/$date sync

echo 'Make open archives ...'; cd $dir_open/$date $pgdump_binc 1c_postgre_compressed_dump.bak 1c_database $pgdump_binc postgre_sysdb_compressed.bak postgres $pgdump_bin 1c_database | gzip > 1c_postgre_sql_dump.gz $pgdump_bin postgres | gzip > postgre_sysdb_sql_dump.gz

/* Тут раскурено не до конца. 1C:Конфигуратор 8.1 работает в WINE, и нормально выгружает / загружает базы через dt-файлы. Но из консоли не работает, пишет, что не может соединиться с X-сервером. Похоже, что даже в режиме /DumpIB конфигуратор стартует как графическое приложение, так что как это решить в консоли, пока не понятно. Буду рад совету !!! */ #sudo -ucyka -H='/home/cyka' wineconsole /home/cyka/wine_c/windows/system32/cmd.exe /c 'C:/1cv81/bin/1cv8.exe config /s Server\1c_database /DisableStartupMessages /n backuper /p PASSWD /DumpIB D:/1C.dt' # mv /.../.../1C.dt $dir_open/$date # Надо бы переменную с датой вставить в предыдущую строку, но все равно эта часть пока не работает.

$rar_bin a -r -rr5 -dh -mdG -ep1 -ol -ow manager_files.rar /mnt/sda1/smb/managers $rar_bin a -r -rr5 -dh -mdG -ep1 -ol -ow buh_files.rar /mnt/sda1/smb/buh

$mysqldump_bin --databases --all-databases | gzip -c > _mysql_sql_dump.gz # Это правильный дамп. #$rar_bin a -r -rr5 -dh -mdG -ep1 -ol -ow _mysql_db.rar /var/mysql/data # А вот так делать не стоит. # Но с базой ничего страшного не случится. Хотя в таком "бэкапе" может и фигня получится.

$rar_bin a -r -rr5 -dh -mdG -ep1 -ol -ow etc.rar /etc $rar_bin a -r -rr5 -dh -mdG -ep1 -ol -ow home.rar /home sync

echo 'Make crypted archives ...'; gpg --homedir $gpgdir -e -r $gpgkey -o 1c_postgre_compressed.swp $gpgzip 1c_postgre_compressed.bak gpg --homedir $gpgdir -e -r $gpgkey -o postgre_sysdb_compressed.swp $gpgzip postgre_sysdb_compressed.bak gpg --homedir $gpgdir -e -r $gpgkey -o 1c_postgre_sql_dump.swp $gpgzip 1c_postgre_sql_dump.gz gpg --homedir $gpgdir -e -r $gpgkey -o postgre_sysdb_sql_dump.swp $gpgzip postgre_sysdb_sql_dump.gz gpg --homedir $gpgdir -e -r $gpgkey -o buh_files.swp $gpgzip buh_files.rar gpg --homedir $gpgdir -e -r $gpgkey -o manager_files.swp $gpgzip manager_files.rar #gpg --homedir $gpgdir -e -r $gpgkey -o _mysql_db.swp $gpgzip _mysql_db.rar # Бэкапить MySQL прямым копированием - зело =) gpg --homedir $gpgdir -e -r $gpgkey -o _mysql_sql_dump.swp $gpgzip _mysql_sql_dump.gz gpg --homedir $gpgdir -e -r $gpgkey -o etc.swp $gpgzip etc.rar gpg --homedir $gpgdir -e -r $gpgkey -o home.swp $gpgzip home.rar #gpg --homedir $gpgdir -e -r $gpgkey -o 1c_dt.swp $gpgzip 1C.dt # Пока не работает. sync

echo 'Move crypted archives ...'; mv $dir_open/$date/*.swp $dir_crypt/$date sync

echo 'Delete old backups ...'; # Тут есть одна шняга. От старых бэкапов остаются пустые каталоги. То есть файлы внутри каталогов со старыми бэкапами сносятся, а сами каталоги - нет. # Надо как-нить побороть лень и сделать более изящно. Срок хранения зашифрованных и незашифрованных бэкапов разный !! find $dir_open/ -mtime +$days_open_store -delete # Удалим все устаревшие незашифрованные бэкапы find $dir_crypt/ -mtime +$days_crypt_store -delete # Удалим все устаревшие зашифрованные бэкапы

echo "=== BackUp script complete ===== [$date]";

#134189

Тут попробовал сделать скрипт архивирования по учебнику. Такого содержания:
[console]#!/bin/bash
backup_dir1=myhome_directory_$(date +%Y-%m-%d).tar.gz
backup_dir2=/home/shared/public/
tar -czf $backup_dir2 $backup_dir1[/console]

Выдает ошибку:
[console]tar: myhome_directory_2011-02-27.tar.gz: Функция stat завершилась с ошибкой: Нет такого файла или каталога
tar: /home/shared/public/: Функция open завершилась с ошибкой: Это каталог
tar: Неисправимая ошибка: завершение работы
tar: Child returned status 2
tar: Завершение работы с состоянием неисправности с из-за возникших ошибок[/console]

Что сделал неправильно?

#134190
Nigelist написал:
Тут попробовал сделать скрипт архивирования по учебнику. Такого содержания:
[console]#!/bin/bash
backup_dir1=myhome_directory_$(date +%Y-%m-%d).tar.gz
backup_dir2=/home/shared/public/
tar -czf $backup_dir2 $backup_dir1[/console]

Выдает ошибку:
[console]tar: myhome_directory_2011-02-27.tar.gz: Функция stat завершилась с ошибкой: Нет такого файла или каталога
tar: /home/shared/public/: Функция open завершилась с ошибкой: Это каталог
tar: Неисправимая ошибка: завершение работы
tar: Child returned status 2
tar: Завершение работы с состоянием неисправности с из-за возникших ошибок[/console]

Что сделал неправильно?

[console]#!/bin/bash
backup_dir1=myhome_directory_$(date +%Y-%m-%d).tar.gz
backup_dir2=/home/shared/public/
tar -czf $backup_dir1 $backup_dir2[/console]
Так попробуйте.

#134209
Nigelist написал:
Тут попробовал сделать скрипт архивирования по учебнику. Такого содержания:

выкиньте свой учебник на помойку.
читайте это.

Nigelist написал:
Добрый день! Пока не умею писать скрипты. В общем передо мной стоит задача - настроить бэкап БД постгреса со следующими параметрами:

1 * чтобы бэкап имел максимально сжатие
2 * Кол-во хранимых бэкапов в определенном каталоге не превышал определенного кол-ва
3 * Имя бэкапа задавалось исходя из текущей даты, например: - postgres_YYYY-MM-DD

Может кто поможет с этим делом?

1) man xz
2) man ls, man head
3) man date

#134272
drBatty написал:
выкиньте свой учебник на помойку.
читайте это.

drBatty, я имел в виду статью на этой странице... smile
Эта книга нормальная?

#134297
Nigelist написал:
я имел в виду статью на этой странице...

ладно, оставим нужную trow на совести Кузнецова :)

Nigelist написал:
Эта книга нормальная?

я про неё и говорил.
а вообще вам нужно man tar && info tar
читать (что такое && знаете уже?)

#134304
drBatty написал:
читать (что такое && знаете уже?)

Ага знаю. Еще не спец, но уже не чайник... smile

#257421

Нужно написать скрипт, который будет делать бэкап. Исходя из примеров вот написал. Где я ошибся? :)

text

#!/bin/bash
if [(-d $"/srv/backup") -eq 0]
    mdir /srv/backup
fi

cd /srv/backup tar -cvf $(date +%Y-%m-%d).tar.gz /srv/firma1 /srv/firma2 /srv/firma3

#257423

Ошибки:
[(-d, mdir, пропущен then

Можно проще:

text

#!/bin/bash

mkdir /srv/backup 2> /dev/null cd /srv/backup tar -cvf $(date +%Y-%m-%d).tar.gz /srv/firma1 /srv/firma2 /srv/firma3

#257425

mkdir /srv/backup 2> /dev/null

А можеш объяснить эту строчку, что означает 2> и dev здесь в виде оператора ? :[

#257427

Читать "man bash" на предмет перенаправления вывода.
2> -- перенаправление второго канала (stderr), куда выводятся ошибки. /dev/null -- устройство, всегда готовое к приёму данных, отправленные туда данные уходят "в никуда".

Если этого не сделать, mkdir будет ругаться в консоль на существующий каталог /srv/backup. В приведённом примере эта ругань отправляется в /dev/null и не раздражает пользователя.

#257430

Первоначальный вариант был бы таким (пробелы важны):

text

#!/bin/bash

BACKUP=/srv/backup

if [ ! -d $BACKUP ]; then mkdir $BACKUP fi cd $BACKUP tar zcvf $(date +%Y-%m-%d).tar.gz /srv/firma1 /srv/firma2 /srv/firma3

Войдите или зарегистрируйтесь, чтобы ответить.