Deux écueils importants
qui ont été ignorées par d'autres réponses jusqu'à présent:
- Suppression de la nouvelle ligne de fin de l'extension de commande
- Suppression de caractère NUL
Suppression de la nouvelle ligne de fin de l'extension de commande
C'est un problème pour:
value="$(cat config.txt)"
solutions de type, mais pas pour les read
solutions basées.
L'expansion de la commande supprime les nouvelles lignes de fin:
S="$(printf "a\n")"
printf "$S" | od -tx1
Les sorties:
0000000 61
0000001
Cela rompt la méthode naïve de lecture à partir de fichiers:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
Solution de contournement POSIX: ajoutez un caractère supplémentaire à l'extension de commande et supprimez-le ultérieurement:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Les sorties:
0000000 61 0a 0a
0000003
Solution de contournement presque POSIX: encodage ASCII. Voir ci-dessous.
Suppression de caractère NUL
Il n'y a aucun moyen sain et simple de stocker des caractères NUL dans des variables .
Cela affecte à la fois l'expansion et les read
solutions, et je ne connais pas de bonne solution de contournement.
Exemple:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Les sorties:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ha, notre NUL est parti!
Solutions de contournement:
Encodage ASCII. Voir ci-dessous.
utilisez les $""
littéraux d' extension bash :
S=$"a\0b"
printf "$S" | od -tx1
Fonctionne uniquement pour les littéraux, donc pas utile pour lire à partir de fichiers.
Solution aux écueils
Stockez une version encodée en uuencode base64 du fichier dans la variable et décodez avant chaque utilisation:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Production:
0000000 61 00 0a
0000003
uuencode et udecode sont POSIX 7 mais pas dans Ubuntu 12.04 par défaut ( sharutils
package) ... Je ne vois pas d'alternative POSIX 7 pour l' <()
extension de substitution de processus bash sauf pour écrire dans un autre fichier ...
Bien sûr, cela est lent et peu pratique, donc je suppose que la vraie réponse est: n'utilisez pas Bash si le fichier d'entrée peut contenir des caractères NUL.
cat
ou$(<someFile)
se traduira par une sortie incomplète ( la taille est inférieure à celle du fichier réel).