Bourne shell (/bin/sh) присутствует во всех Unix системах, соответственно скрипты, написанные на этом языке, будут работать на любой Unix-машине. Для прочтения: man 1 sh. Незаменимая вещь при настройке и обслуживании сервера.
Основые понятия о shell скриптах
Переменные и аргументы командной строки
Присваивание значений переменным производится следующим образом: variable=value, получить присвоенное значение можно по ссылке $variable.
MESSAGE="Hello World" # Присвоить переменной строку "Hello World" PI=3.1415 # Присвоить цифровое значение N=8 TWON=`expr $N * 2` # Присвоить арифметическое выражение (только целые числа) TWON=$(($N * 2)) # Другой вариант TWOPI=`echo "$PI * 2" | bc -l` # Использование bc для операций с плавающей точкой 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#*.} # Взять только расширение prince $file -o $fname.pdf pdftops -paper A4 -noshrink $fname.pdf $fname.ps # Создать postscript буклет cat $fname.ps |psbook|psnup -Pa4 -2 |pstops -b "2:0,1U(21cm,29.7cm)" > $fname.book.ps ps2pdf13 -sPAPERSIZE=a4 -sAutoRotatePages=None $fname.book.ps $fname.book.pdf # В Windows используйте #a4 и #None ! exit 0 # Выход с кодом успешного завершения
awk
Awk — это весьма мощьный и полезный язык для обработки текстовой информации. Кучу примеров, без труда можно найти в сети, здесь приведены лишь несколько простых:
awk '{ print $2, $1 }' file # Вывести из файла 2 колонки, поменя из местами awk '{printf("%5d : %s\n", NR,$0)}' file # Форматирование вывода с номерами строк awk '{print FNR "\t" $0}' files # Несколько измененный вариант awk NF test.txt # Удалить из вывода пустые строки (аналогично grep '.') awk 'length > 80' # Напечатать строки, длинной более 80 символов
sed
Sed — это неинтерактивный строчный редактор, принимает текст с устройства stdin или из текстового файла, выполняет некоторые со строками и выводит в stdout или в файл. Часто применяется в конвейерной обработке данных совместно с другими командами.
sed 's/string1/string2/g' # Заменить string1 на string2 cat ./wrong.txt | sed 's/wrong/right/g' > ./right.txt # Вывести содержимое файла, заменить слова и записать в другой файл sed 's/\(.*\)1/\12/g' # Модифицировать "строку1" в "строку2" sed '//,/< \/p>/d' t.xhtml # Удалить строки, начинающиеся с p> # И заканчивающиеся sed '/ *#/d; /^ *$/d' # Удалить комментарии и пустые строки sed 's/[ \t]*$//' # Удалить символы табуляции sed 's/^[ \t]*//;s/[ \t]*$//' # Удалить пробелы в начале и конце sed 's/[^*]/[&]/' # Заключить первый символ в квадратные скобки sed = file | sed 'N;s/\n/\t/' # Порядковый номер в каждой строке
regex — регулярные выражения
[\^$.|?*+() # Специальные символы, остальные символы означают самих себя \ # Экранирует специальные символы * # Повтор 0 или 1 раз . # Любой символ, за исключением символа новой строки .* # Совпадает 0 или более символов ^ # Начало строки $ # Конец строки .$ # Совпадает с одним любым символ в конце строки ^ $ # Совпадает со строкой, состоящей из одного пробела [^A-Z] # Любые символы, не входящие в диапазон от А до Z
Некоторые полезные команды
Следующие команды могут пригодиться для использования как в скриптах, так и просто из командной строки:
sort -t. -k1,1n -k2,2n -k3,3n -k4,4n # Отсортировать IPv4 ip адреса echo 'Test' | tr '[:lower:]' '[:upper:]' # Смена регистра символов echo foo.bar | cut -d . -f 1 # Вернет foo PID=$(ps | grep script.sh | grep bin | awk '{print $1}') # PID запущенного скрипта PID=$(ps axww | grep [p]ing | awk '{print $1}') # PID процесса ping IP=$(ifconfig $INTERFACE | sed '/.*inet addr:/!d;s///;s/ .*//') # Linux IP=$(ifconfig $INTERFACE | sed '/.*inet /!d;s///;s/ .*//') # FreeBSD if [ `diff file1 file2 | wc -l` != 0 ]; then [...] fi # Файл изменен? cat /etc/master.passwd | grep -v root | grep -v \*: | awk -F":" \ # Создание файла паролей http passwd '{ printf("%s:%s\n", $1, $2) }' > /usr/local/etc/apache2/passwd testuser=$(cat /usr/local/etc/apache2/passwd | grep -v \ # Проверить пользователя в passwd root | grep -v \*: | awk -F":" '{ printf("%s\n", $1) }' | grep ^user$) :(){ :|:& };: # bash fork bomb :). Убьет вашу машину )) tail +2 file > file2 # Удалить первую строку из файла
Я использую этот небольшой трюк, что-бы разом изменить расширение для кучи файлов, например с *.cxx на *.cpp. (советую для начала протемтировать данный пример, без | sh в конце строки.
Тоже самое можно смделать с помощью команды rename, если она присутствует, или с помошью встроенных средст оболочки.
# ls *.cxx | awk -F. '{print "mv "$0" "$1".cpp"}' | sh # ls *.c | sed "s/.*/cp & &.$(date "+%Y%m%d")/" | sh # Копировать файлы *.c в *.c.20080401 # rename .cxx .cpp *.cxx # Переименовать все файлы .cxx в cpp # for i in *.cxx; do mv $i ${i%%.cxx}.cpp; done # Встроенными средствами
По материалам: vds-admin.ru
если нужно удалить все \n, то проще использовать
tr -d ‘\n’ < 1.txt если с условиями или именно sed'ом, то читать сюда .grymoire.com/Unix/Sed.html#uh-51