How do I use bash var substitution in Nix?

I’m trying to use Bash substitution like this:

 $ X=$(basename /nix/store/iw32rg9wxm6w1xxqwkaddh70q932grpw-aapt2-3.5.3-5435860.pom)
 $ echo ${X#*-}                                                  
aapt2-3.5.3-5435860.pom

Because I want to preserver filenames from srcs in unpackPhase:

  unpackPhase = ''
    mkdir -p $out
    for src in $srcs; do
      local filename=$(basename $src)
      cp $src $out/\$\{filename#*-\}
    done
  '';

But this doesn’t seem to work. What is the correct form? $${}? \$\${}? $\${}? \$\$\{\}?
I’m pretty confused as to how to do this.

This section of the nixpkgs manual explains escaping in nix string literals, here is the part that I think you’re interested in:

Since ${ and '' have special meaning in indented strings, you need a way to quote them. $ can be escaped by prefixing it with '' (that is, two single quotes), i.e., ''$ . '' can be escaped by prefixing it with ' , i.e., ''' . $ removes any special meaning from the following $ .

4 Likes

That’s prefect, thanks a bunch!

1 Like

I actually found a more canonical way of doing this, which is with stripHash function available in the setup.sh script:

Which can be used to achieve the same thing I was trying to do here without bash magic.

Thanks

… $ can be escaped … ‘’${test}

I had an issue with a bash function as a string literal in Nix. Nix wanted to do the substitution when building when substitution was only meant for running the bash script. Using this tip Nix ignored them allowing me to build.