2

I have a self-extracting bash script (binary data appended to the end) like this:

#!/bin/bash export TMPDIR=$(mktemp -d) ARCHIVE_START_LINE=$(...) # <omitted> # extracting data archive into a temporary directory tail -n+$ARCHIVE_START_LINE $0 | tar xzv -C $TMPDIR # <ACCESSING_ARCHIVED_RESOURCES> exit 0 # <BINARY_DATA_ARCHIVE> 

The script is hosted remotely at https://<omitted>/script.sh

I want to pull the script and execute it locally.

As I'm using tail within the script passing it current file name as an argument, I cannot do:

/bin/bash -c "$(curl -fsSL https://<omitted>/script.sh)" 

Of course I can first save it into a temporary file, e.g.:

TMP=$(mktemp); curl -fsSL https://<omitted>/script.sh > $TMP; sh $TMP; rm $TMP 

But... any neater way?

5
  • 1
    I don't see how this could ever be possible without some file. Maybe some clever trick with a FiFo, but that's still a file. Why don't you store the binary data as a variable in the script and so avoid the need for tail? Wouldn't that be a decent solution? Commented Mar 29, 2024 at 18:23
  • 1
    Does storing it in a temporary file have awkward problems like it might be scanned by anti-malware software? Commented Mar 29, 2024 at 18:24
  • Why do not use "standard" shar file? mankier.com/1/shar Commented Mar 29, 2024 at 18:36
  • 1
    @AndrewMorton nothing too sinister - just an env setup script. :) It won't be catastrophic to download the file first and then run it locally. Just thought if I could maybe avoid it. I have very limited experience with bash and I wouldn't be surprised if it was something trivial. Commented Mar 30, 2024 at 11:51
  • @RomeoNinov I want the resulting script to both extract the archive and then run the scripts from that extracted archive. Seemed easiest to just write it from scratch. Commented Mar 30, 2024 at 11:57

1 Answer 1

0

I would just change the structure of the script slightly so you don't need tail. Just save the data as a variable instead:

#!/bin/bash ## begin data dump read -r -d '' archive_data <<'EoF' <BINARY_DATA_ARCHIVE> EoF ## end data dump export tmpdir=$(mktemp -d) # extracting data archive into a temporary directory printf '%s' "$archive_data" | tar xzv -C "$tmpdir" exit 0 

Comments:

  • This will not work if the data archive can contain NUL (\0).

  • Note the single quotes around 'EoF', these ensure that any $ won't be expanded to wrong variable names.

  • I also changed your variables to lower case as it is bad practice to use caps for shell variables since, by convention, global environment variables are capitalized and this can lead to naming collisions and unexpected bugs. Use lower case for your variables and capitalize global envs only whenever possible.

  • I changed mktemp to mktemp -d since you seem to be trying to create a directory and without -d the command mktemp makes a file.

You should now be able to do something like

curl -fsSL https://<omitted>/script.sh | bash 
4
  • What if the binary data contains null byte(s)? Will your method work? Commented Mar 29, 2024 at 20:12
  • Ah, very good point @KamilMaciorowski and no, I don't think it will work. I added a disclaimer, thanks. Commented Mar 29, 2024 at 20:14
  • Thanks for sharing, I tried this approach, but am getting an error trying to extract archive: "tar: Error opening archive: Unrecognized archive format". Seems I do indeed have some \0 in my data archive (i.sstatic.net/EBOdu.png), but why does it actually matter? Commented Mar 30, 2024 at 11:44
  • @EdwardRuchevits ah, if you have \0, those are removed by bash when assigning to a variable. Shell variables cannot contain nulls. Try var=$(printf 'a\0b') and then printf '%s\n' "$var" | od -c and you will see that $var is just ab with no \0. You'll also get an error message: "bash: warning: command substitution: ignored null byte in input". Commented Mar 30, 2024 at 14:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.