system.activationScripts

Hello all;
I’m trying to execute this script, however, when I try to execute a bash command, nix rise an error as Im was calling a package instead execute a command.

system.activationScripts.script.text = ''
    #!/bin/bash
    variable_A=${variable_B}
    if [ "$(cat /etc/ec2-tags/name)" == "instance-1" ]; then
      variable_A="$(echo ${variable_A/0./1.})"
    else
      variable_A="$(echo ${variable_A/0./2.})"
    fi

Nix is getting this part: ${variable_A/0./1.} and try to call a componnent

nix/components/variable_A/0./1..': No such file or directory

Any hint what im doing wrong?

try to open up the variable assign to 2 lines, also why u need to echo value at first place? I think $(echo {stuff}) is redundant, do you mean to cat it? also it would be nicer if we know what var a and b are (but probably due to this msg nix/components/variable_A/0./1..': No such file or directory we already know it). btw, What you expect this to do?

Also, (probably this is not related to issue) but the nix string is not copied to be closed either, are there more to script or u missed that line?

I need to set some service parameters based on the host name. So im setting the variable that will be used further in the code as part of service config. The content of the variable_A is an ip address.
So basically the variable_A receives an ip address as value from other .nix file, then, i check the host name on the instance switch configuration step, and if the host name match, i need to update the variable name to finish with 1.0 instead 0.0 pretty much this.

Just a wild guess, but try replacing

variable_A="$(echo ${variable_A/0./1.})"

with

variable_A="$(variable_A)/0./1."

and if var b is also just a var why its wrapped in ${}, is it actually a placeholder for a command?

I’ve tried already, then a different error rise up. “End of the string reached”
Actually i did no. Let me try here.

The variable_B came from other .nix file and was passed as a parameter

Are there also another combo of stuff special chars like " and ’ in your var_b and var_a,
now I’m sorta sure its some string escaping problem,
my best suggestion is

  1. try running bash script manually, if worked, standalone (out of nix config file) proceed to 2
  2. use builtin functions to load from a file and move your script to a file and load it by the absolute path of the file (instead of writing the bash script in line) my sugg is smth like

/etc/nixos/config/your_script.sh

smth like

system.activationScripts.script.text = builtins.readFile /etc/nixos/config/your_script.sh;

(extra reminder: use absolute path in nix config to read it)
I guess it would probably fix the issue, but I’m also a noob around here, so if it didn’t work, maybe someone else notice the issue and help you

inform me if my solution worked

Yeah, doing in this way, nixos is using the variable_a itself as the value instead of the value of it

You just need to escape the ${:

variable_A="$(echo ''${variable_A/0./1.})"

That’s two'. See the docs on “indented strings”: Data Types - Nix Reference Manual

Note this is different for normal strings, those are escaped with \.

Also, yes, the echo subshell is unnecessary and wasteful :stuck_out_tongue:

1 Like

While I’m here, activation scripts don’t work this way, they are just appended into one big file. Hence they’re called “fragments” here: system.activationScripts

Remove that interpreter and make sure your variable name doesn’t mess up another fragment. /bin/bash doesn’t exist on nixos anyway, so this would fail if it was required.

However, if i remove the “echo” does not work. So, keeping the echo

Does:

variable_A="''${variable_A/0./1.}"

work?

No, at the least in my infra, just worked with the “echo”.

I think there’s a miscommunication here somewhere:

$ bash <<'EOF'
variable_b=blah0.2blah
variable_a=${variable_b/0./1.}
declare -p variable_a
EOF

declare -- variable_a="blah1.2blah"

If you’re needing echo, it’s probably a sign that you’re using process substitution with `` or $() (because the output of the process will get substituted).

1 Like

Yes! Your are right. Removing the ‘$()’ worked in perfection! (just missing the two simple quotes)
By the end the declaration is:

system.activationScripts.script.text = ''
    variable_A=${variable_B} (this one from a external module and the value is `10.10.0.0`)
    if [ "$(cat /etc/ec2-tags/name)" == "instance-1" ]; then
      variable_A="''${variable_A/0./1.}" (here im using double quotes followed by two simple quotes)
    else
      variable_Ar="''${variable_A/0./2.}"
    fi

By the end, the variable_A will have the value of 10.10.1.0 or 10.10.2.0 and it will be used further on the configuration file.