J'essaye de faire quelques tours avec dd. J'ai pensé qu'il serait possible de stocker des valeurs hexadécimales dans une variable appelée "en-tête" pour la diriger vers dd.
Ma première étape sans variable a été la suivante:
$ echo -ne "\x36\xc9\xda\x00\xb4" |dd of=hex
$ hd hex
00000000 36 c9 da 00 b4 |6....|
00000005
Après cela, j'ai essayé ceci:
$ header=$(echo -ne "\x36\xc9\xda\x00\xb4")
$ echo -n $header | hd
00000000 36 c9 da b4 |6...|
00000004
Comme vous pouvez le voir, j'ai perdu ma \x00
valeur dans la $header
variable. Quelqu'un at-il une explication à ce comportement? Ça me rend fou.
linux
bash
shell-script
dd
Franc
la source
la source
bash: warning: command substitution: ignored null byte in input
.header="$(echo -ne "\x36\xc9\xda\x00\xb4")"; echo -n "$header" | hd
mais cela donne juste le même résultat.header="\x36\xc9\xda\x00\xb4"; echo -n "$header" | hd
, mais ce n'est pas la même chose que de stocker la forme lisible par l'homme.Réponses:
Vous ne pouvez pas stocker un octet nul dans une chaîne car Bash utilise des chaînes de style C, qui réservent l'octet nul aux terminateurs. Vous devez donc réécrire votre script pour simplement diriger la séquence qui contient l'octet nul sans que Bash ait besoin de le stocker au milieu. Par exemple, vous pouvez faire ceci:
Soit dit en passant, vous n'avez pas besoin
echo
; vous pouvez utiliser Bashprintf
pour de nombreuses autres tâches simples.Ou au lieu de chaîner, vous pouvez utiliser un fichier temporaire:
Bien sûr, cela a le problème que le fichier
/tmp/mysequence
existe peut-être déjà. Et maintenant, vous devez continuer à créer des fichiers temporaires et à enregistrer leurs chemins dans des chaînes.Ou vous pouvez éviter cela en utilisant la substitution de processus:
L'
<(command)
opérateur crée un canal nommé dans le système de fichiers, qui recevra la sortie decommand
.hd
recevra, comme premier argument, le chemin d'accès à ce canal, qu'il ouvrira et lira presque comme n'importe quel fichier. Vous pouvez en savoir plus à ce sujet ici: /unix//a/17117/136742 .la source
zsh
fera, mais uniquement en mode nōn-POSIX.) Je l'ai en fait examiné parce que je me demandais si cela valait la peine de l'implémenter dansmksh
…sh
émulation,\0
n'est pas dans la valeur par défaut de$IFS
.echo "$(printf 'a\0b')"
fonctionne toujours bien dans l'sh
émulationzsh
.Vous pouvez utiliser à la
zsh
place qui est le seul shell qui peut stocker le caractère NUL dans ses variables. Ce caractère se trouve même être dans la valeur par défaut de$IFS
inzsh
.Ou:
Ou
Ou
Cependant, notez que vous ne pouvez pas transmettre une telle variable en tant qu'argument ou variable d'environnement à une commande qui est exécutée car les arguments et les variables d'environnement sont des chaînes délimitées par NUL transmises à l'
execve()
appel système (une limitation de l'API du système, pas du shell ). Danszsh
, vous pouvez cependant passer des octets NUL comme arguments aux fonctions ou commandes intégrées.la source
zsh
syntaxe dans votre question.echo -n $header
signifier passer le contenu de la$header
variable comme dernier argument àecho -n
estzsh
(oufish
ourc
oues
) la syntaxe, pas labash
syntaxe. Dansbash
, cela a une signification très différente . Plus généralement,zsh
c'est commeksh
(bash
le shell GNU, étant plus ou moins un clone partielksh
du shell Unix de facto) mais avec la plupart des particularités de conception du shell Bourne corrigées (et beaucoup de fonctionnalités supplémentaires, et beaucoup plus convivial / moins étonnant).echo $(printf 'ab\0cd') | od -vAn -tx1c
imprime `61 62 20 63 64 0a`, c'est-à-dire un espace où un NUL devrait exister.