J'ai une fonction qui crée un tableau et je veux renvoyer le tableau à l'appelant:
create_array() {
local my_list=("a", "b", "c")
echo "${my_list[@]}"
}
my_algorithm() {
local result=$(create_array)
}
Avec cela, je ne reçois qu'une chaîne étendue. Comment puis-je "retourner" ma liste sans utiliser quoi que ce soit de global?
Quel est le problème avec globals?
Retourner des tableaux n'est vraiment pas pratique. Il y a beaucoup de pièges.
Cela dit, voici une technique qui fonctionne si la variable a le même nom si elle est OK:
$ f () { local a; a=(abc 'def ghi' jkl); declare -p a; }
$ g () { local a; eval $(f); declare -p a; }
$ f; declare -p a; echo; g; declare -p a
declare -a a='([0]="abc" [1]="def ghi" [2]="jkl")'
-bash: declare: a: not found
declare -a a='([0]="abc" [1]="def ghi" [2]="jkl")'
-bash: declare: a: not found
Les commandes declare -p
(À l'exception de celle de f()
permettent d'afficher l'état du tableau à des fins de démonstration. Dans f()
, il est utilisé comme mécanisme pour renvoyer le tableau. tableau.
Si vous avez besoin que le tableau ait un nom différent, vous pouvez faire quelque chose comme ceci:
$ g () { local b r; r=$(f); r="declare -a b=${r#*=}"; eval "$r"; declare -p a; declare -p b; }
$ f; declare -p a; echo; g; declare -p a
declare -a a='([0]="abc" [1]="def ghi" [2]="jkl")'
-bash: declare: a: not found
-bash: declare: a: not found
declare -a b='([0]="abc" [1]="def ghi" [2]="jkl")'
-bash: declare: a: not found
Avec la version 4.3 et les versions ultérieures de Bash, vous pouvez utiliser un nameref pour que l'appelant puisse passer le nom du tableau et l'appelé puisse utiliser un nameref pour remplir le tableau nommé, indirectement.
#!/usr/bin/env bash
create_array() {
local -n arr=$1 # use nameref for indirection
arr=(one "two three" four)
}
use_array() {
local my_array
create_array my_array # call function to populate the array
echo "inside use_array"
declare -p my_array # test the array
}
use_array # call the main function
Produit la sortie:
inside use_array
declare -a my_array=([0]="one" [1]="two three" [2]="four")
Vous pouvez également faire en sorte que la fonction mette à jour un tableau existant:
update_array() {
local -n arr=$1 # use nameref for indirection
arr+=("two three" four) # update the array
}
use_array() {
local my_array=(one)
update_array my_array # call function to update the array
}
C'est une approche plus élégante et efficace car nous n'avons pas besoin de substitution de commande $()
pour saisir la sortie standard de la fonction en cours appelé. Il est également utile que la fonction retourne plusieurs sorties. Nous pouvons simplement utiliser autant de namerefs que le nombre de sorties.
Voici ce que Bash Manual à propos de nameref:
L'attribut nameref peut être affecté à une variable à l'aide de l'option -n des commandes intégrées declare ou locales (voir Intégrations Bash) pour créer un nom ou une référence à une autre variable. Ceci permet aux variables d'être manipulées indirectement. Chaque fois que la variable nameref est référencée, affectée, non définie ou que ses attributs sont modifiés (autre que l’utilisation ou la modification de l’attribut nameref lui-même), l’opération est effectivement effectuée sur la variable spécifiée par la valeur de la variable nameref. Un nameref est couramment utilisé dans les fonctions du shell pour faire référence à une variable dont le nom est transmis en tant qu'argument à la fonction. Par exemple, si un nom de variable est passé à une fonction Shell en tant que premier argument,
declare -n ref = $ 1 dans la fonction crée une variable de nommage ref dont la valeur est le nom de la variable transmis en tant que premier argument. Les références et les affectations à ref, ainsi que les modifications apportées à ses attributs, sont traitées comme des références, des affectations et des modifications d'attribut à la variable dont le nom a été passé en tant que $ 1.
Bash ne peut pas transmettre les structures de données en tant que valeurs de retour. Une valeur de retour doit être un état de sortie numérique compris entre 0 et 255. Cependant, vous pouvez certainement utiliser la substitution de commande ou de processus pour passer des commandes à une instruction eval si vous êtes tellement enclin.
Cela vaut rarement la peine, IMHO. Si vous devez transmettre des structures de données dans Bash, utilisez une variable globale - c'est ce à quoi elles servent. Cependant, si vous ne voulez pas faire cela pour une raison quelconque, pensez en termes de paramètres de position.
Votre exemple pourrait facilement être réécrit pour utiliser des paramètres de position au lieu de variables globales:
use_array () {
for idx in "$@"; do
echo "$idx"
done
}
create_array () {
local array=("a" "b" "c")
use_array "${array[@]}"
}
Tout cela crée cependant une certaine complexité inutile. Les fonctions Bash fonctionnent généralement mieux lorsque vous les traitez davantage comme des procédures avec des effets secondaires et que vous les appelez en séquence.
# Gather values and store them in FOO.
get_values_for_array () { :; }
# Do something with the values in FOO.
process_global_array_variable () { :; }
# Call your functions.
get_values_for_array
process_global_array_variable
Si tout ce qui vous préoccupe est de polluer votre espace de noms global, vous pouvez également utiliser le nset builtin pour supprimer une variable globale une fois que vous avez terminé. En vous servant de votre exemple d’origine, laissez ma_sélection être global (en supprimant le mot-clé local) et ajoutez unset my_list
à la fin de mon_algorithme à nettoyer après vous-même.
Utilisez la technique développée par Matt McClure: http://notes-matthewlmcclure.blogspot.com/2009/12/return-array-from-bash-function-v-2.html
Éviter les variables globales signifie que vous pouvez utiliser la fonction dans un canal. Voici un exemple:
#!/bin/bash
makeJunk()
{
echo 'this is junk'
echo '#more junk and "b@d" characters!'
echo '!#$^%^&(*)_^&% ^$#@:"<>?/.,\\"'"'"
}
processJunk()
{
local -a arr=()
# read each input and add it to arr
while read -r line
do
arr[${#arr[@]}]='"'"$line"'" is junk';
done;
# output the array as a string in the "declare" representation
declare -p arr | sed -e 's/^declare -a [^=]*=//'
}
# processJunk returns the array in a flattened string ready for "declare"
# Note that because of the pipe processJunk cannot return anything using
# a global variable
returned_string=`makeJunk | processJunk`
# convert the returned string to an array named returned_array
# declare correctly manages spaces and bad characters
eval "declare -a returned_array=${returned_string}"
for junk in "${returned_array[@]}"
do
echo "$junk"
done
La sortie est:
"this is junk" is junk
"#more junk and "b@d" characters!" is junk
"!#$^%^&(*)_^&% ^$#@:"<>?/.,\\"'" is junk
Vous n'étiez pas si loin avec votre solution d'origine. Vous avez eu quelques problèmes, vous avez utilisé une virgule comme séparateur et vous n'avez pas réussi à capturer les éléments retournés dans une liste. Essayez ceci:
my_algorithm() {
local result=( $(create_array) )
}
create_array() {
local my_list=("a" "b" "c")
echo "${my_list[@]}"
}
Considérant les commentaires sur les espaces incorporés, quelques ajustements utilisant IFS
peuvent résoudre ceci:
my_algorithm() {
oldIFS="$IFS"
IFS=','
local result=( $(create_array) )
IFS="$oldIFS"
echo "Should be 'c d': ${result[1]}"
}
create_array() {
IFS=','
local my_list=("a b" "c d" "e f")
echo "${my_list[*]}"
}
Cette approche implique les trois étapes suivantes:
myVar="$( declare -p myArray )"
declare -p
Peut être utilisée pour recréer le tableau. Par exemple, la sortie de declare -p myVar
Pourrait ressembler à ceci:declare -a myVar='([0]="1st field" [1]="2nd field" [2]="3rd field")'
${myVar#*=}
Exemple 1 - retourne un tableau d'une fonction
#!/bin/bash
# Example 1 - return an array from a function
function my-fun () {
# set up a new array with 3 fields - note the whitespaces in the
# 2nd (2 spaces) and 3rd (2 tabs) field
local myFunArray=( "1st field" "2nd field" "3rd field" )
# show its contents on stderr (must not be output to stdout!)
echo "now in $FUNCNAME () - showing contents of myFunArray" >&2
echo "by the help of the 'declare -p' builtin:" >&2
declare -p myFunArray >&2
# return the array
local myVar="$( declare -p myFunArray )"
local IFS=$'\v';
echo "${myVar#*=}"
# if the function would continue at this point, then IFS should be
# restored to its default value: <space><tab><newline>
IFS=' '$'\t'$'\n';
}
# main
# call the function and recreate the array that was originally
# set up in the function
eval declare -a myMainArray="$( my-fun )"
# show the array contents
echo ""
echo "now in main part of the script - showing contents of myMainArray"
echo "by the help of the 'declare -p' builtin:"
declare -p myMainArray
# end-of-file
Résultat de l'exemple 1:
now in my-fun () - showing contents of myFunArray
by the help of the 'declare -p' builtin:
declare -a myFunArray='([0]="1st field" [1]="2nd field" [2]="3rd field")'
now in main part of the script - showing contents of myMainArray
by the help of the 'declare -p' builtin:
declare -a myMainArray='([0]="1st field" [1]="2nd field" [2]="3rd field")'
Exemple 2 - passer un tableau à une fonction
#!/bin/bash
# Example 2 - pass an array to a function
function my-fun () {
# recreate the array that was originally set up in the main part of
# the script
eval declare -a myFunArray="$( echo "$1" )"
# note that myFunArray is local - from the bash(1) man page: when used
# in a function, declare makes each name local, as with the local
# command, unless the ‘-g’ option is used.
# IFS has been changed in the main part of this script - now that we
# have recreated the array it's better to restore it to the its (local)
# default value: <space><tab><newline>
local IFS=' '$'\t'$'\n';
# show contents of the array
echo ""
echo "now in $FUNCNAME () - showing contents of myFunArray"
echo "by the help of the 'declare -p' builtin:"
declare -p myFunArray
}
# main
# set up a new array with 3 fields - note the whitespaces in the
# 2nd (2 spaces) and 3rd (2 tabs) field
myMainArray=( "1st field" "2nd field" "3rd field" )
# show the array contents
echo "now in the main part of the script - showing contents of myMainArray"
echo "by the help of the 'declare -p' builtin:"
declare -p myMainArray
# call the function and pass the array to it
myVar="$( declare -p myMainArray )"
IFS=$'\v';
my-fun $( echo "${myVar#*=}" )
# if the script would continue at this point, then IFS should be restored
# to its default value: <space><tab><newline>
IFS=' '$'\t'$'\n';
# end-of-file
Résultat de l'exemple 2:
now in the main part of the script - showing contents of myMainArray
by the help of the 'declare -p' builtin:
declare -a myMainArray='([0]="1st field" [1]="2nd field" [2]="3rd field")'
now in my-fun () - showing contents of myFunArray
by the help of the 'declare -p' builtin:
declare -a myFunArray='([0]="1st field" [1]="2nd field" [2]="3rd field")'
function Query() {
local _tmp=`echo -n "$*" | mysql 2>> zz.err`;
echo -e "$_tmp";
}
function StrToArray() {
IFS=$'\t'; set $1; for item; do echo $item; done; IFS=$oIFS;
}
sql="SELECT codi, bloc, requisit FROM requisits ORDER BY codi";
qry=$(Query $sql0);
IFS=$'\n';
for row in $qry; do
r=( $(StrToArray $row) );
echo ${r[0]} - ${r[1]} - ${r[2]};
done
[ Remarque: Ce qui suit a été rejeté comme modification de cette réponse pour raisons qui n'ont aucun sens pour moi. (puisque l'édition était et non destinée à l'auteur ()), je prends donc la suggestion d'en faire une publication séparée répondre.]
Une implémentation plus simple de adaptation par Steve Zobell de la technique de Matt McClure utilise le bash intégré (depuis version == 4 ) readarray
comme suggéré RastaMatt pour créer une représentation d’un tableau pouvant être converti en tableau au moment de l’exécution. (Notez que readarray
et mapfile
nomment le même code.) Il évite toujours les globales (autorisant l'utilisation de la fonction dans un tube) et gère toujours les caractères désagréables.
Pour des exemples plus développés (par exemple, plus de modularisation) mais toujours un peu comme des jouets, voir bash_pass_arrays_between_functions . Vous trouverez ci-dessous quelques exemples faciles à exécuter, fournis ici pour éviter aux modérateurs de parler de liens externes.
Coupez le bloc suivant et collez-le dans un terminal bash pour créer /tmp/source.sh
et /tmp/junk1.sh
:
FP='/tmp/source.sh' # path to file to be created for `source`ing
cat << 'EOF' > "${FP}" # suppress interpretation of variables in heredoc
function make_junk {
echo 'this is junk'
echo '#more junk and "b@d" characters!'
echo '!#$^%^&(*)_^&% ^$#@:"<>?/.,\\"'"'"
}
### Use 'readarray' (aka 'mapfile', bash built-in) to read lines into an array.
### Handles blank lines, whitespace and even nastier characters.
function lines_to_array_representation {
local -a arr=()
readarray -t arr
# output array as string using 'declare's representation (minus header)
declare -p arr | sed -e 's/^declare -a [^=]*=//'
}
EOF
FP1='/tmp/junk1.sh' # path to script to run
cat << 'EOF' > "${FP1}" # suppress interpretation of variables in heredoc
#!/usr/bin/env bash
source '/tmp/source.sh' # to reuse its functions
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}"
# newline here ... just hit Enter ...
Courir /tmp/junk1.sh
: la sortie devrait être
this is junk
#more junk and "b@d" characters!
!#$^%^&(*)_^&% ^$#@:"<>?/.,\\"'
Remarque lines_to_array_representation
gère également les lignes vides. Essayez de coller le bloc suivant dans votre terminal bash:
FP2='/tmp/junk2.sh' # path to script to run
cat << 'EOF' > "${FP2}" # suppress interpretation of variables in heredoc
#!/usr/bin/env bash
source '/tmp/source.sh' # to reuse its functions
echo '`bash --version` the normal way:'
echo '--------------------------------'
bash --version
echo # newline
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 # newline
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 # newline
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 # newline
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}"
# newline here ... just hit Enter ...
Courir /tmp/junk2.sh
@ ligne de commande. Votre sortie devrait être semblable à la mienne:
`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!
Voici une solution sans références de tableau externes ni manipulation IFS:
# add one level of single quotes to args, eval to remove
squote () {
local a=("$@")
a=("${a[@]//\'/\'\\\'\'}") # "'" => "'\''"
a=("${a[@]/#/\'}") # add "'" prefix to each Word
a=("${a[@]/%/\'}") # add "'" suffix to each Word
echo "${a[@]}"
}
create_array () {
local my_list=(a "b 'c'" "\\\"d
")
squote "${my_list[@]}"
}
my_algorithm () {
eval "local result=($(create_array))"
# result=([0]="a" [1]="b 'c'" [2]=$'\\"d\n')
}
J'ai récemment découvert un problème dans BASH en ce sens qu'une fonction a un accès direct aux variables déclarées dans les fonctions situées plus haut dans la pile d'appels. Je viens tout juste de commencer à réfléchir à la façon d'exploiter cette fonctionnalité (elle promet à la fois des avantages et des dangers), mais une application évidente est une solution à l'esprit de ce problème.
Je préférerais également obtenir une valeur de retour plutôt que d'utiliser une variable globale lors de la délégation de la création d'un tableau. Ma préférence a plusieurs raisons, parmi lesquelles il faut éviter de perturber une valeur préexistante et d'éviter de laisser une valeur qui pourrait être invalide lors d'un accès ultérieur. Bien qu'il existe des solutions de contournement à ces problèmes, le plus simple est de laisser la variable hors de portée lorsque le code est terminé.
Ma solution garantit que le tableau est disponible lorsque cela est nécessaire et est ignoré lorsque la fonction est renvoyée, et laisse non perturbée une variable globale du même nom.
#!/bin/bash
myarr=(global array elements)
get_an_array()
{
myarr=( $( date +"%Y %m %d" ) )
}
request_array()
{
declare -a myarr
get_an_array "myarr"
echo "New contents of local variable myarr:"
printf "%s\n" "${myarr[@]}"
}
echo "Original contents of global variable myarr:"
printf "%s\n" "${myarr[@]}"
echo
request_array
echo
echo "Confirm the global myarr was not touched:"
printf "%s\n" "${myarr[@]}"
Lorsque function request_array appelle get_an_array , get_an_array peut définir directement la variable myarr qui est locale à request_array . Puisque myarr est créé avec declare
, il est local à request_array et sort donc de la portée lorsque request_array est renvoyé.
Bien que cette solution ne renvoie pas littéralement une valeur, je suggère que, dans son ensemble, elle satisfasse les promesses d'une valeur de retour de fonction vraie.
J'ai essayé diverses implémentations, et aucun tableau préservé contenant des éléments avec des espaces ... car ils devaient tous utiliser echo
.
# These implementations only work if no array items contain spaces.
use_array() { eval echo '(' \"\${${1}\[\@\]}\" ')'; }
use_array() { local _array="${1}[@]"; echo '(' "${!_array}" ')'; }
Puis je suis tombé sur réponse de Dennis Williamson . J'ai incorporé sa méthode dans les fonctions suivantes afin qu'elles puissent a) accepter un tableau arbitraire et b) être utilisées pour passer, dupliquer et ajouter des tableaux.
# Print array definition to use with assignments, for loops, etc.
# varname: the name of an array variable.
use_array() {
local r=$( declare -p $1 )
r=${r#declare\ -a\ *=}
# Strip keys so printed definition will be a simple list (like when using
# "${array[@]}"). One side effect of having keys in the definition is
# that when appending arrays (i.e. `a1+=$( use_array a2 )`), values at
# matching indices merge instead of pushing all items onto array.
echo ${r//\[[0-9]\]=}
}
# Same as use_array() but preserves keys.
use_array_assoc() {
local r=$( declare -p $1 )
echo ${r#declare\ -a\ *=}
}
Ensuite, d'autres fonctions peuvent renvoyer un tableau à l'aide d'une sortie capturable ou d'arguments indirects.
# catchable output
return_array_by_printing() {
local returnme=( "one" "two" "two and a half" )
use_array returnme
}
eval test1=$( return_array_by_printing )
# indirect argument
return_array_to_referenced_variable() {
local returnme=( "one" "two" "two and a half" )
eval $1=$( use_array returnme )
}
return_array_to_referenced_variable test2
# Now both test1 and test2 are arrays with three elements
J'avais besoin d'une fonctionnalité similaire récemment, alors voici un mélange des suggestions de RashaMatt et Steve Zobell .
Autant que je sache, les chaînes sont préservées et les espaces sont préservés.
#!bin/bash
function create-array() {
local somearray=("aaa" "bbb ccc" "d" "e f g h")
for elem in "${somearray[@]}"
do
echo "${elem}"
done
}
mapfile -t resa <<< "$(create-array)"
# quick output check
declare -p resa
Quelques autres variations…
#!/bin/bash
function create-array-from-ls() {
local somearray=("$(ls -1)")
for elem in "${somearray[@]}"
do
echo "${elem}"
done
}
function create-array-from-args() {
local somearray=("$@")
for elem in "${somearray[@]}"
do
echo "${elem}"
done
}
mapfile -t resb <<< "$(create-array-from-ls)"
mapfile -t resc <<< "$(create-array-from-args 'xxx' 'yy zz' 't s u' )"
sentenceA="create array from this sentence"
sentenceB="keep this sentence"
mapfile -t resd <<< "$(create-array-from-args ${sentenceA} )"
mapfile -t rese <<< "$(create-array-from-args "$sentenceB" )"
mapfile -t resf <<< "$(create-array-from-args "$sentenceB" "and" "this words" )"
# quick output check
declare -p resb
declare -p resc
declare -p resd
declare -p rese
declare -p resf
Cela peut aussi être fait simplement en passant une variable de tableau à la fonction et en assignant des valeurs de tableau à cette variable, puis en utilisant cette variable en dehors de la fonction. Par exemple.
create_array() {
local __resultArgArray=$1
local my_list=("a" "b" "c")
eval $__resultArgArray="("${my_list[@]}")"
}
my_algorithm() {
create_array result
echo "Total elements in the array: ${#result[@]}"
for i in "${result[@]}"
do
echo $i
done
}
my_algorithm
Si vos données source sont formatées avec chaque élément de la liste sur une ligne distincte, la commande intégrée mapfile
constitue un moyen simple et élégant de lire une liste dans un tableau:
$ list=$(ls -1 /usr/local) # one item per line
$ mapfile -t arrayVar <<<"$list" # -t trims trailing newlines
$ declare -p arrayVar | sed 's#\[#\n[#g'
declare -a arrayVar='(
[0]="bin"
[1]="etc"
[2]="games"
[3]="include"
[4]="lib"
[5]="man"
[6]="sbin"
[7]="share"
[8]="src")'
Notez que, comme avec read
intégré, vous ne devriez * normalement pas utiliser mapfile
dans un pipeline (ou sous-shell) car la variable de tableau affectée ne serait pas disponible pour les instructions suivantes (* sauf si le contrôle de travail bash est désactivé et shopt -s lastpipe
est réglé).
$ help mapfile
mapfile: mapfile [-n count] [-O Origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
Read lines from the standard input into an indexed array variable.
Read lines from the standard input into the indexed array variable ARRAY, or
from file descriptor FD if the -u option is supplied. The variable MAPFILE
is the default ARRAY.
Options:
-n count Copy at most COUNT lines. If COUNT is 0, all lines are copied.
-O Origin Begin assigning to ARRAY at index Origin. The default index is 0.
-s count Discard the first COUNT lines read.
-t Remove a trailing newline from each line read.
-u fd Read lines from file descriptor FD instead of the standard input.
-C callback Evaluate CALLBACK each time QUANTUM lines are read.
-c quantum Specify the number of lines read between each call to CALLBACK.
Arguments:
ARRAY Array variable name to use for file data.
If -C is supplied without -c, the default quantum is 5000. When
CALLBACK is evaluated, it is supplied the index of the next array
element to be assigned and the line to be assigned to that element
as additional arguments.
If not supplied with an explicit Origin, mapfile will clear ARRAY before
assigning to it.
Exit Status:
Returns success unless an invalid option is given or ARRAY is readonly or
not an indexed array.