Используйте $(parent).html(code)
вместо parent.innerHTML = code
.
Ниже также исправлены скрипты, использующие document.write
и скрипты, загруженные через атрибут src
. К сожалению, даже это не работает с скриптами Google AdSense.
var oldDocumentWrite = document.write;
var oldDocumentWriteln = document.writeln;
try {
document.write = function(code) {
$(parent).append(code);
}
document.writeln = function(code) {
document.write(code + "
");
}
$(parent).html(html);
} finally {
$(window).load(function() {
document.write = oldDocumentWrite
document.writeln = oldDocumentWriteln
})
}
Невозможно экспортировать (пока) переменные массива.
Из manpage версии bash 4.1.5 в разделе ubuntu 10.04.
Следующее утверждение из Chet Ramey (текущий разработчик bash по состоянию на 2011 год), вероятно, является самой официальной документацией об этой «ошибке»:
На самом деле нет хорошего способа кодирования переменной массива в среде.
вы (hi!) можете использовать это, не нужно писать файл, для ubuntu 12.04, bash 4.2.24
Кроме того, ваш массив с несколькими строками может быть экспортирован.
cat >> exportArray.sh
function FUNCarrayRestore() {
local l_arrayName=$1
local l_exportedArrayName=${l_arrayName}_exportedArray
# if set, recover its value to array
if eval '[[ -n ${'$l_exportedArrayName'+dummy} ]]'; then
eval $l_arrayName'='`eval 'echo $'$l_exportedArrayName` #do not put export here!
fi
}
export -f FUNCarrayRestore
function FUNCarrayFakeExport() {
local l_arrayName=$1
local l_exportedArrayName=${l_arrayName}_exportedArray
# prepare to be shown with export -p
eval 'export '$l_arrayName
# collect exportable array in string mode
local l_export=`export -p \
|grep "^declare -ax $l_arrayName=" \
|sed 's"^declare -ax '$l_arrayName'"export '$l_exportedArrayName'"'`
# creates exportable non array variable (at child shell)
eval "$l_export"
}
export -f FUNCarrayFakeExport
проверить этот пример на терминальном bash (работает с bash 4.2.24):
source exportArray.sh
list=(a b c)
FUNCarrayFakeExport list
bash
echo ${list[@]} #empty :(
FUNCarrayRestore list
echo ${list[@]} #profit! :D
Я могу улучшить его здесь
PS .: Если кто-то очищает / улучшает / makeItRunFaster, я хотел бы знать / see, thx! : D
Я редактировал другую запись и сделал ошибку. Augh. В любом случае, возможно, это может помочь? https://stackoverflow.com/a/11944320/1594168
Обратите внимание, что поскольку формат массива оболочки недокументирован в bash или любой другой стороне оболочки, очень трудно вернуться массив оболочек независимо от платформы. Вам нужно будет проверить версию, а также создать простой скрипт, который объединяет все массивы оболочек в файл, который могут разрешить другие процессы.
Однако, если вы знаете имя массива, который хотите принять назад домой, тогда есть способ, хотя немного грязный.
Допустим, у меня есть
MyAry[42]="whatever-stuff";
MyAry[55]="foo";
MyAry[99]="bar";
Итак, я хочу забрать его домой
name_of_child=MyAry
take_me_home="`declare -p ${name_of_child}`";
export take_me_home="${take_me_home/#declare -a ${name_of_child}=/}"
Мы можем видеть, что он экспортируется путем проверки из подпроцесса
echo ""|awk '{print "from awk =["ENVIRON["take_me_home"]"]"; }'
Результат:
from awk =['([42]="whatever-stuff" [55]="foo" [99]="bar")']
Если мы абсолютно обязаны, используйте env var для его выгрузки.
env > some_tmp_file
Затем
Перед запуском другого скрипта,
# This is the magic that does it all
source some_tmp_file
Для массивов со значениями без пробелов я использовал простой набор функций для итерации по каждому элементу массива и конкатенации массива:
_arrayToStr(){
array=($@)
arrayString=""
for (( i=0; i<${#array[@]}; i++ )); do
if [[ $i == 0 ]]; then
arrayString="\"${array[i]}\""
else
arrayString="${arrayString} \"${array[i]}\""
fi
done
export arrayString="(${arrayString})"
}
_strToArray(){
str=$1
array=${str//\"/}
array=(${array//[()]/""})
export array=${array[@]}
}
Первая функция с превращением массива в string, добавляя открывающиеся и закрывающиеся круглые скобки и избегая всех двойных кавычек. Вторая функция разделит кавычки и скобки и поместит их в фиктивный массив.
Чтобы экспортировать массив, вы должны передать все элементы исходного массива:
array=(foo bar)
_arrayToStr ${array[@]}
На этом этапе массив был экспортирован в значение $ arrayString. Чтобы импортировать массив в файл назначения, переименуйте массив и выполните противоположное преобразование:
_strToArray "$arrayName"
newArray=(${array[@]})
Jeez. Я не знаю, почему другие ответы сделали это настолько сложным. Bash имеет почти встроенную поддержку для этого.
В сценарии экспорта:
myArray=( ' foo"bar ' $'\n''\nbaz)' ) # an array with two nasty elements
myArray="${myArray[@]@Q}" ./importing_script.sh
(обратите внимание, двойные кавычки необходимы для правильной обработки пробелов в элементах массива.)
При входе в importing_script.sh
значение переменной среды myArray
содержит эти точные 26 байтов:
' foo"bar ' $'\n\\nbaz)'
Затем восстанавливается следующий массив:
eval "myArray=( ${myArray} )"
ВНИМАНИЕ! Не нравится eval
, если вы не можете доверять источнику переменной среды myArray
. Этот трюк демонстрирует уязвимость «Маленькие бреющие столы» . Представьте, чтобы кто-то установил значение myArray
на ) ; rm -rf / #
.
eval
является опасной функцией, и ее нельзя использовать в сценариях.
– jww
25 October 2017 в 04:08
eval
is i> опасно, если вы не можете быть уверены в содержании проверяемой строки. Прочтите мое ПРЕДОСТЕРЕЖЕНИЕ выше.
– Matt Whitlock
26 October 2017 в 12:47
source othershellscript
– dothebart
1 December 2017 в 15:40
myArray
в дочернем процессе будет содержать массив, эквивалентный массиву, содержащемуся в переменной оболочки myArray
в родительском процессе. (Возможно, вы упустили круглые скобки в заявлении eval
?)
– Matt Whitlock
8 December 2017 в 06:17
Основываясь на использовании @mr.spuratic BASH_ENV
, здесь I туннель $@
через script -f -c
script -c <command> <logfile>
можно использовать для запуска команды внутри другой pty (и группы процессов) но он не может передать какие-либо структурированные аргументы в <command>
.
Вместо <command>
является простой строкой, которая будет аргументом для вызова библиотеки system
.
Мне нужно туннель $@
внешнего bash в $@
of bash, вызванный скриптом.
Поскольку declare -p
не может принимать @
, здесь я использую магическую переменную bash _
(с фиктивным значением первого массива, которое будет перезаписано bash). Это спасает меня от любых важных переменных:
Доказательство концепции: BASH_ENV=<( declare -a _=("" "$@") && declare -p _ ) bash -c 'set -- "${_[@]:1}" && echo "$@"'
«Но, вы говорите,« вы передаете аргументы в bash - и действительно я , но это простая строка известного символа. Здесь используется script
SHELL=/bin/bash BASH_ENV=<( declare -a _=("" "$@") && declare -p _ && echo 'set -- "${_[@]:1}"') script -f -c 'echo "$@"' /tmp/logfile
, которая дает мне эту функцию-обертку in_pty
:
in_pty() {
SHELL=/bin/bash BASH_ENV=<( declare -a _=("" "$@") && declare -p _ && echo 'set -- "${_[@]:1}"') script -f -c 'echo "$@"' /tmp/logfile
}
или эта обертка без функции в качестве составной строки для Makefiles:
in_pty=bash -c 'SHELL=/bin/bash BASH_ENV=<( declare -a _=("" "$$@") && declare -p _ && echo '"'"'set -- "$${_[@]:1}"'"'"') script -qfc '"'"'"$$@"'"'"' /tmp/logfile' --
...
$(in_pty) test --verbose $@ $^
Как сообщалось Lesmana, вы не можете экспортировать массивы. Поэтому вы должны их сериализовать, прежде чем проходить через среду. Эта сериализация полезно для других мест, где подходит только строка (su -c 'string', ssh host 'string'). Самый короткий способ сделать это - злоупотреблять «getopt»
# preserve_array(arguments). return in _RET a string that can be expanded
# later to recreate positional arguments. They can be restored with:
# eval set -- "$_RET"
preserve_array() {
_RET=$(getopt --shell sh --options "" -- -- "$@") && _RET=${_RET# --}
}
# restore_array(name, payload)
restore_array() {
local name="$1" payload="$2"
eval set -- "$payload"
eval "unset $name && $name=("\$@")"
}
Использовать его следующим образом:
foo=("1: &&& - *" "2: two" "3: %# abc" )
preserve_array "${foo[@]}"
foo_stuffed=${_RET}
restore_array newfoo "$foo_stuffed"
for elem in "${newfoo[@]}"; do echo "$elem"; done
## output:
# 1: &&& - *
# 2: two
# 3: %# abc
Это не относится к unset / разреженным массивам. Возможно, вы сможете уменьшить 2 'eval' вызовы в файле restore_array.