Nix file --argstr pathDir: error: getting status of '/home/user/pathDir': No such file or directory

I don’t understand why args sequence matter / where my errors is caused from

in bash shell variables get defined
and should be handed over to the shell.nix file ( e.g. via --argstr)

  • here it should be any dir path ( like pwd)

the var pathDir only works if there are no other args

  • or if pathDir is on the first position

Why that?


testPkgNix="bash" ; pathDir="$(pwd)" ;
echo $pathDir
nix-shell Nix_args.nix --pure --show-trace  

nix-shell Nix_args.nix --pure --argstr pathDir ${pathDir} --show-trace # ok
nix-shell Nix_args.nix --pure --argstr testPkg    ${testPkgNix} --argstr pathDir ${pathDir}    --show-trace # issue # should warn that testPkg is no parameter in the script
nix-shell Nix_args.nix --pure --argstr testPkgNix ${testPkgNix} --argstr pathDir ${pathDir}       --show-trace # issue # should work
nix-shell Nix_args.nix --pure --argstr pathDir ${pathDir}       --argstr testPkg ${testPkgNix}      --show-trace # ok #  # should warn that testPkg is no parameter in the script
nix-shell Nix_args.nix --pure --argstr pathDir ${pathDir}       --argstr testPkgNix ${testPkgNix} --show-trace # ok # 
{ testPkgNix ? "zsh", pathDir ? "/home/" , ...}:
let  
 pkgs = import <nixpkgs> {} ; 
in                                                                         
 pkgs.mkShell {                              
         name="devEnv";                           
         buildInputs = [                                      
             pkgs.bash                                                                 
             pkgs.which                                                                 
             ];                                                                            
         shellHook = ''                     
              echo "Path ${pathDir}"       
              echo "pkgs ${testPkgNix}"                                            
              '';                                                                       
    }

In the example script testPkgNix variable isn’t defined, therefore the --argstr after that is assigned to the testPkg/testPkgNix argument of the nix expression. Which again makes nix see pathDir as just a regular argument to nix-shell which at this location seems to be a relative path.

Hello @NobbZ,

thanks for your response.

testPkgNix is defined.

Only testPkg is not defined. (Here I would expect a warning) BUT it works in the fourth execution example

Then your example is incomplete. Can you update it?

in bash
testPkgNix="bash"

in shell.nix
{ testPkgNix ? "zsh",

What more has to be defined?

At the moment my best guess is that bash vars have to be strictly with '"' like --argstr key “${val}” (to be save in many cases)

testPkgPy=“” ;
looks like an empty string is an issue

If you do testPkgPy="" and then use $testPkgPy in shell, it will expand to “nothing”, while "$testPkgPy" will expand to the empty string.

So, yes, that makes a huge difference.

But using ... already means to ignore extra attributes in the argument, so should this be a warning?

@dramforever
Thanks for the hint (while testing, all gets changed too often)

  • it was tested without , ... } as well

NO warning - without the .../extra attributes

@NobbZ
Not in my test.

  • When it is an empty string it gets ignored/seen as undefined instead of handing over an empty string

in zsh

testPkgNix="" ; pathDir="$(pwd)" ;
# testPkg="pkgTest" ; pathDir="$(pwd)" ;
echo "${pathDir}"
echo "${testPkgNix}"
nix-shell --pure --argstr testPkg    "${testPkgNix}" --argstr pathDir "${pathDir}"   =( << 'EOF'
{ testPkgNix ? "emptyStringAsNotDefined_insteadOfEmptyString", pathDir ? "./test/" }:
let  
 pkgs = import <nixpkgs> {} ; 
in                                                                         
 pkgs.mkShell {                              
         name="devEnv";                           
         buildInputs = [                                      
             pkgs.bash                                                                 
             pkgs.which                                                                 
             ];                                                                            
         shellHook = ''                     
              echo "Path ${pathDir}"       
              echo "pkgs ${testPkgNix}"                                            
              '';                                                                       
    }
EOF
)

(same behavior in bash shell)

I was talking about shell expansion, not interpretation within nix.

$ nix-shell --pure --argstr testPkg "${testPkgNix}" --argstr pathDir "${pathDir}"
these 2 paths will be fetched (0.10 MiB download, 0.55 MiB unpacked):
  /nix/store/0dmllfici0iw4cdjsy22magghzip1815-bash-4.4-p23-dev
  /nix/store/ajidkqg53y0zvh0m5cjgqiw3pf9cvlf0-bash-interactive-4.4-p23-dev
copying path '/nix/store/0dmllfici0iw4cdjsy22magghzip1815-bash-4.4-p23-dev' from 'https://cache.nixos.org'...
copying path '/nix/store/ajidkqg53y0zvh0m5cjgqiw3pf9cvlf0-bash-interactive-4.4-p23-dev' from 'https://cache.nixos.org'...
Path /tmp/tmp.R1R391Vvba
pkgs emptyStringAsNotDefined_insteadOfEmptyString

[nix-shell:/tmp/tmp.R1R391Vvba]$ exit
$ nix-shell --pure --argstr testPkg ${testPkgNix} --argstr pathDir "${pathDir}"
error: --- SysError -------------------------------------------------------------------------------------------------------- nix-shell
getting status of '/tmp/tmp.R1R391Vvba/pathDir': No such file or directory

As you can see, without the wrapping " we get the error from the title.

regarding the 1. example

  • shouldn’t an empty string handed over to .nix file?

It is passed an empty string to the expression. Though as we are using --arg rather than --argstr, the empty string is interpreted as the empty expression and replaced by the default value.

I can assume that this treatement is usefull in shell scripting. Though sadly I can not find it documented as such.