2

Ultimately my goal is to convert a hexdump of data to the correct floating point value. I have set up my shell script to isolate the individual hex values I need to look at and arrange them in the correct order for a little Endian float conversion.

To simplify everything, I'll bypass the code I have managed to get working, and I'll start with:

rawHex=0x41000000
echo $(perl -e 'print unpack "f", pack "L", $ENV{rawHex}')

When I execute this code, the result is 0. However if I were to execute the code without attempting to pull the value of the shell variable:

echo $(perl -e 'print unpack "f", pack "L", 0x41000000')

The result is 8, which is what I am expecting.

I'd appreciate any help on how I can update my Perl expression to properly interpret the value of the shell variable. Thanks.

Dan
  • 53
  • 4
  • 1
    The variable you define in the shell is "local," not an "environment" variable so it isn't seen by `%ENV`. You need to "export" it, `export rawHex=...` (or just `export rawHex` if it's already been set up). Now `%ENV` will have it. (Alternatively, you can pass it to your Perl command-line program, as a command line argument or a switch) – zdim Nov 13 '19 at 23:41
  • I attempted to verify that the variable was accessible this way by evaluating:```echo $(perl -e 'print $ENV{rawHex}')``` and the result was 0x41000000 as expected. – Dan Nov 13 '19 at 23:47
  • See [this post](https://stackoverflow.com/a/55753111/4653379) for the explanation and then [this one](https://stackoverflow.com/a/58705112/4653379) (with its links) should be useful, too – zdim Nov 13 '19 at 23:50
  • (to round off these comments: you also need [hex](https://perldoc.perl.org/functions/hex.html). It's now all done in ikegami's answer) – zdim Nov 14 '19 at 07:02

2 Answers2

5
export rawHex=0x41000000
perl -le'print unpack "f", pack "L", hex($ENV{rawHex})'

As you discovered, your code isn't equivalent to the following:

perl -e 'print unpack "f", pack "L", 0x41000000'

Your code is equivalent to the following:

perl -e 'print unpack "f", pack "L", "0x41000000"'

Like "0x41000000", $ENV{rawHex} produces the string 0x41000000. On the other hand, 0x41000000 produces the number one billion, ninety million, five hundred nineteen thousand and forty.

To convert the hex representation of a number into the number it represents, one uses hex. Simply replace $ENV{rawHex} with hex($ENV{rawHex}).

export rawHex=0x41000000
perl -le'print unpack "f", pack "L", hex($ENV{rawHex})'

The -l causes a line feed to be added to the output so you don't need to use echo. Feel free to remove the l if you're not actually using echo

Generating code (as suggested in the earlier answer) is a horrible practice.

ikegami
  • 367,544
  • 15
  • 269
  • 518
1

A working solution is

rawHex=0x41000000
echo $(perl -e "print unpack 'f', pack 'L', ${rawHex}")

Your code has two problems. The first is that in bash, variables between single quotes ' will not be evaluated. That's why I inverted single and double quotes in your example.

The second problem is the use of ENV. I am not sure why you use it, but you don't need it.

Michele Dorigatti
  • 811
  • 1
  • 9
  • 17
  • I had tried a permutation of this, but I had an unnecessary set of parentheses, and it was not returning a consistent result. Now that I've removed the parentheses, it's working. Thank you! – Dan Nov 13 '19 at 23:35
  • Remember to accept my answer if it solved your problem ;) – Michele Dorigatti Nov 13 '19 at 23:35
  • 2
    While this is correct technically (it'll work) I'll have to speak against "injection" -- it opens the whole (Perl one-line) script to who-knows-what. There are other ways to pass a shell variable to a program, one by `export`-ing whereby it becomes an "environment" variable and can be accessed in `%ENV` – zdim Nov 13 '19 at 23:43
  • 1
    Re "*variables between single quotes ' will not be evaluated.*", That's a good thing. Generating code is not a good idea. – ikegami Nov 14 '19 at 00:54