J'ai une fonction bash qui prend un fichier en paramètre, vérifie que le fichier existe, puis écrit tout ce qui sort de stdin dans le fichier. La solution naïve fonctionne bien pour le texte, mais j'ai des problèmes avec les données binaires arbitraires.
echo -n '' >| "$file" #Truncate the file
while read lines
do # Is there a better way to do this? I would like one...
echo $lines >> "$file"
done
> $file
. Cela ne fonctionne que comme la première chose qui recherche stdin dans le script shell parent. Fondamentalement, tout le code de David peut être réduit à un seul caractère, mais je pense quecat -
c'est plus élégant et moins difficile à comprendre car il est compris à vue.cat
s ensemble, juste pour agacer les fanatiques de l'UUOCcat
juste pour que les gens qui insistent pour l'utiliser doivent nécessairement faire de la gymnastique mentale pour lire le code. Les pipes nommées sont également de bonnes cibles.Pour lire un fichier texte littéralement, n'utilisez pas plain
read
, qui traite la sortie de deux manières:read
interprète\
comme un personnage d'échappement; utiliserread -r
pour désactiver cette fonction.read
se divise en mots sur les caractères en$IFS
; définiIFS
sur une chaîne vide pour désactiver cette option.L'idiome habituel pour traiter un fichier texte ligne par ligne est
Pour une explication de cet idiome, voir Pourquoi est-il
while IFS= read
utilisé si souvent au lieu deIFS=; while read..
? .Pour écrire une chaîne littéralement, n'utilisez pas simplement plain
echo
, qui traite la chaîne de deux manières:echo
processus anti-slash s'échappent. (Sur bash, cela dépend si l'xpg_echo
option est définie.)-n
ou-e
(l'ensemble exact dépend du shell).Une façon portable d'imprimer une chaîne est littéralement avec
printf
. (Il n'y a pas de meilleur moyen en bash, sauf si vous savez que votre entrée ne ressemble pas à une optionecho
.) Utilisez le premier formulaire pour imprimer la chaîne exacte, et le second formulaire si vous souhaitez ajouter une nouvelle ligne.Cela ne convient que pour le traitement de texte , car:
Vous ne pouvez pas traiter les données binaires dans le shell, mais les versions modernes des utilitaires sur la plupart des unités peuvent gérer des données arbitraires. Pour passer toutes les entrées à la sortie, utilisez
cat
. Aller sur une tangente,echo -n ''
est une façon compliquée et non portable de ne rien faire;echo -n
serait tout aussi bon (ou non selon le shell), et:
est plus simple et entièrement portable.ou, plus simple,
Dans un script, vous n'avez généralement pas besoin d'utiliser
>|
car ilnoclobber
est désactivé par défaut.la source
Cela fera exactement ce que vous voulez:
Notez cependant l'utilisation de la mémoire. Cela lit l'entrée d'une manière délimitée par des valeurs nulles.
S'il n'y a pas d' octets
\0
nuls dans l'entrée, bash devra d'abord lire l'intégralité du contenu de l'entrée en mémoire, puis le sortir.Concernant votre étape tronquée:
beaucoup plus simple et équivalent est:
la source