Reputation: 563
i want to write a bash script to echo a shape(heart) that made of strings and draw it in Terminal. like this picture: i find a bash script but it didn't work.
echo '\x1f\x8b\x08\x00\x95\x10\xe0R\x02\xffSPP\xf0\xc9/KU\x80\x03\x10\x8f\x0bB\xa1c.l\x82dJ\xe0\xb0\x01\xe6\x02\x0cATa.T\xf7\x02\x00\xd9\x91g\x05\xc5\x00\x00\x00'|gunzip
i find above code and tried it, but it didn't work.
Upvotes: 2
Views: 9569
Reputation: 35006
Following up my earlier comment (not sure how to convert a *gz file to a hex string) ...
I found I can do something similar with base64
with the idea being that the base-64 string is going to be easier to work with (ymmv).
Create a file with the desired text 'image', eg:
$ cat heart
Love Love
LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLove
LoveLoveLoveLove
LoveLoveLove
Love
Run the file through base64
to generate a base-64 (as opposed to hex==base-16) string representing the contents of the file, eg:
$ base64 heart
ICAgTG92ZSAgICAgICAgICBMb3ZlCiAgTG92ZUxvdmVMb3ZlTG92ZUxvdmUKTG92ZUxvdmVMb3ZlTG92ZUxvdmVMb3ZlCkxvdmVMb3ZlTG92ZUxvdmVMb3ZlTG92ZQpMb3ZlTG92ZUxvdmVMb3ZlTG92ZUxvdmUKICBMb3ZlTG92ZUxvdmVMb3ZlTG92ZQogICAgTG92ZUxvdmVMb3ZlTG92ZQogICAgICBMb3ZlTG92ZUxvdmUKICAgICAgICAgIExvdmUK
At this point you can use following modified command to echo
the above string and then pipe it through base64 -d
(ie, replace `gunzip), eg:
$ echo "ICAgTG92ZSAgICAgICAgICBMb3ZlCiAgTG92ZUxvdmVMb3ZlTG92ZUxvdmUKTG92ZUxvdmVMb3ZlTG92ZUxvdmVMb3ZlCkxvdmVMb3ZlTG92ZUxvdmVMb3ZlTG92ZQpMb3ZlTG92ZUxvdmVMb3ZlTG92ZUxvdmUKICBMb3ZlTG92ZUxvdmVMb3ZlTG92ZQogICAgTG92ZUxvdmVMb3ZlTG92ZQogICAgICBMb3ZlTG92ZUxvdmUKICAgICAgICAgIExvdmUK=" | base64 -d
Love Love
LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLove
LoveLoveLoveLove
LoveLoveLove
Love
NOTE: base64 -d
== convert from base-64 to the original contents of the file.
For a smaller string you can gzip
the heart
file first and then run the *gz file through base64
, eg:
$ gzip heart
=> generates file heart.gz
$ base64 heart.gz
H4sICHSiC14AA2hlYXJ0AFNQUPDJL0tVgAMQjwtCoWMubIJkSuCwAeYCDEFUYS409wIAcgvdzcYAAAA=
Then to get back to the image we have to run the steps in reverse:
echo "H4sICHSiC14AA2hlYXJ0AFNQUPDJL0tVgAMQjwtCoWMubIJkSuCwAeYCDEFUYS409wIAcgvdzcYAAAA=" | base64 -d | gunzip
Love Love
LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLove
LoveLoveLoveLove
LoveLoveLove
Love
Upvotes: 3
Reputation: 35006
Background:
Someone created a text file with the textual image of the heart; let's call the file heart
.
Then they (likely) zipped the file with gzip
, eg: gzip heart
which generated the file heart.gz
.
At this point if you ran the file through gunzip
and dumped the results to stdout you'd get:
$ gunzip -c heart.gz
Love Love
LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLove
LoveLoveLoveLove
LoveLoveLove
Love
You could also generate the same results by cat
ing the heart.gz
and then piping the output to gunzip
, eg:
$ cat heart.gz | gunzip
Love Love
LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLove
LoveLoveLoveLove
LoveLoveLove
Love
Current question:
Instead of uploading the heart.gz
file and then requiring the download of said file, the originator (in essence) converted heart.gz
to its equivalent string of hex codes. This eliminated the need to upload the heart.gz
file.
Now, intead of running the file (heart.gz
) through gunzip
, the user can echo
the hex string to stdout (basically generate the same output as cat heart.gz
), which is then piped to gunzip
, with the net result that the command you're asking about should generate the image in question:
$ echo '\x1f\x8b\x08\x00\x95\x10\xe0R\x02\xffSPP\xf0\xc9/KU\x80\x03\x10\x8f\x0bB\xa1c.l\x82dJ\xe0\xb0\x01\xe6\x02\x0cATa.T\xf7\x02\x00\xd9\x91g\x05\xc5\x00\x00\x00'|gunzip
Love Love
LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLove
LoveLoveLoveLove
LoveLoveLove
Love
NOTE: echo
may not work exactly right depending on your version of echo
, so you may need to use echo -e
(as per Cyrus comment) or replace echo
with printf
(as per that other guy's answer).
Upvotes: 1
Reputation: 123570
It's tricky to get exact binary output with echo
because implementations differ a lot.
In bash, you can instead do this with printf
(other shells vary because \x
escapes are not portable):
$ printf '\x1f\x8b\x08\x00\x95\x10\xe0R\x02\xffSPP\xf0\xc9/KU\x80\x03\x10\x8f\x0bB\xa1c.l\x82dJ\xe0\xb0\x01\xe6\x02\x0cATa.T\xf7\x02\x00\xd9\x91g\x05\xc5\x00\x00\x00'|gunzip
Love Love
LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLove
LoveLoveLoveLove
LoveLoveLove
Love$
Note that the compressed contents is not linefeed terminated, so the next prompt will appear on top of the heart.
Upvotes: 2