Comment attribuer une heredoc valeur à une variable en Bash?
J'ai cette multi-ligne de chaîne (guillemets compris):
abc'asdf"
$(dont-execute-this)
foo"bar"''
Comment aurais-je l'attribuer à une variable à l'aide d'un heredoc en Bash?
J'ai besoin de conserver les retours à la ligne.
Je ne veux pas échapper les caractères dans la chaîne, ce serait ennuyeux...
- J'ai juste essayé une heredoc cession avec une seule cité
'EOF'
, avec échappé retours à la ligne (avec` in the content: if the second line has
cd commande, j'obtiens en retour: ".sh: ligne X: cd: command not found"; mais si je double-quote"EOF"
; puis des variables bash${A}
ne pas être préservé comme des chaînes de caractères (ils se élargie); mais ensuite, des sauts de lignes sont préservées et, je n'ai pas de problème d'exécution d'une commande aveccd
en deuxième ligne (et à la fois des "expressions du FOLKLORE" et "expressions du FOLKLORE" semblent bien jouer aussi aveceval
, pour l'exécution d'un ensemble de commandes stockées dans une variable de type string). Cheers! - ... et pour ajouter à mon commentaire précédent: bash commentaires "#" en double-qouted
"EOF"
variable, si elle est appelée pareval $VAR
, seront la cause de tout le reste du script à être commentée, comme ici, $VAR sera considéré comme une seule ligne; pour être en mesure d'utiliser bash#
commentaires multilignes script, double-quote également variable dans leeval call:
eval "$VAR"`. - J'ai eu des problèmes avec
eval
ith cette méthode, mais qui n'a pas suivi vers le bas comme elle faisait partie d'un paquet quieval
s certaines variables définies dans le fichier config. Message d'erreur était:/usr/lib/network/network: eval: line 153: syntax error: unexpected end of file
. J'ai tout juste de passer à une autre solution.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez éviter une inutile l'utilisation de
cat
et poignée incompatibles citations mieux avec cette:Si vous ne citez pas la variable lorsque vous faites l'écho, les retours à la ligne sont perdues. Citant les conserve:
Si vous souhaitez utiliser l'indentation pour des raisons de lisibilité dans le code source, utilisez un tiret après le moins thans. Le retrait doit être fait en utilisant uniquement les onglets (pas d'espaces).
Si, au lieu de cela, vous voulez préserver les onglets dans le contenu de la variable qui en découle, vous devez supprimer l'onglet de
IFS
. Le terminal de marqueur pour la doc ici (EOF
) ne doit pas être en retrait.Onglets peuvent être insérés à la ligne de commande en appuyant sur Ctrl-V Tab. Si vous utilisez un éditeur, en fonction de celui qui, qui peut également fonctionner ou vous devrez peut-être désactiver la fonction qui convertit automatiquement les tabulations en espaces.
-r
option pour conserver les barres obliques inverses ainsi.read
doivent presque toujours-r
. J'ai oublié de l'inclure (fixe).set -o errexit
(un.k.unset -e
) dans votre script et que vous utilisez ce, alors il sera de mettre fin à votre script carread
renvoie une valeur non nulle code de retour quand elle atteint les expressions du FOLKLORE.set -e
et recommande toujours à l'encontre de son utilisation. Il est préférable d'utiliser la bonne gestion d'erreur à la place.trap
est votre ami. D'autres amis:else
et||
parmi d'autres.-d
paramètre surread
? Je suis coincé à l'aide d'un environnement qui n'ont pas la-d
option, mais je ne peux pas trouver une autre façon d'obtenir desread
pour charger plusieurs lignes sans elle.cat
vraiment la peine dans ce cas? L'affectation d'un heredoc à une variable decat
est bien connu de l'idiome. En quelque sorte, à l'aide deread
dissimule des choses pour peu d'avantages à mon humble avis.read -rd'' VAR << EOF
ne fonctionne pas, carVAR
sera analysé dans le séparateur (et le heredoc finira dans$REPLY
).d
et la chaîne vide;bash
s'effondre-rd''
simplement-rd
avantread
voit jamais de ses arguments, de sorteVAR
est traitée comme argument de-d
.read
sera de retour avec un code de sortie non nulle. Ce qui rend cette méthode de moins que l'idéal dans un script avec la vérification des erreurs est activé (par exempleset -e
).set -e
ne doit jamais être utilisé - faire une vérification d'erreur à la placeread
(2) pour chaque 1 octet dans le document.$?
== 1 après l'exécution deIFS='' read -r -d '' VAR <<'EOF'
même s'il consomme un "expressions du FOLKLORE" au début de la ligne? Aucun moyen de contourner cela?trap
ing trop d'erreurs, lorsque vous travaillez sur un code partagé de la base, il n'est pas poli de modification à une norme (comme#!/bin/bash -eu
). Donc, j'ai ajouté une note à la fin de cette excellente réponse.-r -d
? Je ne pouvais pas trouver dansman read
. Exemple 3 a bien fonctionné dans mon cas.read
est un Bash builtin et vous pouvez obtenir des informations à ce sujet à l'aide dehelp read
ouman bash
. L'option-r
est d'accepter les barres obliques inverses, littéralement, au lieu de les utiliser pour échapper tous les caractères. Le-d
option définit le premier caractère de l'argument comme délimiteur entre les enregistrements (lignes) au lieu de la valeur par défaut qui est de retour à la ligne. Dans l'exemple, je suis le délimiteur à une chaîne nulle.read
saufIFS=
.Utiliser $() pour affecter la sortie de
cat
à votre variable comme ceci:Veillant à délimiter départ END_HEREDOC avec des guillemets simples.
Note que la fin de l'heredoc délimiteur
END_HEREDOC
doit être seul sur la ligne (d'où parenthèse de fin est sur la ligne suivante).Grâce à
@ephemient
pour la réponse.echo "$VAR"
au lieu deecho $VAR
.ash
et OpenWRT oùread
ne prend pas en charge-d
.set -e
.$(cat)
et appuyez sur Ctrl-D pour envoyer un EOF. Cela a l'avantage de permettre la "END_HEREDOC" pour éventuellement se produire dans le texte.'END_HEREDOC'
?read
est intégrée à Bash et pas forcément compatible avec Zsh.$(cat <<-'}'
-- fin avec indenté}
, suivie par)
sur la ligne suivante.c'est la variation de Dennis méthode, semble plus élégant dans les scripts.
définition de la fonction:
utilisation:
profiter de
p.s. faites un "lecture en boucle" en version pour les coques qui ne prennent pas en charge
read -d
. devrait fonctionner avecset -eu
et non appariés backticks, mais pas testé très bien:read
boucle dans la fonction, afin d'éviter la-d ''
bashism nécessaire pour conserver les retours à la ligne).set -e
ensemble, alors que la réponse choisie n'est pas. Il semble être à cause dehttp://unix.stackexchange.com/a/265151/20650
read
boucle ressemblent effectivement à éviter la-d ''
? Depuis la belle réponse de l'OP n'est certainement pas de travailler sur AIX.L'ajout de commentaire ici comme une réponse étant donné que je n'ai pas assez de points de rep pour commenter votre texte de la question.
Ce n'est pas vrai, vous êtes probablement juste d'être induit en erreur par le comportement de l'écho:
echo $VAR # strips newlines
echo "$VAR" # preserves newlines
ne fonctionne pas parce que vous êtes rediriger stdin pour quelque chose qui ne se soucie pas d'elle, à savoir la cession
fonctionne, mais il y a un arrière-tic qui peut vous arrêter de l'utilisation de ce. Aussi, vous devriez vraiment éviter d'utiliser des backticks, il est préférable d'utiliser la substitution de commande notation
$(..)
.$(cat <<'END'
à la place. @Neil: Le dernier saut de ligne ne fera pas partie de la variable, mais le repos sera préservé.echo "$A"
(c'est à dire de mettre $A dans les guillemets) et vous faire voir les retours à la ligne!export A=$(<<END ... END)
fonctionne tout aussi bien, avec moins de processus en cours d'exécution.REM=<< 'REM' ... comment block goes here ... REM
. Ou de manière plus compacte,: << 'REM' ...
. Où "REM" pourrait être quelque chose comme "NOTES" ou "BLOC-notes", etc.Bifurquant Neil réponse, souvent, vous n'avez pas besoin d'une var à tous, vous pouvez utiliser une fonction de la même façon qu'une variable, et il est beaucoup plus facile à lire que la ligne ou
read
de solutions à base d'.Un tableau est une variable, donc dans ce cas mapfile travaillera
Vous pouvez ensuite les imprimer comme ce
attribuer un heredoc valeur à une variable
utilisé comme un argument d'une commande
echo "$VAR"
Je me suis trouvé avoir à lire une chaîne de caractères avec la valeur NULL, alors voici une solution qui va lire rien vous jeter à elle. Bien que si vous avez fait affaire avec des valeurs NULL, vous aurez besoin pour faire face à l'hex de niveau.
$ cat > read.dd.sh
Preuve:
HEREDOC exemple (avec ^J, ^M, ^I):
Grâce à dimo414 réponse, cela montre comment sa grande solution fonctionne, et montre que vous pouvez avoir des devis et des variables dans le texte facilement ainsi:
exemple de sortie
test.sh