[ Примітка: наступне було відхилено як редагування цієї відповіді з причин, які для мене не мають сенсу (оскільки редакція не була призначена для звернення до автора публікації!), Тому я приймаю пропозицію зробити її окремою відповідь.]
Більш проста реалізація адаптації Стіва Зобелла методики Метта МакКлура використовує вбудований bash (починаючи з версії == 4 ), readarray
як пропонується RastaMatt, для створення представлення масиву, який може бути перетворений в масив під час виконання. (Зверніть увагу на те, що обидва readarray
і mapfile
називають один і той самий код.) Він все одно уникає глобалів (що дозволяє використовувати функцію в трубі), і все ще обробляє неприємні символи.
Деякі більш розроблені (наприклад, більша модуляризація), але все ще певні приклади іграшок, див. Bash_pass_arrays_between_functions . Нижче наведено декілька легко виконуваних прикладів, наведених тут, щоб уникнути модераторів, які б не стосувались зовнішніх посилань.
Виріжте наступний блок і вставте його в термінал bash, щоб створити /tmp/source.sh
та /tmp/junk1.sh
:
FP='/tmp/source.sh'
cat << 'EOF' > "${FP}"
function make_junk {
echo 'this is junk'
echo '#more junk and "b@d" characters!'
echo '!#$^%^&(*)_^&% ^$#@:"<>?/.,\\"'"'"
}
function lines_to_array_representation {
local -a arr=()
readarray -t arr
declare -p arr | sed -e 's/^declare -a [^=]*=//'
}
EOF
FP1='/tmp/junk1.sh'
cat << 'EOF' > "${FP1}"
source '/tmp/source.sh'
returned_string="$(make_junk | lines_to_array_representation)"
eval "declare -a returned_array=${returned_string}"
for elem in "${returned_array[@]}" ; do
echo "${elem}"
done
EOF
chmod u+x "${FP1}"
Виконати /tmp/junk1.sh
: вихід повинен бути
this is junk
!
Примітка lines_to_array_representation
також обробляє порожні рядки. Спробуйте вставити наступний блок у ваш термінал bash:
FP2='/tmp/junk2.sh'
cat << 'EOF' > "${FP2}"
source '/tmp/source.sh'
echo '`bash --version` the normal way:'
echo '--------------------------------'
bash --version
echo
echo '`bash --version` via `lines_to_array_representation`:'
echo '-----------------------------------------------------'
bash_version="$(bash --version | lines_to_array_representation)"
eval "declare -a returned_array=${bash_version}"
for elem in "${returned_array[@]}" ; do
echo "${elem}"
done
echo
echo 'But are they *really* the same? Ask `diff`:'
echo '-------------------------------------------'
echo 'You already know how to capture normal output (from `bash --version`):'
declare -r PATH_TO_NORMAL_OUTPUT="$(mktemp)"
bash --version > "${PATH_TO_NORMAL_OUTPUT}"
echo "normal output captured to file @ ${PATH_TO_NORMAL_OUTPUT}"
ls -al "${PATH_TO_NORMAL_OUTPUT}"
echo
echo 'Capturing L2AR takes a bit more work, but is not onerous.'
echo "Look @ contents of the file you're about to run to see how it's done."
declare -r RAW_L2AR_OUTPUT="$(bash --version | lines_to_array_representation)"
declare -r PATH_TO_COOKED_L2AR_OUTPUT="$(mktemp)"
eval "declare -a returned_array=${RAW_L2AR_OUTPUT}"
for elem in "${returned_array[@]}" ; do
echo "${elem}" >> "${PATH_TO_COOKED_L2AR_OUTPUT}"
done
echo "output from lines_to_array_representation captured to file @ ${PATH_TO_COOKED_L2AR_OUTPUT}"
ls -al "${PATH_TO_COOKED_L2AR_OUTPUT}"
echo
echo 'So are they really the same? Per'
echo "\`diff -uwB "${PATH_TO_NORMAL_OUTPUT}" "${PATH_TO_COOKED_L2AR_OUTPUT}" | wc -l\`"
diff -uwB "${PATH_TO_NORMAL_OUTPUT}" "${PATH_TO_COOKED_L2AR_OUTPUT}" | wc -l
echo '... they are the same!'
EOF
chmod u+x "${FP2}"
Запустіть /tmp/junk2.sh
@ commandline. Ваш результат повинен бути подібним до мого:
`bash --version` the normal way:
--------------------------------
GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
`bash --version` via `lines_to_array_representation`:
-----------------------------------------------------
GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
But are they *really* the same? Ask `diff`:
-------------------------------------------
You already know how to capture normal output (from `bash --version`):
normal output captured to file @ /tmp/tmp.Ni1bgyPPEw
-rw------- 1 me me 308 Jun 18 16:27 /tmp/tmp.Ni1bgyPPEw
Capturing L2AR takes a bit more work, but is not onerous.
Look @ contents of the file you're about to run to see how it's done.
output from lines_to_array_representation captured to file @ /tmp/tmp.1D6O2vckGz
-rw------- 1 me me 308 Jun 18 16:27 /tmp/tmp.1D6O2vckGz
So are they really the same? Per
`diff -uwB /tmp/tmp.Ni1bgyPPEw /tmp/tmp.1D6O2vckGz | wc -l`
0
... they are the same!