Мендель Купер - Искусство программирования на языке сценариев командной оболочки
- Название:Искусство программирования на языке сценариев командной оболочки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Мендель Купер - Искусство программирования на языке сценариев командной оболочки краткое содержание
Данное руководство не предполагает наличие у читателя познаний в области программирования на языке сценариев, однако, быстро восполняет этот недостаток, постепенно, шаг за шагом раскрывая мудрость и красоту UNIX. Это руководство может рассматриваться как учебник, предназначенный для самостоятельного изучения или как справочник по программированию на shell. Руководство снабжено серией хорошо прокомментированных примеров, поскольку лучший путь к изучению языка сценариев -- это написание сценариев.
Искусство программирования на языке сценариев командной оболочки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
echo ${#result}
}
#:docstring strcspn:
# Порядок использования: strcspn $s1 $s2
#
# Strcspn возвращает максимальную длину сегмента в строке s1,
# который полностью не содержит символы из строки s2.
#:end docstring:
###;;;autoload
function strcspn ()
{
# Сброс содержимого переменной IFS позволяет обрабатывать пробелы как обычные символы.
local IFS=
local result="${1%%[${2}]*}"
echo ${#result}
}
#:docstring strstr:
# Порядок использования: strstr s1 s2
#
# Strstr выводит подстроку первого вхождения строки s2
# в строке s1, или ничего не выводит, если подстрока s2 в строке s1 не найдена.
# Если s2 содержит строку нулевой длины, то strstr выводит строку s1.
#:end docstring:
###;;;autoload
function strstr ()
{
# Если s2 -- строка нулевой длины, то вывести строку s1
[ ${#2} -eq 0 ] && { echo "$1" ; return 0; }
# не выводить ничего, если s2 не найдена в s1
case "$1" in
*$2*) ;;
*) return 1;;
esac
# использовать шаблон, для удаления всех несоответствий после s2 в s1
first=${1/$2*/}
# Затем удалить все несоответствия с начала строки
echo "${1##$first}"
}
#:docstring strtok:
# Порядок использования: strtok s1 s2
#
# Strtok рассматривает строку s1, как последовательность из 0, или более,
# лексем (токенов), разделенных символами строки s2
# При первом вызове (с непустым аргументом s1)
# выводит первую лексему на stdout.
# Функция запоминает свое положение в строке s1 от вызова к вызову,
# так что последующие вызовы должны производиться с пустым первым аргументом,
# чтобы продолжить выделение лексем из строки s1.
# После вывода последней лексемы, все последующие вызовы будут выводить на stdout
# пустое значение. Строка-разделитель может изменяться от вызова к вызову.
#:end docstring:
###;;;autoload
function strtok ()
{
:
}
#:docstring strtrunc:
# Порядок использования: strtrunc $n $s1 {$s2} {$...}
#
# Используется многими функциями, такими как strncmp, чтобы отсечь "лишние" символы.
# Выводит первые n символов в каждой из строк s1 s2 ... на stdout.
#:end docstring:
###;;;autoload
function strtrunc ()
{
n=$1 ; shift
for z; do
echo "${z:0:$n}"
done
}
# provide string
# string.bash конец библиотеки
# ========================================================================== #
# ==> Все, что находится ниже, добавлено автором документа.
# ==> Чтобы этот сценарий можно было использовать как "библиотеку", необходимо
# ==> удалить все, что находится ниже и "source" этот файл в вашем сценарии.
# strcat
string0=one
string1=two
echo
echo "Проверка функции \"strcat\" :"
echo "Изначально \"string0\" = $string0"
echo "\"string1\" = $string1"
strcat string0 string1
echo "Теперь \"string0\" = $string0"
echo
# strlen
echo
echo "Проверка функции \"strlen\" :"
str=123456789
echo "\"str\" = $str"
echo -n "Длина строки \"str\" = "
strlen str
echo
# Упражнение:
# ---------
# Добавьте проверку остальных функций.
exit 0
Michael Zick предоставил очень сложный пример работы с массивами и утилитой md5sum, используемой для кодирования сведений о каталоге.
От переводчика:
К своему стыду вынужден признаться, что перевод комментариев оказался мне не "по зубам", поэтому оставляю этот сценарий без перевода.
Пример A-21. Directory information
#! /bin/bash
# directory-info.sh
# Parses and lists directory information.
# NOTE: Change lines 273 and 353 per "README" file.
# Michael Zick is the author of this script.
# Used here with his permission.
# Controls
# If overridden by command arguments, they must be in the order:
# Arg1: "Descriptor Directory"
# Arg2: "Exclude Paths"
# Arg3: "Exclude Directories"
#
# Environment Settings override Defaults.
# Command arguments override Environment Settings.
# Default location for content addressed file descriptors.
MD5UCFS=${1:-${MD5UCFS:-'/tmpfs/ucfs'}}
# Directory paths never to list or enter
declare -a \
EXCLUDE_PATHS=${2:-${EXCLUDE_PATHS:-'(/proc /dev /devfs /tmpfs)'}}
# Directories never to list or enter
declare -a \
EXCLUDE_DIRS=${3:-${EXCLUDE_DIRS:-'(ucfs lost+found tmp wtmp)'}}
# Files never to list or enter
declare -a \
EXCLUDE_FILES=${3:-${EXCLUDE_FILES:-'(core "Name with Spaces")'}}
# Here document used as a comment block.
: << LSfieldsDoc
# # # # # List Filesystem Directory Information # # # # #
#
# ListDirectory "FileGlob" "Field-Array-Name"
# or
# ListDirectory -of "FileGlob" "Field-Array-Filename"
# '-of' meaning 'output to filename'
# # # # #
String format description based on: ls (GNU fileutils) version 4.0.36
Produces a line (or more) formatted:
inode permissions hard-links owner group ...
32736 -rw------- 1 mszick mszick
size day month date hh:mm:ss year path
2756608 Sun Apr 20 08:53:06 2003 /home/mszick/core
Unless it is formatted:
inode permissions hard-links owner group ...
266705 crw-rw---- 1 root uucp
major minor day month date hh:mm:ss year path
4, 68 Sun Apr 20 09:27:33 2003 /dev/ttyS4
NOTE: that pesky comma after the major number
NOTE: the 'path' may be multiple fields:
/home/mszick/core
/proc/982/fd/0 -> /dev/null
/proc/982/fd/1 -> /home/mszick/.xsession-errors
/proc/982/fd/13 -> /tmp/tmpfZVVOCs (deleted)
/proc/982/fd/7 -> /tmp/kde-mszick/ksycoca
/proc/982/fd/8 -> socket:[11586]
/proc/982/fd/9 -> pipe:[11588]
If that isn't enough to keep your parser guessing,
either or both of the path components may be relative:
../Built-Shared -> Built-Static
../linux-2.4.20.tar.bz2 -> ../../../SRCS/linux-2.4.20.tar.bz2
The first character of the 11 (10?) character permissions field:
's' Socket
'd' Directory
'b' Block device
'c' Character device
'l' Symbolic link
NOTE: Hard links not marked - test for identical inode numbers
on identical filesystems.
All information about hard linked files are shared, except
for the names and the name's location in the directory system.
NOTE: A "Hard link" is known as a "File Alias" on some systems.
'-' An undistingushed file
Followed by three groups of letters for: User, Group, Others
Character 1: '-' Not readable; 'r' Readable
Character 2: '-' Not writable; 'w' Writable
Character 3, User and Group: Combined execute and special
'-' Not Executable, Not Special
'x' Executable, Not Special
's' Executable, Special
'S' Not Executable, Special
Character 3, Others: Combined execute and sticky (tacky?)
'-' Not Executable, Not Tacky
'x' Executable, Not Tacky
't' Executable, Tacky
'T' Not Executable, Tacky
Followed by an access indicator
Haven't tested this one, it may be the eleventh character
or it may generate another field
' ' No alternate access
'+' Alternate access
LSfieldsDoc
ListDirectory()
{
local -a T
local -i of=0 # Default return in variable
# OLD_IFS=$IFS # Using BASH default ' \t\n'
case "$#" in
3) case "$1" in
-of) of=1 ; shift ;;
* ) return 1 ;;
esac ;;
2) : ;; # Poor man's "continue"
*) return 1 ;;
esac
# NOTE: the (ls) command is NOT quoted (")
T=( $(ls --inode --ignore-backups --almost-all --directory \
--full-time --color=none --time=status --sort=none \
--format=long $1) )
case $of in
# Assign T back to the array whose name was passed as $2
0) eval $2=\( \"\$\{T\[@\]\}\" \) ;;
# Write T into filename passed as $2
1) echo "${T[@]}" > "$2" ;;
esac
return 0
}
# # # # # Is that string a legal number? # # # # #
#
# IsNumber "Var"
# # # # # There has to be a better way, sigh...
IsNumber()
{
local -i int
if [ $# -eq 0 ]
then
return 1
else
(let int=$1) 2>/dev/null
return $? # Exit status of the let thread
fi
}
# # # # # Index Filesystem Directory Information # # # # #
#
# IndexList "Field-Array-Name" "Index-Array-Name"
# or
# IndexList -if Field-Array-Filename Index-Array-Name
# IndexList -of Field-Array-Name Index-Array-Filename
# IndexList -if -of Field-Array-Filename Index-Array-Filename
# # # # #
: << IndexListDoc
Walk an array of directory fields produced by ListDirectory
Having suppressed the line breaks in an otherwise line oriented
report, build an index to the array element which starts each line.
Each line gets two index entries, the first element of each line
(inode) and the element that holds the pathname of the file.
The first index entry pair (Line-Number==0) are informational:
Index-Array-Name[0] : Number of "Lines" indexed
Index-Array-Name[1] : "Current Line" pointer into Index-Array-Name
The following index pairs (if any) hold element indexes into
the Field-Array-Name per:
Index-Array-Name[Line-Number * 2] : The "inode" field element.
NOTE: This distance may be either +11 or +12 elements.
Index-Array-Name[(Line-Number * 2) + 1] : The "pathname" element.
NOTE: This distance may be a variable number of elements.
Next line index pair for Line-Number+1.
IndexListDoc
IndexList()
{
local -a LIST # Local of listname passed
local -a -i INDEX=( 0 0 ) # Local of index to return
local -i Lidx Lcnt
local -i if=0 of=0 # Default to variable names
case "$#" in # Simplistic option testing
0) return 1 ;;
1) return 1 ;;
2) : ;; # Poor man's continue
3) case "$1" in
Читать дальшеИнтервал:
Закладка: