Если вам нужен легко переносимый способ удаления завершающей новой строки, для избавления от нее можно воспользоваться внешней командой
tr
, но она будет выполняться немного медленнее. Если вашим системам UNIX нужна переносимость и нужно избавиться от завершающей новой строки, как правило, лучше придерживаться команды
printf
. Если ваши сценарии предназначены для работы только в ОС Linux и bash, вполне подойдет
echo -n
, хотя, возможно, придется начинать файл со строки
#!/bin/bash
для того, чтобы в явной
форме показать, что вы рассчитываете на поведение в стиле bash.
eval
Команда eval позволяет вычислять аргументы. Она встроена в командную оболочку и обычно не представлена как отдельная команда. Лучше всего ее действие демонстрирует короткий пример, позаимствованный непосредственно из стандарта X/Open.
foo=10
x=foo
у='$'$х
echo $у
Будет выведено
$foo
. Однако код
foo=10
x=foo
eval у='$'$х
echo $у
выведет на экран 10. Таким образом,
eval
немного похожа на дополнительный знак
$
: она возвращает значение значения переменной.
Команда
eval
очень полезна, т.к. позволяет генерировать и выполнять код на лету. Применение этой команды усложняет отладку сценария, но разрешает делать то, что в противном случае выполнить сложно или даже невозможно.
exec
У команды
exec
два варианта применения. Обычно ее используют для замены текущей командной оболочки другой программой.
Например, строка
exec wall "Thanks for all the fish"
в сценарии заменит текущую оболочку командой
wall
. Строки, следующие за командой
exec
, не обрабатываются, потому что командная оболочка, выполнявшая сценарий, больше не существует.
Второй вариант применения
exec
— модификация текущих дескрипторов файлов.
exec 3< afile
Эта команда открывает файловый дескриптор 3 для чтения из файла afile. Этот вариант редко используется.
exit n
Команда
exit
вызывает завершение сценария с кодом завершения
n
. Если вы примените ее в строке подсказки или приглашения любой интерактивной командной оболочки, она приведет к вашему выходу из системы. Если разрешить сценарию завершиться без указания кода завершения, статус последней выполненной в сценарии команды используется как возвращаемое значение. Задание кода завершения считается хорошим стилем программирования.
При программировании сценариев в командной оболочке код завершения 0 — успешное завершение сценария, коды от 1 до 125 включительно — коды ошибок, которые можно использовать в сценариях. Оставшиеся значения зарезервированы в соответствии с табл. 2.5.
Таблица 2.5
Код завершения
Описание
126
Файл не является исполняемым
127
Команда не найдена
128 и выше
Появившийся сигнал
Многим программистам на языках С и С++ использование нуля как признака успешного завершения может показаться несколько необычным. Большое преимущество сценариев — возможность применения 125 кодов ошибок, определенных пользователем, и отсутствие необходимости в глобальной переменной для хранения кода ошибки.
Далее приведен простой пример, возвращающий код успешного завершения, если в текущем каталоге существует файл с именем .profile.
#!/bin/sh
if [ -f .profile ]; then
exit 0
fi
exit 1
Если вы любитель острых ощущений или, как минимум, лаконичных сценариев, можете переписать сценарий в виде одной строки, используя комбинацию И-списка и ИЛИ-списка, описанных ранее:
[ -f .profile ] && exit 0 || exit 1
export
Команда
export
делает переменную, называемую ее параметром, доступной в подоболочках. По умолчанию переменные, созданные в командной оболочке, не доступны в новых дочерних подоболочках, запускаемых из данной. Команда
export
создает из своего параметра переменную окружения, которая видна другим сценариям и программам, запускаемым из текущей программы. Говоря профессиональным языком, экспортируемые переменные формируют переменные окружения в любых дочерних процессах, порожденных командной оболочкой. Лучше всего проиллюстрировать это примером из двух сценариев:
export1
и
export2
(упражнение 2.14).
Упражнение 2.14. Экспорт переменных
1. Первым представим сценарий export2.
#!/bin/sh
echo "$foo"
echo "$bar"
2. Теперь сценарий export1. В конце сценария запускается export2.
#!/bin/sh
foo="The first meta-syntactic variable"
export bar="The second meta-syntactic variable"
export2
Если вы запустите их, то получите следующий результат.
$ ./export1
The second meta-syntactic variable
$
Как это работает
Сценарий export2 просто выводит значения двух переменных. В сценарии export1 задаются значения обеих переменных, но только переменная bar помечается как экспортируемая, поэтому, когда впоследствии запускается сценарий export2, значение переменной
foo
потеряно, а значение переменной
bar
экспортировано во второй сценарий. На экране появляется пустая строка, поскольку
$foo
ничего не содержит и вывод переменной со значением