2015-05-15

Скрипты /bin/sh

Основы
Переменные и аргументы

Присваивание значений переменным производится следующим образом: variable=value, получить присвоенное значение можно по ссылке $variable.

# Присвоить переменной строку "Hello"
MESSAGE="Hello"    
# Присвоить цифровое значение
PI=3.1415
N=8# Присвоить выражение (только целые числа)
TWON=`expr $N * 2`
# Другой вариант
TWON=$(($N * 2))
# Использование bc для операций с плавающей точкой
TWOPI=`echo "$PI * 2" | bc -l`
ZERO=`echo "c($PI/4)-sqrt(2)/2" | bc -l`

Аргументы командной строки:

$0, $1, $2, ...   # $0 - сама команда(название скрипта)
$#                # Кол-во аргументов
$*                # Все аргументы (аналог $@)


Специальные переменные

$$                # ID текущего процесса
$?                # Код возврата последней выполненной команды
  command
  if [ $? != 0 ]; then
    echo "command failed"
  fi
mypath=`pwd`
mypath=${mypath}/file.txt
echo ${mypath##*/}     # Вывести только имя файла
echo ${mypath%%.*}     # Полный путь без расширения
var2=${var:=string}    # Если var назначена, использовать ее значение, иначе string
                       # значение string будет присвоено и var и var2.


Конструкции

for file in `ls`
do
    echo $file
done

count=0
while [ $count -lt 5 ]; do
    echo $count
    sleep 1
    count=$(($count + 1))
done

myfunction() {
    find . -type f -name "*.$1" -print       # $1 -первый аргумент функции
}
myfunction "txt"


Генерируем файл

MYHOME=/home/colin
cat > testhome.sh << _EOF
# Все до символа _EOF, записывается в файл testhome.sh
if [ -d "$MYHOME" ] ; then
    echo $MYHOME exists
else
    echo $MYHOME does not exist
fi
_EOF
sh testhome.sh

Пример: скрипт на bourne shell

Скрипт, создает PDF буклет, из XHTML документа:

#!/bin/sh
# Данный скрипт создает книгу в формате PDF, для печати на принтере
if [ $# -ne 1 ]; then  # Проверить аргумент
  echo 1>&2 "Usage: $0 HtmlFile"
  exit 1               # Выход с кодом больше нуля в случае ошибки
fi

file=$1                # Присвоить имя файла из агрумента
fname=${file%.*}       # Взять только имя файла
fext=${file#*.}        # Взять только расширение
# С www.princexml.com
prince $file -o $fname.pdf # Создать postscript буклет
pdftops -paper A4 -noshrink $fname.pdf $fname.ps
cat $fname.ps |psbook|psnup -Pa4 -2 |pstops -b "2:0,1U(21cm,29.7cm)" > $fname.book.ps# В Windows используйте #a4 и #None !
ps2pdf13 -sPAPERSIZE=a4 -sAutoRotatePages=None $fname.book.ps $fname.book.pdf
exit 0                 # Выход с кодом успешного завершения

awk

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

# Вывести из файла 2 колонки, поменя из местами
awk '{ print $2, $1 }' file

# Форматирование вывода с номерами строк
awk '{printf("%5d : %s\n", NR,$0)}' file

# Несколько измененный вариант
awk '{print FNR "\t" $0}' files

# Удалить из вывода пустые строки (аналогично grep '.')
awk NF test.txt

# Напечатать строки, длинной более 80 символов
awk 'length > 80'

sed

Sed - это неинтерактивный строчный редактор, принимает текст с устройства stdin или из текстового файла, выполняет некоторые со строками и выводит в stdout или в файл. Часто применяется в конвейерной обработке данных совместно с другими командами.

# Заменить string1 на string2
sed 's/string1/string2/g'

# Вывести содержимое файла, заменить слова и записать в другой файл
cat ./wrong.txt | sed 's/wrong/right/g' > ./right.txt

# Модифицировать "строку1" в "строку2"
sed 's/\(.*\)1/\12/g'

# Удалить строки, начинающиеся с <p>
# И заканчивающиеся </p>
sed '/<p>/,/<\/p>/d' t.xhtml

# Удалить комментарии и пустые строки
sed '/ *#/d; /^ *$/d'

# Удалить символы табуляции
sed 's/[ \t]*$//'

# Удалить пробелы в начале и конце
sed 's/^[ \t]*//;s/[ \t]*$//'

# Заключить первый символ в квадратные скобки
sed 's/[^*]/[&]/'

# Порядковый номер в каждой строке
sed = file | sed 'N;s/\n/\t/'

regex - регулярные выражения

Регулярные выражения могут очень пригодится и в работе с sed.

[\^$.|?*+()         # Специальные символы, остальные символы означают самих себя
\                   # Экранирует специальные символы
*                   # Повтор 0 или 1 раз
.                   # Любой символ, за исключением символа новой строки
.*                  # Совпадает 0 или более символов
^                   # Начало строки
$                   # Конец строки
.$                  # Совпадает с одним любым символ в конце строки
^ $                 # Совпадает со строкой, состоящей из одного пробела
[^A-Z]              # Любые символы, не входящие в диапазон от А до Z

Некоторые полезные команды

Следующие команды могут пригодиться для использования как в скриптах, так и просто из командной строки:

# Отсортировать IPv4 ip адреса
sort -t. -k1,1n -k2,2n -k3,3n -k4,4n

# Смена регистра символов
echo 'Test' | tr '[:lower:]' '[:upper:]'

# Вернет foo
echo foo.bar | cut -d . -f 1

# PID запущенного скрипта
PID=$(ps | grep script.sh | grep bin | awk '{print $1}')

# PID процесса ping
PID=$(ps axww | grep [p]ing | awk '{print $1}')

# Linux
IP=$(ifconfig $INTERFACE | sed '/.*inet addr:/!d;s///;s/ .*//')

# FreeBSD
IP=$(ifconfig $INTERFACE | sed '/.*inet /!d;s///;s/ .*//')

# Файл изменен?
if [ `diff file1 file2 | wc -l` != 0 ]; then [...] fi

# Проверить пользователя в passwd
testuser=$(cat /usr/local/etc/apache2/passwd | grep -v \

# bash fork bomb :). Убьет вашу машину ))
root | grep -v \*: | awk -F":" '{ printf("%s\n", $1) }' | grep ^user$)
:(){ :|:& };:



# Удалить первую строку из файла
tail +2 file > file2

Небольшой трюк, что-бы разом изменить расширение для кучи файлов, например с *.cxx на *.cpp.
ls *.cxx | awk -F. '{print "mv "$0" "$1".cpp"}' | sh 
# Копировать файлы *.c в *.c.20080401
ls *.c | sed "s/.*/cp & &.$(date "+%Y%m%d")/" | sh

# Переименовать все файлы .cxx в cpp
rename .cxx .cpp *.cxx

# Встроенными средствами
for i in *.cxx; do mv $i ${i%%.cxx}.cpp; done



Где взял всё это точно не упомню но если хозяин найдётся и сообщит то линк на его пост поставлю ;-)

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

Отправить комментарий