Конструкция.
for VAR in List do команда done
Переменная $VAR принимает значения из списка List.
Цикл выполняется столько раз сколько элементов в списке.
Пример.
#!/bin/bash for i in 1 2 3 4 5 6 7 do echo "Print $i" done echo "Echo after done"
Результат.
kostya@aee3:~/BT$ ./for.sh Print 1 Print 2 Print 3 Print 4 Print 5 Print 6 Print 7 Echo after done
В командае не используется переменная которая перебирается в списке, при этом цикл так же будет выполняться.
#!/bin/bash for VAR in 1 2 3 4 5 6 7 do echo "Print $i" done echo "Echo after done"
Результат.
kostya@aee3:~/BT$ ./for.sh Print Print Print Print Print Print Print Echo after done
Сложные (с пробелами, спец символами) элементы списка можно задать в кавычках.
#!/bin/bash for i in 1 "2=3+11*345" 3ake "bla bla bla" 5 6 7 do echo "Print $i" done echo "Echo after done"
Результат.
kostya@aee3:~/BT$ ./for.sh Print 1 Print 2=3+11*345 Print 3ake Print bla bla bla Print 5 Print 6 Print 7 Echo after done
Передача списка для цикла из файла.
#!/bin/bash f="myfile" for i in $(cat $f) do echo "Print $i" done echo "Echo after done"
Файл с элементами цикла.
Пробел воспринимается как разделитель между элементами, кавычки не работают.
kostya@aee3:~/BT$ cat myfile q1 w2 e3 e3 "r4r4r4 t5t5t5" y6
Результат.
kostya@aee3:~/BT$ ./for.sh Print q1 Print w2 Print e3 Print e3 Print "r4r4r4 Print t5t5t5" Print y6 Echo after done
Цикл с перебором чисел.
#!/bin/bash for ((i = 1; i < 10; i++)) do echo "Print number $i" done echo "Echo after fi"
Результат.
kostya@aee3:~/BT$ ./for1.sh Print number 1 Print number 2 Print number 3 Print number 4 Print number 5 Print number 6 Print number 7 Print number 8 Print number 9 Echo after fi
Конструкция.
while выражение проверяющее условие do команда1 done
Команда1 будет выполняться пока выполняется условие.
Пример.
#!/bin/bash VAR1="0" # while [ $VAR1 -lt 5 ] do echo "VAR1=$VAR1" VAR1=$[$VAR1 + 1] done echo "Echo after done"
Результат.
kostya@blackpc:~/Dropbox/BT$ ./while.sh VAR1=0 VAR1=1 VAR1=2 VAR1=3 VAR1=4 Echo after done
Конструкция:
if команда1\условие then команда2 fi команда0
При этом команда2 сработает только если команда1 выполнилась успешно и без ошибок (в STDERR ничего не передавалось).
Пример.
#!/bin/bash if ping -c 1 -W 1 $1 2>&1 >/dev/null #В случае ошибки STDERR передать в STDOUT и потом все в нулл. then echo "$1 is reachable" fi echo "Echo after fi"
Если пинг успешен, то будет сообщение “$1 is reachable”.
Если нет, то будет выполняться команда идущая после “fi”.
kostya@aee3:~/BT$ ./ifthen-ping.sh 8.8.8.8 8.8.8.8 is reachable Echo after fi kostya@aee3:~/BT$ ./ifthen-ping.sh 8.8.8.1 Echo after fi
Конструкция:
if команда1\условие then команда2 else команда3 fi
Если команда1 выполнилась без ошибкой, то делаем команду2.
Если с ошибкой, то делаем команду3.
Пример.
#!/bin/bash if ifconfig | grep $1 then echo "I found my wifi interface!!" else echo "Where is my interface?" fi echo "Echo after fi"
В системе есть только интерфейс wlp3s0.
kostya@aee3:~/BT$ ./ifthe.sh wlp3s0 wlp3s0 Link encap:Ethernet HWaddr 74:e5:0b:6e:97:74 I found my wifi interface!! Echo after fi kostya@aee3:~/BT$ ./ifthe.sh wlp3s1 Where is my interface? Echo after fi
Конструкция:
if команда1\условие then команда2 elif команда3\условие then команда4 fi
Последовательно проверяем несколько условий и при первом совпадении делаем действие.
Пример.
Сравниваем текущее время в секундах (часы-минуты-секунды) с несколькими значениями и выводим одно из сообщений.
#!/bin/bash SIX_PM_IN_SEC=$((18 * 3600)) NINE_AM_IN_SEC=$((9 * 3600)) ## CHOUR=$(date +%H) CMIN=$(date +%M) CSEC=$(date +%S) ## CHOUR_IN_SEC=$(($CHOUR * 3600)) CMIN_IN_SEC=$(($CMIN * 60)) ## CTIME_IN_SEC=$((CHOUR_IN_SEC + CMIN_IN_SEC + CSEC)) ## if [ $CTIME_IN_SEC -le $NINE_AM_IN_SEC ] then echo "Why so early?" elif [[ $CTIME_IN_SEC -gt $NINE_AM_IN_SEC && $CTIME_IN_SEC -le $SIX_PM_IN_SEC ]] then echo "Keep calm and work" elif [ $CTIME_IN_SEC -gt $SIX_PM_IN_SEC ] then echo "Run Lola Run" fi
Передать результат команды в переменную можно двумя способалм:
Пример.
#!/bin/bash MYDATE=`date +%D` MYTIME="$(date +%T)" # Можно в кавычках, можно без. echo "MYDATE = $MYDATE and MYTIME = $MYTIME"
Результат.
kostya@aee3:~/BT$ ./cmd_to_var.sh MYDATE = 07/02/17 and MYTIME = 19:58:56
Честно подсмотрел у joemiller.
#!/bin/bash INTERVAL="1" # update interval in seconds if [ -z "$1" ]; then echo echo usage: $0 [network-interface] echo echo e.g. $0 eth0 echo echo shows packets-per-second exit fi IF=$1 while true do R1=`cat /sys/class/net/$1/statistics/rx_packets` T1=`cat /sys/class/net/$1/statistics/tx_packets` sleep $INTERVAL R2=`cat /sys/class/net/$1/statistics/rx_packets` T2=`cat /sys/class/net/$1/statistics/tx_packets` TXPPS=`expr $T2 - $T1` RXPPS=`expr $R2 - $R1` echo "TX $1: $TXPPS pkts/s RX $1: $RXPPS pkts/s" done
#!/bin/bash if [ -z "$1" ]; then echo echo usage: $0 network-interface echo echo e.g. $0 eth0 echo exit fi IF=$1 while true do R1=`cat /sys/class/net/$1/statistics/rx_bytes` T1=`cat /sys/class/net/$1/statistics/tx_bytes` sleep 1 R2=`cat /sys/class/net/$1/statistics/rx_bytes` T2=`cat /sys/class/net/$1/statistics/tx_bytes` TBPS=`expr $T2 - $T1` RBPS=`expr $R2 - $R1` TKBPS=`expr $TBPS / 1024` RKBPS=`expr $RBPS / 1024` echo "tx $1: $TKBPS kb/s rx $1: $RKBPS kb/s" done
#!/bin/bash ### SSHOPT="/usr/bin/ssh -c blowfish" ROPT="-v -az --delete" BASE_BUP_DIR="/backup" BASE_LOG_DIR="/root/bin/log" BUP_SRV="nas" SRV="san" LOG_FILE="$BASE_LOG_DIR/$SRV_bup_log" CDATE=$(date +%Y%m%d) CTIME=$(date +%H:%M) ### echo "$CDATE" > $LOG_FILE echo "Время начала бэкапа: $CTIME" >> $LOG_FILE echo "Бэкап $SRV с помощью rsync на $BUP_SRV." >> $LOG_FILE echo "===============" >> $LOG_FILE echo "===============" >> $LOG_FILE echo "Время начала выполнения задания 1: $CTIME" >> $LOG_FILE rsync $ROPT -e "$SSHOPT" root@san:/etc/ $BASE_BUP_DIR/san/etc | tee -a $LOG_FILE # echo "===============" >> $LOG_FILE echo "Время начала выполнения задания 2: $CTIME" >> $LOG_FILE rsync $ROPT -e "$SSHOPT" root@san:/root/ $BASE_BUP_DIR/san/root | tee -a $LOG_FILE # echo "===============" >> $LOG_FILE echo "===============" >> $LOG_FILE echo "Время окончания бэкапа: $CTIME" >> $LOG_FILE # mailx -s "Бэкап $SRV" noc@company.name < $LOG_FILE
#!/bin/bash #backup noc1 to noc1. CDATE=$(date +%Y%m%d) ROPT="-v -az --delete" #RSYNC rsync $ROPT /etc/ /backup/noc1/etc/ rsync $ROPT /root/ /backup/noc1/root/ rsync $ROPT /home/rancid/ /backup/noc1/rancid/ rsync $ROPT /var/www/ /backup/noc1/var_www/ rsync $ROPT /var/log/ /backup/noc1/var_log/ rsync $ROPT /usr/local/viewvc-1.1.26/ /backup/noc1/usr_local_viewvc-1.1.26/ #MYSQLDUMP mysqldump -u USERNAME -pPASSWORD viewvc_db > /backup/noc1/mysql/viewvc_db_$CDATE.sql
#!/bin/bash CDATE=$(date +%Y%m%d) BASE_BACKUP_DIR=/backup EXT_BACKUP_DIR=/backup/for_ext_bup #TAR tar -zcvf $EXT_BACKUP_DIR/voip1-$CDATE.tar.gz -C $BASE_BACKUP_DIR voip1 #FTP lftp -u USERNAME,PASSWORD some-ftps-server.ru:23322<<EOF-PUT set ftp:ssl-force true set ssl:verify-certificate no lcd $EXT_BACKUP_DIR cd some-dir-at-ftps-server put voip1-$CDATE.tar.gz exit EOF-PUT #DELETE OLD BACKUP FILES find /backup/for_ext_bup/voip1-*.tar.gz -mtime +30 -delete
#!/bin/bash # Задаем базовые и стартовые значения переменных. BASE_NFSEN_BACKUP_DATA_DIR=/root/test-nfdump/profiles-data/live BASE_TAR_DIR=/root/test-nfdump/tar ROUTER=START-ROUTER YEAR=START-YEAR MONTH=START-MONTH # Выводим имена директорий в виде списка которые будут использоваться в цикле архивирования всех месяцев (MONTH=ALL) LIST_ONLY_FOLDER_NAME () { find $BASE_NFSEN_BACKUP_DATA_DIR/$ROUTER/$YEAR -maxdepth 1 -mindepth 1 -type d -printf '%f\n' } # Формируем справку. SHOW_HELP () { echo "Скрипт $0 предназначен для архивирования netflow данных которые были скописрованы с сервера flow1." echo "Данные сворачиваются в архив вида nfcapd-ciso1-201702.tar.bz2." echo "Скрипту обзательно надо дать три ключа: \"-r\", \"-y\", \"-m\"." echo "Ключ \"-r\" задает роутер, данные которого будут архивироваться." echo "Ключ \"-y\" указывает на год за который надо будет брать данные." echo "Ключ \"-m\" указывает на месяц за который надо брать данне для добавления в архив." echo "Ключ \"-m\" может иметь два значния - конкретный номер месяца (01, 02 и так до 12) или ALL (будут перебираться все месяцы в выбранном годе)." echo "Пример: \"$0 -r cisco6 -y 2015 -m {03|ALL}\"." } # Проверям наличие аргументов у скрипта. if [ $# -eq "0" ]; # Количество переданных скрипту агрументов ($#) равно нулю (значение NO_ARGS)? then echo "!!!" echo "Ошибка: Скрипт запускается без ключей и аргументов." echo "!!!" SHOW_HELP # Если да, то показать справку exit # и выйти fi #Работа с ключами. while getopts "r:y:m:" option # Определяем ключи и говорим, что после ключа обязательно должен быть аргумент. do case $option in r) ROUTER=$OPTARG;; # Присваеваем переменной значение аргумента y) YEAR=$OPTARG;; m) MONTH=$OPTARG;; *) echo "Выбран недопустимый ключ." # Если введен ключ который мы ранее не определили, то выводим сообщение exit;; # и выходим esac done # Проверяем, что скрипту были переданы три ключа с аргументами. # Если значение переменной совпадает со стартовым значением, значит ключ не был задан. if [ "$ROUTER" = "START-ROUTER" ]; then echo "!!!" echo "Ошибка: Не задан ключ \"-r\"." echo "!!!" SHOW_HELP exit elif [ "$YEAR" = "START-YEAR" ]; then echo "!!!" echo "Ошибка: Не задан ключ \"-y\"." echo "!!!" SHOW_HELP exit elif [ "$MONTH" = "START-MONTH" ]; then echo "!!!" echo "Ошибка: Не задан ключ \"-m\"." echo "!!!" SHOW_HELP exit elif [ "$MONTH" = "ALL" ]; # Запускаем цикл если с ключем было передано ALL. # Будет создано столько архивов, сколько месячных папок выдаст команда LIST_ONLY_FOLDER_NAME. then for MONTH in `LIST_ONLY_FOLDER_NAME` do tar -cjvf $BASE_TAR_DIR/nfcapd-$ROUTER-$YEAR$MONTH.tar.bz2 -C $BASE_NFSEN_BACKUP_DATA_DIR $ROUTER/$YEAR/$MONTH done else # Если с ключем -m был передан конкретный номер месяца, то делаем один архив. tar -cjvf $BASE_TAR_DIR/nfcapd-$ROUTER-$YEAR$MONTH.tar.bz2 -C $BASE_NFSEN_BACKUP_DATA_DIR $ROUTER/$YEAR/$MONTH fi
Скрипт bash tar-backup-netflow-data-via-ssh.sh позволяет сразу скопировать архив на удаленный сервер по ssh.
Это полезно когда на локальном сервере мало место и некуда записать архив.
Перед запуском скрипта на 1.2.3.4 надо скопиловать ssh ключ3, что бы заходить под пользователем username без пароля.
#!/bin/bash # Задаем базовые и стартовые значения переменных. BASE_NFSEN_BACKUP_DATA_DIR=/data/nfsen_1_3_8_bup/profiles-data/live BASE_TAR_DIR=/backup/nfsen_bup ROUTER=START-ROUTER YEAR=START-YEAR MONTH=START-MONTH # Выводим имена директорий в виде списка которые будут использоваться в цикле архивирования всех месяцев (MONTH=ALL) LIST_ONLY_FOLDER_NAME () { find $BASE_NFSEN_BACKUP_DATA_DIR/$ROUTER/$YEAR -maxdepth 1 -mindepth 1 -type d -printf '%f\n' } # Формируем справку. SHOW_HELP () { echo "Скрипт $0 предназначен для архивирования netflow данных которые были скописрованы с сервера flow1." echo "Данные сворачиваются в архив вида nfcapd-ciso1-201702.tar.bz2." echo "Скрипту обзательно надо дать три ключа: \"-r\", \"-y\", \"-m\"." echo "Ключ \"-r\" задает роутер, данные которого будут архивироваться." echo "Ключ \"-y\" указывает на год за который надо будет брать данные." echo "Ключ \"-m\" указывает на месяц за который надо брать данне для добавления в архив." echo "Ключ \"-m\" может иметь два значния - конкретный номер месяца (01, 02 и так до 12) или ALL (будут перебираться все месяцы в выбранном годе)." echo "Пример: \"$0 -r cisco6 -y 2015 -m {03|ALL}\"." } # Проверям наличие аргументов у скрипта. if [ $# -eq "0" ]; # Количество переданных скрипту агрументов ($#) равно нулю (значение NO_ARGS)? then echo "!!!" echo "Ошибка: Скрипт запускается без ключей и аргументов." echo "!!!" SHOW_HELP # Если да, то показать справку exit # и выйти fi #Работа с ключами. while getopts "r:y:m:" option # Определяем ключи и говорим, что после ключа обязательно должен быть аргумент. do case $option in r) ROUTER=$OPTARG;; # Присваеваем переменной значение аргумента y) YEAR=$OPTARG;; m) MONTH=$OPTARG;; *) echo "Выбран недопустимый ключ." # Если введен ключ который мы ранее не определили, то выводим сообщение exit;; # и выходим esac done # Проверяем, что скрипту были переданы три ключа с аргументами. # Если значение переменной совпадает со стартовым значением, значит ключ не был задан. if [ "$ROUTER" = "START-ROUTER" ]; then echo "!!!" echo "Ошибка: Не задан ключ \"-r\"." echo "!!!" SHOW_HELP exit elif [ "$YEAR" = "START-YEAR" ]; then echo "!!!" echo "Ошибка: Не задан ключ \"-y\"." echo "!!!" SHOW_HELP exit elif [ "$MONTH" = "START-MONTH" ]; then echo "!!!" echo "Ошибка: Не задан ключ \"-m\"." echo "!!!" SHOW_HELP exit elif [ "$MONTH" = "ALL" ]; # Запускаем цикл если с ключем было передано ALL. # Будет создано столько архивов, сколько месячных папок выдаст команда LIST_ONLY_FOLDER_NAME. then for MONTH in `LIST_ONLY_FOLDER_NAME` do tar -cjvf - -C $BASE_NFSEN_BACKUP_DATA_DIR $ROUTER/$YEAR/$MONTH | ssh root@1.2.3.4 "cat > $BASE_TAR_DIR/nfcapd-$ROUTER-$YEAR$MONTH.tar.bz2" done else # Если с ключем -m был передан конкретный номер месяца, то делаем один архив. tar -cjvf - -C $BASE_NFSEN_BACKUP_DATA_DIR $ROUTER/$YEAR/$MONTH | ssh username@1.2.3.4 "cat > $BASE_TAR_DIR/nfcapd-$ROUTER-$YEAR$MONTH.tar.bz2" fi
#!/bin/bash for n in 'seq $2' do dd if=/dev/urandom of=$1 bs=8b conv=notrunc done
Пример - затираем раздел /dev/sdb1 ($1) одним проходом ($2).
В случае паранойи количество проходом ставим 7.
[root@aee2 bin]# ./clear-some-important-data.sh /dev/sdb1 1 dd: error writing '/dev/sdb1': No space left on device 977661+0 records in 977660+0 records out 4004495360 bytes (4.0 GB, 3.7 GiB) copied, 409.491 s, 9.8 MB/s
#!/bin/sh #### Exim Stats #### log_file="/root/exim_stats_log" date_minus_1day="$(date --date "-1 days" +'%d.%m.%Y')" serv_name="$(hostname)" serv_name_short="$(hostname -s)" # echo "=" > ${log_file} echo "= ${serv_name_short} exim stats. " >> ${log_file} echo "=" >> ${log_file} /usr/sbin/eximstats `ls -t /var/log/exim/main.log* | head -n2 | tail -n1`| tee -a ${log_file} # mailx -r root@${serv_name} -s "Exim stats for ${date_minus_1day} from ${serv_name_short}" a@b.com < ${log_file}
#!/bin/bash find /var/log/nginx/ -maxdepth 0 -type f -mtime +2 -exec mv '{}' /var/log/nginx/1_archive_nginx_logs/ \; find /var/log/nginx/1_archive_nginx_logs/ -type f -mtime +60 -delete
#!/bin/bash mv /var/www/html/dump/dump.xml /var/www/html/dump/dump.xml.$(date +"%Y%m%d-%H%M") cp /home/rkn/dump.xml /var/www/html/dump/dump.xml
#!/bin/bash branch_dir=(offce1 office2) for i in ${branch_dir[@]}; do mv /var/log/somelog/$i/*.gz /var/log/somelog/1archive-$i/ find /var/log/somelog/1archive-$i/ -type f -mtime +60 -delete
#!/bin/sh url=$1 host $url | head -n 1 host www.$url | head -n 1
Версия для Cenots6
#!/bin/bash log_file="/var/log/obkt/mtr/mtr_xxx_$1.log" echo "#####################" >> $log_file echo -e "Start time: $(date +"%Y%m%d - %H:%M:%S")" >> $log_file echo -e "Test address: $1\n" >> $log_file mtr -o LSR -4 -r -n -c $2 $1 >> $log_file echo -e "\nStop time: $(date +"%Y%m%d - %H:%M:%S")" >> $log_file echo -e "#####################\n" >> $log_file
Результат работы:
##################### Start time: 20220810 - 00:41:09 Test address: 77.233.186.43 HOST: xxx.xxx.pro Loss% Snt Rcv Avg Best Wrst StDev 1. 172.20.1.2 83.3% 300 50 0.2 0.1 0.5 0.1 2. ??? 100.0 300 0 0.0 0.0 0.0 0.0 3. 87.245.233.89 0.0% 300 300 10.1 1.1 51.5 9.1 4. 87.245.229.187 0.0% 300 300 2.4 2.2 2.9 0.2 5. ??? 100.0 300 0 0.0 0.0 0.0 0.0 6. 188.170.165.123 0.0% 300 300 31.9 31.7 34.4 0.2 7. 86.109.222.224 0.0% 300 300 31.3 30.7 138.0 6.7 8. 77.233.186.43 0.0% 300 300 40.5 37.3 46.7 1.6 Stop time: 20220810 - 00:46:09 #####################
Версия для Cenots7/Debian11/Ubuntu
#!/bin/bash log_file="/var/log/obkt/mtr/mtr_noc19_$1.log" echo "#####################" >> $log_file echo -e "Start time: $(date +"%Y%m%d - %H:%M:%S")" >> $log_file echo -e "Test address: $1\n" >> $log_file mtr -z -o LSR -b -w -c $2 $1 >> $log_file echo -e "\nStop time: $(date +"%Y%m%d - %H:%M:%S")" >> $log_file echo -e "#####################\n" >> $log_file
Результат работы:
##################### Start time: 20220810 - 03:51:17 Test address: 109.73.46.180 Start: Wed Aug 10 03:51:17 2022 HOST: noc19 Loss% Snt Rcv Avg Best Wrst StDev 1. AS49505 84.38.180.253 0.0% 300 300 7.5 0.4 135.8 13.8 2. AS49505 92.53.93.89 0.0% 300 300 7.5 1.0 159.9 15.1 3. AS29076 ae0-3002.rt2.spb.cloud-ix.net (31.28.18.102) 0.0% 300 300 6.4 0.9 149.5 14.5 4. AS??? ??? 100.0 300 0 0.0 0.0 0.0 0.0 5. AS29076 mastertel.msk.cloud-ix.net (31.28.19.122) 0.0% 300 300 15.4 9.9 168.5 16.2 6. AS29226 217-67-176-250.in-addr.mastertelecom.ru (217.67.176.250) 0.0% 300 300 33.4 11.6 446.6 40.8 7. AS29226 109-73-46-177.in-addr.mastertelecom.ru (109.73.46.177) 0.0% 300 300 20.7 12.2 174.5 19.2 8. AS29226 mail.frecom.ru (109.73.46.180) 0.0% 300 300 16.4 11.6 169.2 12.4 Stop time: 20220810 - 03:56:27 #####################