just icon indicating copy to clipboard operation
just copied to clipboard

Problem setting up Nushell on Windows

Open sim4life opened this issue 1 year ago โ€ข 7 comments

Using the alacritty v0.13.2 terminal, I'm trying to write Nushell v0.93.0 specific commands in my justfile on Windows 11 23H2. My justfile looks like:

for:
  for file in `ls .`; do echo $file; done

for2:
  for direc in `ls -s . | where type == dir | get name`; do \
    echo $direc; \
  done

$ just for

runs fine

$ just for2

/usr/bin/bash: line 1: get: command not found INFO: Could not find "type". INFO: Could not find "==".

It seems that justfile is interpreting ls -s . | where type == dir | get name as a bash command when I want it to be interpreted as Nushell command. If I start my justfile with

set shell := ["nu", "-c"] OR set shell := ["nu", "--env-config", "~\\.config\\nushell\\env.nu", "--config", "~\\.config\\nushell\\config.nu", "-c"] OR I change the recipe to:

for2:
  #!nu
  for dir in `ls -s . | where type == dir | get name`; do \
    echo $dir; \
  done

then it reports the following error:

Error: nu::parser::keyword_missing_arg ร— Missing argument to in. โ•ญโ”€[C:\Users\myusername\AppData\Local\Temp\just-UQzDXm\for2:13:13] 12 โ”‚ 13 โ”‚ for direc in ls -s . | where type == dir | get name; do
ยท โ–ฒ ยท โ•ฐโ”€โ”€ missing any value that follows in 14 โ”‚ echo $direc;
โ•ฐโ”€โ”€โ”€โ”€ error: Recipe for2 failed with exit code 1

Any suggestions on setting up windows and Nushell cross-platform justfile scripting?

sim4life avatar Jun 07 '24 07:06 sim4life

Hi @sim4life ,

Although I am not very familiar with Nushell, I just tried executing the command you provided directly in Nushell

~> for dir in "ls -s . | where type == dir | get name"; do echo $dir; done                      1 06/07/2024 06:00:29 PM
Error: nu::parser::keyword_missing_arg

  ร— Missing argument to `in`.
   โ•ญโ”€[entry #21:1:11]
 1 โ”‚ for dir in "ls -s . | where type == dir | get name"; do echo $dir; done
   ยท           โ–ฒ
   ยท           โ•ฐโ”€โ”€ missing any value that follows in
   โ•ฐโ”€โ”€โ”€โ”€

I don't think it is a valid nushell script

potterxu avatar Jun 07 '24 10:06 potterxu

Check https://www.nushell.sh/book/control_flow.html#for for a valid for loop sytax in nushell

for file in (ls .) {
  print $file
}

for direc in (ls -s . | where type == dir | get name) {
  print $direc
}

potterxu avatar Jun 07 '24 10:06 potterxu

set shell applies to the shell used for linewise recipes as well as backticks.

So when you set the shell to Nushell, you should write recipe lines in Nushell as well.

If you want to mix Bash and Nushell recipes, set shell to one and use shebang recipes for the other.

If you want to mix Bash and Nushell in the same recipe, you need to call out explicitly from one to the other. You could do this indirectly through just:

set shell := ['nu', '-c'] 

# Nu script
list-dir-names:
    ls -s . | where type == dir | get name

# Bash script
for:
    #!/usr/bin/env bash
    set -euxo pipefail
    for direc in $(just list-dir-names); do echo $direc; done

I don't see a reason to ever do this, but it is possible.

starthal avatar Jun 07 '24 17:06 starthal

Thanks for the replies: The syntax

for3:
  for direc in (ls -s . | where type == dir | get name) { echo $direc }

was giving me an error:

for3: -c: line 1: syntax error near unexpected token `('

I did NOT intend to mix n match nushell and bash syntax but it seems that the backticks shell command syntax ignores rest of the global shell settings in justfile and chooses bash in Windows. So I ended up completely replacing justfile for-loop syntax with nushell for-loop syntax like:

for2:
  #!nu
  ls -s . | where ($it | $it.type == dir) | get name

sim4life avatar Jun 08 '24 16:06 sim4life

Can you post a complete justfile, along with the error message you're getting? I want to make sure I understand the problem.

casey avatar Jun 08 '24 17:06 casey

One clarification to my previous comment: backticks within a recipe line are not preprocessed by just in any way. They are interpreted by the shell normally. So backticks in bash will execute the enclosed command in a subshell, while backticks in Nu just indicate a string.

The only syntax that causes just to change the text of a recipe is {{ }}. After those substitutions are made, the resulting script is interpreted by the shell directly.

starthal avatar Jun 08 '24 18:06 starthal

@sim4life

Are you referencing the for loop section in the readme and you think you are using a justfile for loop syntax?

for2:
  for direc in `ls -s . | where type == dir | get name`; do \
    echo $direc; \
  done

with your above justfile, you are expecting that

  • the for is a generic justfile loop

  • the backticks will be executed in nushell, and then the output being processed in the for loop

right?

but the for loop section in the readme is actually describing how to write a multi-line constructs in the justfile, and it is taking bash as an example. (which means there is no justfile-syntax for loop, the example is bash for loop)

  • so if you use set shell := ['nu', '-c'], the whole recipe is processed in nushell, then the for loop syntax is wrong, as it is actually a bash for
  • if you do not use set shell := ['nu', '-c'], the whole recipe is processed in bash, then the command ls -s . | where type == dir | get name will be processed in bash

so, you are trying use so-called "justfile-syntax" for loop and nu command in backticks. However, it is actually mixing a bash for-loop and a nushell command in the backticks.

  • No generic for-loop syntax in justfile, you need to write recipe lines based on the the shell type you want

@casey @starthal Please correct me if I am wrong

potterxu avatar Jun 11 '24 06:06 potterxu