33.7. Разные советы

33.7. Разные советы

Для ведения учета использования сценария пользователями, добавьте следующие строки в сценарий. Они запишут в файл отчета название сценария и время запуска.

# Добавление (>>) учетной записи, об использовании сценария, в файл отчета.

date>> $SAVE_FILE # Дата и время.

echo $0>> $SAVE_FILE # Название сценария.

echo>> $SAVE_FILE # Пустая строка -- как разделитель записей.

# Не забудьте определить переменную окружения SAVE_FILE в ~/.bashrc

# (что нибудь, типа: ~/.scripts-run)

Оператор >> производит добавление строки в конец файла. А как быть, если надо добавить строку в начало существующего файла?

file=data.txt

title="***Это титульная строка в текстовом файле***"

echo $title | cat - $file >$file.new

# "cat -" объединяет stdout с содержимым $file.

# В результате получится

#+ новый файл $file.new, в начало которого добавлена строка $title.

Само собой разумеется, то же самое можно сделать с помощью sed.

Сценарий командной оболочки может использоваться как команда внутри другого сценария командной оболочки, Tcl, или wish сценария или, даже в Makefile. Он может быть вызван как внешняя команда из программы на языке C, с помощью функции system(), т.е. system("script_name");.

Собирайте свои библиотеки часто используемых функций и определений. Эти "библиотеки" могут быть "подключены" к сценариям, с помощью команды точка (.) или source.

# Сценарий-библиотека

# ------ -------

# Обратите внимание:

# Здесь нет sha-bang ("#!").

# И нет "живого кода".

# Определения переменных

ROOT_UID=0 # UID root-а, 0.

E_NOTROOT=101 # Ошибка -- "обычный пользователь".

MAXRETVAL=255 # Максимальное значение, которое могут возвращать функции.

SUCCESS=0

FAILURE=-1

# Функции

Usage () # Сообщение "Порядок использования:".

{

if [ -z "$1" ] # Нет аргументов.

then

msg=filename

else

msg=$@

fi

echo "Порядок использования: `basename $0` "$msg""

}

Check_if_root () # Проверка прав пользователя.

{ # из примера "ex39.sh".

if [ "$UID" -ne "$ROOT_UID" ]

then

echo "Этот сценарий должен запускаться с привилегиями root."

exit $E_NOTROOT

fi

}

CreateTempfileName () # Создание "уникального" имени для временного файла.

{ # Из примера "ex51.sh".

prefix=temp

suffix=`eval date +%s`

Tempfilename=$prefix.$suffix

}

isalpha2 () # Проверка, состоит ли строка только из алфавитных символов.

{ # Из примера "isalpha.sh".

[ $# -eq 1 ] || return $FAILURE

case $1 in

*[!a-zA-Z]*|"") return $FAILURE;;

*) return $SUCCESS;;

esac # Спасибо S.C.

}

abs () # Абсолютное значение.

{ # Внимание: Максимально возможное возвращаеиое значение

# не может превышать 255.

E_ARGERR=-999999

if [ -z "$1" ] # Проверка наличия входного аргумента.

then

return $E_ARGERR # Код ошибки, обычно возвращаемый в таких случаях.

fi

if [ "$1" -ge 0 ] # Если не отрицательное,

then #

absval=$1 # оставить как есть.

else # Иначе,

let "absval = (( 0 - $1 ))" # изменить знак.

fi

return $absval

}

tolower () # Преобразование строк символов в нижний регистр

{

if [ -z "$1" ] # Если нет входного аргумента,

then #+ выдать сообщение об ошибке

echo "(null)"

return #+ и выйти из функции.

fi

echo "$@" | tr A-Z a-z

# Преобразовать все входные аргументы ($@).

return

# Для записи результата работы функции в переменную, используйте операцию подстановки команды.

# Например:

# oldvar="A seT of miXed-caSe LEtTerS"

# newvar=`tolower "$oldvar"`

# echo "$newvar" # a set of mixed-case letters

#

# Упражнение: Добавьте в эту библиотеку функцию перевода символов в верхний регистр.

# toupper() [это довольно просто].

}

Для повышения ясности комментариев, выделяйте их особым образом.

## Внимание!

rm -rf *.zzy ## Комбинация ключей "-rf", в команде "rm", чрезвычайно опасна,

##+ особенно при удалении по шаблону.

#+ Продолжение комментария на новой строке.

# Это первая строка комментария

#+ это вторая строка комментария,

#+ это последняя строка комментария.

#* Обратите внимание.

#o Элемент списка.

#> Альтернативный вариант.

while [ "$var1" != "end" ] #> while test "$var1" != "end"

Для создания блочных комментариев, можно использовать конструкцию if-test.

#!/bin/bash

COMMENT_BLOCK=

# Если попробовать инициализировать эту переменную чем нибудь,

#+ то вы получите неожиданный результат.

if [ $COMMENT_BLOCK ]; then

Блок комментария --

=================================

Это строка комментария.

Это другая строка комментария.

Это еще одна строка комментария.

=================================

echo "Эта строка не выводится."

Этот блок комментария не вызывает сообщения об ошибке! Круто!

fi

echo "Эта строка будет выведена на stdout."

exit 0

Сравните этот вариант создания блочных комментариев со встроенным документом, использующимся для создания блочных комментариев.

С помощью служебной переменной $?, можно проверить -- является ли входной аргумент целым числом.

#!/bin/bash

SUCCESS=0

E_BADINPUT=65

test "$1" -ne 0 -o "$1" -eq 0 2>/dev/null

# Проверка: "равно нулю или не равно нулю".

# 2>/dev/null подавление вывода сообщений об ошибках.

if [ $? -ne "$SUCCESS" ]

then

echo "Порядок использования: `basename $0` целое_число"

exit $E_BADINPUT

fi

let "sum = $1 + 25" # Будет выдавать ошибку, если $1 не является целым числом.

echo "Sum = $sum"

# Любая переменная может быть проверена таким образом, а не только входные аргументы.

exit 0

Диапазон, возвращаемых функциями значений, 0 - 255 -- серьезное ограничение. Иногда может оказаться весьма проблематичным использование глобальных переменных, для передачи результата из функции. В таких случаях можно порекомендовать передачу результатов работы функции через запись в stdout.