Как улучшить сценарии с помощью нового KornShell

Как ksh93 помогает улучшить сценарии оболочки

AIX 5L включает в себя ksh93, последнюю версию языка KornShell, в которой сделан ряд значительных улучшений по сравнению с предыдущей версией 1988 года. Новая версия представляет собой альтернативу языкам Tcl и Perl и выигрывает у них по скорости и функциональности. В этой статье рассказывается, как воспользоваться преимуществами ksh93.

Шив Дутта, старший инженер-программист, IBM

Шив Дутта (Shiv Dutta) - старший инженер-программист в группе IBM System And Technology Group; он оказывает помощь независимым производителям программного обеспечения в адаптации их программ на платформе System p. Шив был одним из соавторов справочника Красная книга (redbook) AIX 5L Differences Guide Version 5.3 Edition (Новое в AIX 5L версии 5.3). Вы можете связаться с ним по электронной почте sdutta@us.ibm.com.



06.04.2009

На протяжении многих лет KornShell был, может быть, самым мощным языком сценариев для оболочек, используемым в среде Unix/AIX. Его версия 1988 года (ksh88) уже имела больше возможностей, чем Bourne shell и C shell, две другие наиболее часто используемые командные оболочки, вместе взятые. В 1993 году в версию KornShell 1988 года были внесены большие усовершенствования, которые сделали его еще более мощным. В этой статье обсуждаются некоторые из этих улучшений. KornShell использовался во всех версиях AIX и, следовательно, обсуждаемые здесь улучшения могут быть интересны как для программистов, так и для разработчиков AIX. Целью этой статьи не является подробное обсуждение KornShell в целом и поэтому нет описания тех возможностей, которые были реализованы еще в предыдущих версиях оболочки. Новая версия ksh93 является расширенной версией 1988 года.

Введение

ksh93 представляет собой альтернативу двум другим популярным языкам сценариев Tcl и Perl. Как язык программирования он превосходит оба этих языка по скорости и функциональности. Более того, как и Tcl, его можно расширять и дополнять с помощью API на C.

В AIX 5L, как и в других версиях AIX, командной оболочкой по умолчанию является KornShell. Однако Kornshell, используемый в AIX 5L, является усовершенствованной POSIX-совместимой версией ksh88. AIX 5L включает в себя также копию версии 1993 года. Она представлена как /usr/bin/ksh93. Эта версия также POSIX-совместима. За исключением моментов, связанных с POSIX, ksh93 обратно совместима с ksh88.

Важно отметить, что в AIX 5L путь к командной оболочке – /usr/bin/ksh. Это особенно важно для пользователя root. В предыдущих версиях AIX путь был /bin/ksh, и требовалась связь между /bin и /usr/bin. Если эта связь случайно удалялась, то система становилась незагружаемой, потому что для пользователя root не оказывалось командной оболочки и многих системных команд.


Возможности ksh93

В этом разделе обсуждаются массивы, а также следующие темы:

Массивы

ksh93 поддерживает как индексированные массивы (имеются в ksh88), так и ассоциативные массивы. Индексированные массивы – это такие массивы, индексы которых являются целыми константами или целыми выражениями. В ksh93 диапазон для индексов индексированных массивов был увеличен. Он составляет от 0 до 4095 (в ksh88 – от 0 до 1023).

Ассоциативные массивы – это массивы, индексы которых являются строками. Атрибут -A объявления typeset указывает, что переменная является ассоциативным массивом. Синтаксис ассоциативных массивов включает правила для доступа и для возвращения списка индексов.

Синтаксис доступа

	${переменная[индекс]}
		- Все символы между скобками [ ] входят в индекс, включая пробел.

Пример

	$typeset -A sales
	$sales[magazine]=50
	$print ${sales[magazine]}
	50
	$print ${sales[" magazine "]}

	$sales[ book ]=100
	$print ${sales[book]}

	$print ${sales[ book ]}
	100

Возвращение списка индексов

