0

I have multiple bash scripts and resources required by these scripts (like music files and images) and I want to pack them all into one executable file.

For example:

$ find Scripts/

Scripts/
Scripts/main.sh
Scripts/bin/1.sh
Scripts/bin/2.sh
Scripts/src/music.mp3

Now, I want to pack all these into one executable which if I execute, executes the Scripts/main.sh file.

How can I do that?

3
  • How does one script (e.g. main.sh) call or source another? If by its absolute path then there's a problem; If by its relative path then there's another problem. If by $PATH then another. One solution I can think of is refactoring code, so dependent files just define shell functions, main.sh sources them all and uses the functions. Then it's relatively easy to replace . …/source … with actual content (definitions) to get one big standalone main.sh. Oct 5, 2022 at 15:08
  • Does this post using 7Zip solve your problem?
    – harrymc
    Oct 5, 2022 at 15:46
  • What is the motivation here? It is for distributing the "package" in one file that the user just has to execute? Other?
    – PierU
    Oct 5, 2022 at 16:44

1 Answer 1

2

One way is to use the Shell Archive (shar) utility. It is maybe not installed by default, but likely present in the repository of your distribution.

Very much like tar it can create an single-file archive of a list of files. The difference is that the archive file is self-extracting: this is a shell script that has to be run.

In your case :

shar -M -D -Q Scripts/ > myarchive.sh packs the whole Scripts/ folder into myarchive.sh.

Then you can pass myarchive.sh to someone else. By running sh myarchive.sh he will locally unpack Scripts/ and all its content.

But this is not enough, as you also want to execute Scripts/main.sh . You have then to add this command at the end of myarchive.sh, and the full command is:

shar -M -D -Q Scripts/ | head -n -1 > myarchive.sh && echo "Scripts/main.sh" >> myarchive.sh

The purpose of head -n -1 is to remove the last line of the archiv, which is exit 0, otherwise the command you are adding won't be executed. I haven't tested since this syntax doesn't work on macOS (I used grep -v "exit 0"instead, but there can be edge effects with that).

Now Scripts/main.sh will be executed once the archive is unpacked.

I couldn't solve a (small) problem: the -Q option is supposed to make the unpack stage quiet, without output messages. But there are still some of them, I don't why...

1
  • sed '$d' should remove the last line on any kind of Unix Oct 6, 2022 at 1:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .