ksh: присвоение вывода функции массиву - PullRequest
2 голосов
/ 20 марта 2010

Почему это не работает ???

#!/bin/ksh

# array testfunc()
function testfunc {
    typeset -A env
    env=( one="motherload" )
            print -r $env
    return 0
}

testfunc # returns: ( one=motherload )
typeset -A testvar # segfaults on linux, memfaults on solaris 
testvar=$(testfunc) # segfaults on linux, memfaults on solaris
print ${testvar.one}

примечание: я обновил приведенный выше скрипт до print ${testvar.one} с print $testvar, чтобы более точно показать, что я пытаюсь выполнить.

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

ksh версия:

linux: version sh (AT&T Research) 1993-12-28 s+

solaris: version sh (AT&T Research) 93s+ 2008-01-31

Обновление:

Итак, еще один вопрос: он будет работать в ksh 93t + без сообщения об ошибке, но он не назначит массив должным образом. Я хотел бы пойти о назначении массива из функции? Я попытался присвоить массив так же:

typeset -A testvar=$(testfunc)
print ${testvar.one}

Но это также не сработало должным образом.

EDIT

Так что же здесь происходит?

typeset -A env=( one="motherload" two="vain" )
print ${env.one}
print ${env.two}

Я думал, что именно так вы определили ассоциативные массивы, может быть, то, на что я смотрел, было старым, но кто знает ... кажется странным поведение, так как это выводит "motherload" и "напрасно"

1 Ответ

2 голосов
/ 20 марта 2010

Ваш скрипт отлично работает для меня в Linux с ksh 93t +.

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

hd filename
cat -v filename
hexdump -C filename

Если это просто вопрос окончания строки DOS, то это исправит:

dos2unix filename

Edit:

Вот один из способов создания и заполнения ассоциативного массива в ksh:

$ typeset -A testvar
$ testvar=([one]="motherlode" [two]="vein" [waste]="tailings")
$ echo ${testvar[two]}
vein
$ testvar[ore]="gold"
$ echo ${!testvar[@]}    # print the indices of the array
one two waste ore
$ typeset -p testvar     # show the current definition of the array
typeset -A testvar=([one]="motherlode" [two]="vein" [waste]="tailings" [ore]="gold")

Как вы можете видеть, ksh использует заключенные в скобки индексы для массивов. Пунктирная запись используется для доступа к членам составной переменной .

Я не верю, что функции ksh могут возвращать массивы. Однако вы можете использовать технику печати, которая есть в вашей функции (но добавьте квадратные скобки вокруг имени индекса), и использовать eval для выполнения назначения.

$ typeset -A testvar 
$ eval "testvar=($(testfunc))"

или добавить в существующий массив:

$ eval "testvar+=($(testfunc))"

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

Однако, если вы это сделаете, вы можете проанализировать результат typeset -p:

$ result=$(typeset -p env)
$ result=${result#*\(}
$ result=${result%\)*}
$ print result

или перебрать массив:

$ for index in ${!env[@]}; do print -n "[$index]=${env[$index]} "; done; print

Вы можете обратиться к документации, касающейся дисциплинарных функций и переменных типа

...