${!varname[@]}	Результат - список индексов, 
определенных в массиве varname.
${!varname[*]}	Для переменной, не являющейся массивом,
 значение 0, если эта переменная
				определена. 
				В противном случае значением будет null.

				- * и @ различаются только в том случае, 
				когда сопровождаются двойными
				кавычками. В двойных кавычках
				 в ksh93 результатом формата
				${!varname[*]} является один аргумент, 
				а формата  ${!varname[@]} -
				отдельные аргументы для
				 каждого индекса массива.

Пример

	typeset -A color
	color=([apple]=yellow  [banana]=green  [grape]=purple)

	for i in ${!color[*]}  
	do 
		print $i ${color[$i]}
	done

	for i in ${!color[@]} 
	do  
		print $i ${color[$i]}
	done
	
	for i in "${!color[*]}"
	do 
		print $i ${color[$i]}
	done

	for i in "${!color[@]}"
	do 
		print $i ${color[$i]}
	done

	------------------------ Результат---------------------------
	grape  purple
	apple  yellow
	banana  green

	grape  purple
	apple  yellow
	banana  green

	grape apple banana

	grape  purple
	apple  yellow
	banana  green

Составные переменные

В ksh93 переменная определяется парой имя=значение, где пространством имен для переменной является иерархия идентификаторов с символом "." (точка) в качестве разделителя. Переменная с . (точкой) в имени называется составной переменной. Чтобы создать переменную с точкой в имени, должна уже существовать переменная, имя которой содержит все до точки. Например, new.var допустима, если уже существует new. Переменные, чьи имена содержат точки, не могут экспортироваться.

Расширенное пространство имен дает возможность делать для переменной определения агрегированных данных. Имена переменных, начинающиеся с .sh, зарезервированы для ksh93. Ниже приводится определение составной переменной с именем grid.

	$grid=(
		# максимальный размер grid
		integer maximum=10
		# максимальная ширина 
		integer width=20
		# текущий индекс в grid
		integer index=30
		typeset entries
		)

Пример

	$print ${grid.maximum}
	10
	$print ${grid.width}
	20
	$print ${grid.index}
	30

В этом примере определяется составная переменная grid, состоящая из элементов maximum, width, index и entries. Ссылка ${grid.index} возвращает значение, связанное с элементом index. Используя команду eval, можно создавать дополнительные переменные с теми же элементами. Например, можно определить переменные row и col так, чтобы они имели такое же определение, как и grid:

	$eval row="$grid"
	$eval col="$grid"

Пример

	$print ${row.maximum}
	10
	$print ${row.width}
	20
	$print ${row.index}
	30

	$print ${col.maximum}
	10
	$print ${col.width}
	20
	$print ${col.index}
	30

Составные присвоения

Составные присвоения могут использоваться для присвоения значений индексированному или ассоциативному массиву и для присвоения значений соответствующим составным переменным. Это механизм для присвоения значений одной или более переменным. Он может принимать следующие формы:

varname=(value ...)  		Для присвоения значений индексированному массиву 
							с именем varname.
varname=([expression]=value ...)  Для присвоения значений ассоциативному массиву
							с именем varname.
varname=(assignment ...) 	Для присвоения значений набору переменных, имена которых
							имеют вид varname.name.

Перед = не допускаются пробелы и табуляция.
Пробелы и табуляция разрешаются после ( и перед )
Первое значение связывается с индексом 0, второе значение — с индексом 1, и т.д.

Пример 1

	$files=(*)

	for i in ${!files[@]}
	do
		print ${files[$i]}
	done

	------------ Результат------------

	Список файлов в текущем каталоге

Пример 2

	$age=( [John]=18 [Pat]=21 [Phillip]=23 )
	$print ${!age[*]}
	John Pat  Phillip

Пример 3

	$point=( a=3.5 b=4.2 )
	$print ${point.a}
	3.5
	$print ${point.b}
	4.2

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

	variable=(value... )

Пример

	$ab= ( one two )
	$print ${ab[0]} ${ab[1]}
	one two
	$IFS=:
	PATH=/bin:/usr/bin:/usr/local:/etc
	paths= ( ${PATH} )
	$print ${paths[0]} ${paths[2]}
	/bin /usr/local

Создание ассоциативных массивов с помощью составного присвоения

Пример

	typeset -A color
	color=([sky]=blue  [fire]=red [marigold]=yellow)

	for i in ${!color[@]}  
	do 
		print $i ${color[$i]}
	done

	-------------------- Результат --------------------
	marigold  yellow
	fire  red
	sky  blue

Ссылки на имя

Часто бывает полезно передать имя переменной, а не ее значение, в качестве аргумента функции. Переменная-ссылка на имя, называемая nameref, дает механизм предоставления локального имени для этой переменной. Атрибут typeset-n указывает, что переменная является ссылкой на другую переменную. Имя для ссылки на имя должно быть идентификатором. Как только ссылка на имя создана, каждая ссылка на эту переменную приводит к использованию переменной, названной по ссылке на имя.

Переменная nameref не может содержать точки в имени.

Пример 1

	$old=123
	$typeset -n new=old
	$echo $new
	123

nameref-переменная может также использоваться для изменения значения первоначальной переменной.

	$new=345
	$echo $old
	345

Особенно удобно nameref использовать для передачи имен переменных функциям.

Пример 2

	function getFile {

	typeset -n filename=${1}
	typeset message="${2}"

	print -n "${message}"
		read filename
	}

	function canRead  {

	typeset -n file=${1}

		if [[ -r ${file} ]]
		then
			return 0
		else
			return 1
		fi
	}

	function endPrint {

	print ${fromFile} скопирован в ${toFile}
	}

	getFile toFile "Копировать в файл: "
	getFile fromFile "Копировать из файла:  "

	if canRead fromFile
	then
		cp ${fromFile} ${toFile}
		endPrint
		exit 0
	else
		print -u2 не удается читать из ${fromFile}
		exit 1
	fi

Поддержка локализации

ksh93 обеспечивает поддержку локализации. Строки в двойных кавычках, перед которыми стоит $, проверяются на подстановку сообщений. Если данное сообщение есть в каталоге сообщений и переменная окружения оболочки LANG определена, а locale - не C и не POSIX, то ksh93 выполнит замену строки на соответствующую строку из каталога сообщений. В противном случае строка останется неизменной.

Команда ksh93 -D для сценария выведет все сообщения, определенные для локализации.


Пакет разработчика для KornShell

ksh93 можно расширять с помощью пакета разработчика для KornShell (KDK – KornShell Development Kit). Можно написать свои собственные встроенные функции на C и загружать их в текущую среду оболочки с помощью команды builtin. Эта возможность доступна на операционных системах, позволяющих делать загрузку и связывание кода в текущем процессе во время выполнения.

Выполняется встроенная команда без создания отдельного процесса. Эта команда вызывается ksh93 как C-функция. Если у этой функции нет побочных эффектов при выполнении в процессе командной оболочки, то поведение этой встроенной функции идентично поведению самостоятельной команды. В этом случае основная разница – в производительности, поскольку исключаются накладные расходы, связанные с созданием процесса.

Служебные функции

С каждой переменной может быть связана одна или более функций путем определения функций, имена которых имеют вид varname.action, где varname – имя переменной, а action – имя служебной функции. Служебные функции с именами get, set и unset могут быть определены для любой переменной. Эти функции вызываются, когда производятся действия с соответствующей переменной varname. С помощью пакета разработчика для KornShell можно также добавлять функции, уникальные для используемой среды.

Когда к переменной обращаются в виде $myVariable, ksh93 вызовет функцию get, связанную с myVariable. Служебная функция по умолчанию – это просто возврат текущего значения, связанного с myVariable. На уровне оболочки можно определить служебную функцию myVariable.get.

Функция set вызывается, когда переменной присваивается значение. Внутри функции set специальная переменная .sh.name является именем переменной, значение которой устанавливается. Значение специальной переменной .sh.value является значением, возвращаемым из функции.


Изменения и дополнения к ksh93

Ниже описываются арифметические возможности, а также другие изменения и дополнения:

Арифметические вычисления

ksh93 поддерживает арифметику с плавающей точкой двойной точности. Атрибуты typesetexponential (-E) и float (-F) используются для определения вещественных переменных. Каждый атрибут может быть задан с числом, которое обозначает:

	-E	Количество значимых цифр при преобразовании числа.
	-F	Количество цифр после запятой при преобразовании числа.

