Skip to main content
added 198 characters in body
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441

You're running that command substitution with eval, so you get the quotes and escapedescapes processed twice.

Assuming byte=41 total=3, what eval sees is the arguments printf, \x41%0.s, 1, 2, 3. It concatenates them to printf \x41%0.s 1 2 3, which after escape processing runs printf with the four args x41%0.s, 1, 2, 3. (It should print x41x41x41, here.)

You could fix that by adding the correct amount of backslashes, but you probably also want to not use echo -e, since it'd only mess up the result if you were printing backslashes.


Anyway,

Unless you want to do it the hard way on purpose, it'd be easier to use some other tools than just the shell. E.g. you could use tr to get the byte you want, but it doesn't support hex escapes, only octal with \000, so there's the trouble of converting.

$ byte=41 count=15
$ printf "%${count}s" "" | tr ' ' "\\$(printf %o $((0x$byte)) )"
AAAAAAAAAAAAAAA

Or, you could use Perl:

$ perl -e 'print chr(hex($ARGV[0])) x $ARGV[1]' 41 15
AAAAAAAAAAAAAAA

You're running that command substitution with eval, so you get the quotes and escaped processed twice.

Assuming byte=41 total=3, what eval sees is the arguments printf, \x41%0.s, 1, 2, 3. It concatenates them to printf \x41%0.s 1 2 3, which after escape processing runs printf with the four args x41%0.s, 1, 2, 3. (It should print x41x41x41, here.)


Unless you want to do it the hard way on purpose, it'd be easier to use some other tools than just the shell. E.g. you could use tr to get the byte you want, but it doesn't support hex escapes, only octal with \000, so there's the trouble of converting.

$ byte=41 count=15
$ printf "%${count}s" "" | tr ' ' "\\$(printf %o $((0x$byte)) )"
AAAAAAAAAAAAAAA

Or, you could use Perl:

$ perl -e 'print chr(hex($ARGV[0])) x $ARGV[1]' 41 15
AAAAAAAAAAAAAAA

You're running that command substitution with eval, so you get the quotes and escapes processed twice.

Assuming byte=41 total=3, what eval sees is the arguments printf, \x41%0.s, 1, 2, 3. It concatenates them to printf \x41%0.s 1 2 3, which after escape processing runs printf with the four args x41%0.s, 1, 2, 3. (It should print x41x41x41, here.)

You could fix that by adding the correct amount of backslashes, but you probably also want to not use echo -e, since it'd only mess up the result if you were printing backslashes.


Anyway,

Unless you want to do it the hard way on purpose, it'd be easier to use some other tools than just the shell. E.g. you could use tr to get the byte you want, but it doesn't support hex escapes, only octal with \000, so there's the trouble of converting.

$ byte=41 count=15
$ printf "%${count}s" "" | tr ' ' "\\$(printf %o $((0x$byte)) )"
AAAAAAAAAAAAAAA

Or, you could use Perl:

$ perl -e 'print chr(hex($ARGV[0])) x $ARGV[1]' 41 15
AAAAAAAAAAAAAAA
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441

You're running that command substitution with eval, so you get the quotes and escaped processed twice.

Assuming byte=41 total=3, what eval sees is the arguments printf, \x41%0.s, 1, 2, 3. It concatenates them to printf \x41%0.s 1 2 3, which after escape processing runs printf with the four args x41%0.s, 1, 2, 3. (It should print x41x41x41, here.)


Unless you want to do it the hard way on purpose, it'd be easier to use some other tools than just the shell. E.g. you could use tr to get the byte you want, but it doesn't support hex escapes, only octal with \000, so there's the trouble of converting.

$ byte=41 count=15
$ printf "%${count}s" "" | tr ' ' "\\$(printf %o $((0x$byte)) )"
AAAAAAAAAAAAAAA

Or, you could use Perl:

$ perl -e 'print chr(hex($ARGV[0])) x $ARGV[1]' 41 15
AAAAAAAAAAAAAAA