J'ai cette chaîne multi-lignes (guillemets inclus):
abc'asdf"
$(dont-execute-this)
foo"bar"''
Comment pourrais-je l'affecter à une variable en utilisant un hérédoc dans Bash?
Je dois préserver les nouvelles lignes.
Je ne veux pas échapper aux caractères de la chaîne, ce serait ennuyeux ...
'EOF'
, avec des sauts de ligne échappés avec la` in the content: if the second line has
commande cd`, je reviens: " .sh: ligne X: cd: commande introuvable "; mais si je cite deux fois"EOF"
; alors les variables bash${A}
ne sont pas conservées sous forme de chaînes (elles sont développées); mais ensuite, les sauts de ligne sont préservés - et, je n'ai aucun problème à exécuter une commande aveccd
en deuxième ligne ( et les deux 'EOF' et "EOF" semblent bien fonctionner également aveceval
, pour exécuter un ensemble de commandes stockées dans une variable chaîne ). À votre santé!"EOF"
variable double-qouted , s'ils sont appelés viaeval $VAR
, feront commenter tout le reste du script, car ici $ VAR sera vu comme une seule ligne ; pour pouvoir utiliser les#
commentaires bash dans un script multiligne, double-quote aussi variable dans l'eval call:
eval "$ VAR" `.eval
cette méthode, mais je ne l'ai pas retrouvée car elle faisait partie d'un paqueteval
contenant des variables définies dans son fichier de configuration. Message d'erreur était:/usr/lib/network/network: eval: line 153: syntax error: unexpected end of file
. Je viens de passer à une autre solution.Réponses:
Vous pouvez éviter une utilisation inutile
cat
et mieux gérer les citations incompatibles avec ceci:Si vous ne citez pas la variable lorsque vous l'échoz, les sauts de ligne sont perdus. Le citer les conserve:
Si vous souhaitez utiliser l'indentation pour la lisibilité dans le code source, utilisez un tiret après les moins. L'indentation doit être effectuée en utilisant uniquement des tabulations (pas d'espaces).
Si, à la place, vous souhaitez conserver les onglets dans le contenu de la variable résultante, vous devez supprimer l'onglet de
IFS
. Le marqueur terminal pour ici doc (EOF
) ne doit pas être mis en retrait.Des onglets peuvent être insérés sur la ligne de commande en appuyant sur Ctrl- V Tab. Si vous utilisez un éditeur, selon celui-ci, cela peut également fonctionner ou vous devrez peut-être désactiver la fonctionnalité qui convertit automatiquement les tabulations en espaces.
la source
set -o errexit
(akaset -e
) dans votre script et que vous l'utilisez, il terminera votre script carread
retourne un code retour non nul lorsqu'il atteindra EOF.set -e
et déconseille toujours son utilisation. Il est préférable d'utiliser à la place une gestion des erreurs appropriée.trap
est votre ami. Autres amis:else
et||
entre autres.cat
peine en vaut-il vraiment la peine dans un tel cas? Assigner un hérédoc à une variable aveccat
est un idiome bien connu. En quelque sorte en utilisantread
obscurcit les choses pour de petits avantages à mon humble avis.d
et la chaîne vide;bash
s'effondre-rd''
simplement-rd
avant deread
voir ses arguments, ilVAR
est donc traité comme l'argument de-d
.read
reviendra avec un code de sortie différent de zéro. Cela rend cette méthode loin d'être idéale dans un script avec vérification des erreurs activée (par exempleset -e
).Utilisez $ () pour affecter la sortie de
cat
à votre variable comme ceci:Assurez-vous de délimiter le début END_HEREDOC avec des guillemets simples.
Notez que la fin du délimiteur hérédoc
END_HEREDOC
doit être seul sur la ligne (par conséquent, la parenthèse de fin se trouve sur la ligne suivante).Grâce à
@ephemient
pour la réponse.la source
echo "$VAR"
au lieu deecho $VAR
.ash
et OpenWRT oùread
ne prend pas en charge-d
.il s'agit d'une variante de la méthode Dennis, plus élégante dans les scripts.
définition de la fonction:
usage:
prendre plaisir
ps a fait une version en «boucle de lecture» pour les shells qui ne sont pas compatibles
read -d
. devrait travailler avecset -eu
et contre - apostrophes non appariés , mais pas testé très bien:la source
read
boucle dans la fonction, pour éviter le-d ''
bashisme nécessaire pour préserver les retours à la ligne).set -e
set, contrairement à la réponse sélectionnée. Il semble que ce soit à cause dehttp://unix.stackexchange.com/a/265151/20650
ne fonctionne pas parce que vous redirigez stdin vers quelque chose qui ne vous intéresse pas, à savoir l'affectation
fonctionne, mais il y a un back-tic là-dedans qui peut vous empêcher d'utiliser cela. De plus, vous devriez vraiment éviter d'utiliser des backticks, il est préférable d'utiliser la notation de substitution de commande
$(..)
.la source
$(cat <<'END'
plutôt. @Neil: La toute dernière nouvelle ligne ne fera pas partie de la variable, mais le reste sera conservé.echo "$A"
(c'est-à-dire en mettant $ A entre guillemets) et vous voyez les nouvelles lignes!REM=<< 'REM' ... comment block goes here ... REM
. Ou plus compacte,: << 'REM' ...
. Où "REM" pourrait être quelque chose comme "NOTES" ou "SCRATCHPAD", etc.Ce n'est pas vrai - vous êtes probablement juste trompé par le comportement de l'écho:
echo $VAR # strips newlines
echo "$VAR" # preserves newlines
la source
En dérivant la réponse de Neil , vous n'avez souvent pas besoin de var du tout, vous pouvez utiliser une fonction de la même manière qu'une variable et c'est beaucoup plus facile à lire que les
read
solutions en ligne ou basées.la source
Un tableau est une variable, donc dans ce cas, le mapfile fonctionnera
Ensuite, vous pouvez imprimer comme ceci
la source
affecter une valeur hérédoc à une variable
utilisé comme argument d'une commande
la source
echo "$VAR"
Je me suis retrouvé à devoir lire une chaîne contenant NULL, alors voici une solution qui lira tout ce vous lui lancerez. Bien que si vous avez réellement affaire à NULL, vous devrez vous en occuper au niveau hexadécimal.
$ cat> read.dd.sh
Preuve:
Exemple HEREDOC (avec ^ J, ^ M, ^ I):
la source
Merci à la réponse de dimo414 , cela montre comment fonctionne sa grande solution et montre que vous pouvez également avoir facilement des guillemets et des variables dans le texte:
exemple de sortie
test.sh
la source
la source