Пример

	$typeset -E4 x
	$typeset -F5 y
	$x=1234.567	
	$y=1234.567
	$print $x
	1235
	$print $y
	1234.56700

Внимание: Арифметические операции с числами смешанного типа могут привести к противоречивым результатам.

Добавлены следующие операторы:

  • Условный оператор ?:
  • Оператор "запятая" ,
  • Постфиксный и префиксный операторы ++ и --
  • Унарный +

В арифметических выражениях можно использовать функции из математической библиотеки ANSI C. Для целочисленных констант можно задавать представление числа вплоть до 64.

Имеются следующие функции:

abs, acos, asin, atan, cos, cosh, exp, int, log, sin, sinh, sqrt, tan, tanh

Новые подстановки параметров

В ksh93 имеются следующие подстановки параметров:

${!varname}	Результат - имя переменной, определяемой по varname.
		В большинстве случаев varname просто разворачивается как varname. 
		Однако если varname является ссылочной переменной,
		то результатом будет имя переменной, на которую ссылается varname.

Пример

	$x=10
	$print ${!x}
	x
	$nameref foo=bar
	$print ${!foo}
	bar

${variable:offset}		Подстрока, начинающаяся со смещения offset.
${variable:offset:[length]}	Вплоть до length cимволов variable, начиная с offset.

Основная задачи этой подстановки состоит в том чтобы возвращать (извлекать) подстроку из значения переменной variable. Значение variable не изменяется.

Пример

	$alphabet=abcdefghijklmnopqrstuvwxyz
	$print ${alphabet:12}
	mnopqrstuvwxyz
	$print ${alphabet:12:3}
	mno
	$print ${alphabet:12:30}
	mnopqrstuvwxyz
	$seven=7; two=2
	$print ${alphabet:${seven}:${two}}
	hi

${@:offset} Позиционные параметры, начинающиеся с offset.
${*:offset}

${@:offset:length} Вплоть до length позиционных параметров, начиная с offset.
${*:offset:length}

${varname[@]:offset} Элементы массива varname, начинающиеся с offset.
${varname[*]:offset}

${varname[@]:offset:length} Вплоть до length элементов массива varname, начиная с offset.
${varname[*]:offset:length}

Пример

	$set foo/fun/bar  hello.world  /dev/null
	$print ${@:2}
	hello.world  /dev/null
	$print ${*:2:4}
	hello.world  /dev/null
	$x=( foo/fun/bar  hello.world  /dev/null)
	$print ${x[@]:1:2}
	hello.world  /dev/null

${variableOPpattern/string}

Основная задача этой подстановки – возврат измененной версии значения переменной variable. Значение variable не изменяется.


Оператор OP	Действие
/	Значение variable при первом совпадении с шаблоном pattern замещается на string.
/#	Если variable начинается с pattern, pattern замещается на string.
/%	Если variable заканчивается шаблоном pattern, pattern замещается на string.
//	Значение variable при каждом совпадении с pattern замещается на string.

