What is the easiest way to edit a variable in a bash script from another bash script?

I have a bash script which only contains bash variables. for example:

#!/bin/bash
a="foo"
b="bar"

I also have another script, which should change the values of the variables of the first script permanently, so after it is run, the first script should contain:

#!/bin/bash
a="bar"
b="bar"

I'm looking for the easiest way to achieve this. I know this can be done using sed, but I also read that it should be possible to source the first script into the other script, and then just assign a new value to the variable. (I'd like to avoid regex or parsing if possible) I am, though, not sure if this only applies to the running shell, or if it actually updates the first script file as well. Is updating another script possible through sourcing or something else bash-specific, or should I just use sed? (I know other tools can be used, such as awk, but I'm not familiar with any of them)

For context, I'm trying to edit the level-name value in my Minecraft server's server.properties file, which isn't exactly a bash script by extension or shebang, but follows the exact same syntax. I could add a shebang to the file if that would be required for something more high-level than sed to work. This is the script I want to change the server.properties file from.


Solution 1:

For context, I'm trying to edit the level-name value in my Minecraft server's server.properties file, which isn't exactly a bash script by extension or shebang, but follows the exact same syntax.

No it does not. It follows a superficially similar format of "key=value" assignments, but the actual syntax of Java .properties files is completely different than that of variable assignments in Bash scripts. Trying to use the Bash interpreter's parser for a .properties file is actually worse than using a regex for it.

For example, variable names containing dashes (such as level-name) are not valid in Bash. Similarly, values with spaces (as seen in this default file) would not be accepted by Bash unless they were quoted.

And vice versa, assignment formats that would be valid in Bash (e.g. the output of declare -p var1 var2, which is what you'd use in Bash to produce a source-able script) are not valid in .properties files.

(It's unclear to me whether Minecraft's "Bedrock Edition" uses a fully Java-compatible .properties parser, or whether it uses a simpler one without the escaping rules, but its default server.properties still has the same incompatibilities with Bash syntax.)

So if you want to avoid hand-rolling regexes and want to use "The Real Thing", then use the java.util.Properties class:

// javac setprop.java && java -cp . SetProp server.properties level-name 'Yay'

import java.io.FileReader;
import java.io.FileWriter;
import java.util.Properties;

class SetProp
{
        public static void main(String args[])
        throws Exception
        {
                if (args.length != 3) {
                        System.err.println("Usage: setprop FILE KEY VALUE");
                        System.exit(2);
                }

                String file = args[0];
                String key = args[1];
                String value = args[2];

                Properties prop = new Properties();
                prop.load(new FileReader(file));
                prop.setProperty(key, value);
                // prop.store(new FileWriter(file), null);
                prop.store(System.out, null);
        }
}