Пример

	$path=/chapters/chapter01/subchapter
	$print ${path/chapter/JUNK}
	/JUNKs/chapter01/subchapter

	$print ${path/#chapter/JUNK}
	/chapters/chapter01/subchapter

	$path=chapters/chapter01/subchapter
	$print ${path/#chapter/JUNK}
	JUNKs/chapter01/subchapter

	$print ${path//chapter/JUNK}
	JUNKs/JUNK01/subJUNK

Новые механизмы заключения в кавычки

ksh93 обрабатывает строку в одиночных кавычках, перед которой стоит $, $’...’ используя соглашения для строк ANSI C.

В ANSI C строка определяется с помощью $ перед строкой в одиночных кавычках. Например, $'*' – литеральная звездочка *. В строках ANSI C все символы между одиночными кавычками сохраняют свое литеральное значение, за исключением escape-последовательностей.

	$print -r $’${PWD} \nвозвращает текущий каталог.’
	${PWD}
	возвращает текущий каталог.

	$print $’${PWD} \nвозвращает текущий каталог.’
	${PWD}
	возвращает текущий каталог.

ksh93 обрабатывает строку в двойных кавычках, перед которой стоит $, $"...", как строку, которую нужно перевести, если locale не C и не POSIX. $ игнорируется в locale C и POSIX.

Поддержка строк в ANSI C является очень важным моментом при программировании на языке сценариев. Рассмотрим, например, случай, когда нужно обработать переменные с символами табуляции в их значениях. Без поддержки строк ANSI C нельзя эффективно проверить значение переменной на вставленные символы табуляции. В качестве примера рассмотрим следующий сценарий:

Пример 1

	$print $’hello\n\tworld’

	hello
		world

Пример 2

	$print "foo\tbar" > /tmp/foobar
	$read aline <  /tmp/foobar
	$if [[ "${aline}" == "foo\tbar" ]]
	then 
		print TRUE
	fi

Сравнение не получится. Если в условии строку заменить строкой ANSI C, сравнение сработает, как показано ниже:

	$print "foo\tbar" > /tmp/foobar
	$read aline < /tmp/foobar
	$if [[ "${aline}" == $'foo\tbar' ]]
	then      
		print TRUE
	fi

Дополнения ввода/вывода

За операторами перенаправления >& цифра и <& цифра может следовать - , что приведет к перемещению данного файлового дескриптора, а не к копированию.

Пример

	exec 3<&4-	# Перемещает файловый дескриптор 4 в 3.

Встроенная команда printf и параметр форматирования -f для print могут использоваться для осуществления форматированного вывода с помощью соглашений форматирования ANSI C. Кроме того, print и printf могут содержать следующие параметры форматирования:

%b	Разворачивать escape-последовательности в каждом параметре.
%q	Заключать в кавычки строки, содержащие специальные символы.
%P	Обрабатывать параметр как регулярное выражение 
			и преобразовать его в шаблон оболочки.

У встроенной команды read есть параметры для задания таймаута (-t) и символа разделителя строк (-d). Кроме того, можно указать, что read разделяет поля в индексированный массив.

	read -t 15 line	# Ждет до 15 секунд, затем считывает строку в переменную с именем 
					# line.
	read -d : field	# Читает до символа : в переменную field.
	read -A var 	# Сохраняет поля в var как индексированный массив,
					# начиная с индекса 0, используя символы
					# в переменной IFS в качестве разделителей.

Новое поведение для функций

Если объявить функцию в виде function varname, то ksh93 будет выполнять эту функцию в отдельном окружении.

Если объявить функцию в виде varname(), ksh93 будет выполнять эту функцию в текущем окружении, как сценарий с точкой.

Второй формат предоставляется для совместимости со стандартами POSIX. Главное отличие состоит в области видимости имени переменной. В приведенной ниже POSIX-функции bar переменная foo имеет глобальную область видимости и переопределяется с присвоением значения 6.

	typeset foo=5
	bar()
	{
		typeset foo=6
		echo $foo
	}
	bar
	6
	echo $foo
	6

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

	typeset foo=5
	function bar
	{
		typeset foo=6
		echo $foo
	}
	bar
	6
	echo $foo
	5

Новые возможности поиска по шаблону

Конструкция сравнения с шаблоном [:character_class:] внутри [ ] ищет совпадения с заданным набором символов. Имеются следующие классы символов:

Класс символов	То же самое, что и

[:alnum:]		a-z, A-Z, 0-9
[:alpha:]		как a-z, A-Z
[:blank:]		пробел или символ табуляции
[:cntrl:]		набор управляющих символов
[:digit:] 		0-9
[:graph:] 		цифры, символы и знаки препинания
[:lower:] 		a-z
[:print:]		цифры, символы, знаки препинания и символ пробела 
[:punct:]  		любой знак препинания
[:space:] 		пробел, символ табуляции, перевод строки, вертикальная табуляция,
				перевод страницы, возврат каретки
[:upper:]		A-Z
[:xdigit:]		шестнадцатеричная цифра a-f, A-F, 0-9

Пример

	para[[:digit:]t] совпадает с para0, para1, ..., para9, и parat

Поиск по шаблону в строках

	строка = = шаблон
  • Истина, если строка совпадает с шаблоном.
  • По обе стороны от = = должны быть пробелы.

Встроенные переменные

Ниже приводятся некоторые из 16 новых переменных, добавленных в ksh93:

.sh.name			В служебной (discipline)
 функции присваивается имя переменной,
						связанной с этой функцией.
.sh.subscript	В служебной функции 
присваивается имя индекса переменной,
						связанной с этой функцией.
.sh.value		В служебной функции set 
присваивается значение,
						которое должно быть	
						присвоено переменной, 
						связанной с функцией set. 
						Когда служебная функция завершится,
						значение .sh.value
						 будет равно присвоенному значению.

Пример

	unset foo
	function foo.set
	{
		print "old: ${.sh.name}[ ${.sh.subscript}]=${.sh.value}"
		.sh.value=good
	}
	foo[3]=bad
	old:foo[3]=bad
	print "new: foo[3]=${foo[3]}"
	new:foo[3]=good

.sh.version	Версия оболочки.

				$print ${.sh.version}
				Version M-12/28/93e

FIGNOREksh93 игнорирует каждое имя, которое соответствует образцу, определенному значением FIGNORE.

Пример

	$print /usr/*/include/*		
	# Отображает список файлов во всех каталогах include.

	/usr/local/include/sys /usr/gcc/include/sys
	$FIGNORE=gcc      			
	# Шаблон для соответствия всем исходным файлам на C.
	$print usr/*/include/*
	/usr/local/include/sys

HISTCMD		
Номер текущей команды в файле истории команд.
ERRNO 		
Эта переменная удалена из ksh93. 
Сообщения об ошибках,
					выдаваемые ksh93, 
					в большинстве случаев указывают причину
					системных отказов.
ENV	 		Эта переменная теперь эффективна 
только для интерактивных оболочек.
SECONDS		Эта переменная имеет теперь
 миллисекундное разрешение, а не секундное.
TMOUT 		Эта переменная также задает
 таймаут для команды select.

Новые составные команды

Составная команда отрицания (зарезервированное слово !) отрицает возвращаемое значение выражения.

Пример

	if   ! who | grep -s ‘sdutta’
	then 
		print sdutta is not logged on
	fi

Возвращаемое ! значение:

  • True (нулевое), если возвращаемое значение выражения False (ненулевое).
  • False (ненулевое), если возвращаемое значение выражения True (нулевое).

Команда управления

Новая арифметическая составная команда for подобна команде for языка ANSI C:

	for ((init; test; increment))
	do
		список команд
	done

Новые правила поиска в PATH

В способ поиска команд в ksh93 были внесены следующие изменения:

  • Первыми ищутся только специальные встроенные команды. (В ранних версиях KornShell сначала делался поиск всех встроенных команд.) Специальные встроенные команды – это встроенные команды, которые выполняются в текущем окружении, например, alias, break, continue и т.д.
  • Затем выполняется поиск функций.
  • Затем поиск неспециальных встроенных команд.
  • Затем выполняется поиск внешних команд, который ведется по каталогам, перечисленным в $PATH.
  • Во время поиска в PATHksh93 обрабатывает каталоги, которые также присутствуют в FPATH как каталоги для поиска функций. В ранних версиях оболочки поиск для функций, находящихся в FPATH, делался только после поиска по PATH.
  • Встроенные команды могут быть связаны с полным именем файла. В этом случае эта встроенная команда используется только тогда, когда поиск по PATH выдает этот PATH.
  • Параметр trackall в ksh93 включен по умолчанию.

Изменения возвращаемых значений

Возвращаемые значения изменены следующим образом:

  • Если команда не найдена, то возвращается 127.
  • Если команда найдена, но не может быть выполнена, то возвращается 126.
  • Если команда завершается по сигналу, возвращается 256 плюс номер сигнала. Можно воспользоваться kill -l, чтобы получить имя сигнала, вызвавшего возвращенное значение.

Дополнения и изменения во встроенных командах

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

Добавлены следующие встроенные команды:

  • builtin может использоваться для получения списка встроенных команд или для добавления динамически связанных библиотек и новых встроенных команд.
  • command исключает функции из порядка поиска. Перед специальной встроенной командой command заставляет ее вести себя как обычная встроенная команда.
  • disown заставляет ksh93 не посылать сигнал HUP указанным заданиям.
  • false возвращает False. В ksh88 это был псевдоним.
  • true возвращает True. В ksh88 это был псевдоним.
  • getconf отображает значение параметров конфигурации системы.
  • hist – то же самое, что и fc в ksh88. fc теперь псевдоним.
  • printf – почти то же самое, что и функция printf в языке программирования ANSI C.

Команды alias и typeset с параметром -f игнорируют параметр -x, поскольку псевдонимы и функции больше не экспортируются в сценарии.

Следующие параметры добавлены в exec:

  • -a name для указания имени команды в качестве параметра.
  • -c для очистки окружения.

Следующие параметры добавлены или изменены в kill:

  • -n для указания сигнала по номеру сигнала.
  • -s для указания сигнала по имени сигнала.
  • -l без параметров только перечисляет имена сигналов, но не их номера. -l может использоваться для преобразования имени сигнала в номер сигнала и наоборот.

Следующие параметры добавлены в unset:

  • -n удаляет определение переменной-ссылки на имя.
  • -v указывает, что будут удалены определения только переменных.

Следующие параметры добавлены в whence:

  • -a отображает все совпадения для каждого имени.
  • -f пропускает поиск функций.

Встроенная команда "точка" (.) теперь выполняет как функции, так и файлы. ksh93 выполняет указанную функцию в текущем окружении. ksh93 использует для поиска функции путь, заданный в переменной FPATH. Кроме того, параметры, переданные . (точке), восстанавливаются, когда сценарий или функция с точкой . завершается.

Новые параметры запуска ksh93

В ksh93 добавлены следующие новые параметры запуска:

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

Заданные псевдонимы

Следующие псевдонимы определены оболочкой:

	command=’command’
	fc=hist
	float=’typeset -E’
	nameref=’typeset -n’
	redirect=’command exec’
	times=’{ { times; } 2>&1; }’

Использование ksh93 для создания сценария с suid

Для подготовки сценария с suid требуется:

  • #! Указание на использование KornShell.
  • Права на выполнение для пользователя, группы и остальных.
  • Отсутствие прав на чтение.
  • Добавить права suid с помощью chmod u+s для файла.

Добавить параметр -p к #! для усиления безопасности, чтобы принудительно вызвать создание отдельного процесса, если при обычном выполнении этого не делается.

Пример

	#! /usr/bin/ksh -p

Ввод/вывод в командной оболочке

Версии ksh93 дают возможность серверам получать непосредственный доступ к сокетам, если операционная система поддерживает соединения сокетов в виде:

	/dev/tcp/hostid/portid   
	/dev/udp/hostid/portid

где:

  • hostid - десятичный номер компьютера, разделенный точками.
  • portid - порт, который слушает сервер.

Назначение клавиш

В ksh93 возможно перехватывание клавиш во время ввода и придание им нового смысла. Каждый раз, когда оболочка обрабатывает символы, введенные с клавиатуры (за исключением тех, что используются в строках поиска или в качестве аргумента к директиве редактирования, например, r в vi), срабатывает метод-перехватчик KEYBD, и действие, связанное с этим методом, может быть использовано для изменения значения введенной клавиши так, что она будет выполнять другую операцию.

FPATH

Функции ksh93 не наследуются между различными экземплярами ksh93. Например, дочерний процесс не имеет доступа к функциям, определенным в родительском процессе ksh93. Это исторически ограничило возможность повторного использования функций в KornShell. В качестве решения этой проблемы ksh93 ищет в разделенном двоеточиями списке каталогов из FPATH исполняемый файл с таким же именем, как и у функции.


Заключение

ksh93, новейшая версия языка KornShell, имеет ряд значительных улучшений по сравнению с ее предыдущей версией 1988 года. Эта новая версия, являющаяся альтернативой Tcl и Perl, выгодно отличается по скорости и функциональности. Как и Tcl, ее можно расширять и дополнять с помощью API на C.

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=380217
ArticleTitle=Как улучшить сценарии с помощью нового KornShell
publish-date=04062009