1

In Bash I would do something like

...
...
if ! cd non_exist_dir > /dev/null 2>&1; then
  echo "error in cd"
  return 1
fi
...
...

How would I do that in idiomatic nushell ?
Especially, how can I get rid of the annoying error message displayed by nushell because the directory doesn't exist ?
Bonus points if I could get something like a "return" command, which seems to be missing in nushell.

zentrunix
  • 2,098
  • 12
  • 20

2 Answers2

2

Nushell 0.72 introduces try/catch blocks which can suppress or replace the error handling for Nushell builtins. For your example:

try {
    cd non_exist_dir
} catch {
    print -e "error in cd"
}

As for the other part of your question, a return code would only seem to be useful if are returning to a non-Nushell process. Any error handling from within Nushell can use Nushell errors and try/catch blocks.

But if you are returning to a non-Nushell process, then you can use the exit <status_code> builtin.

This would only work in either:

  • A script
  • An invocation of nu -c "<commands>"

However, a simple cd could never work in either case, since both cases start a new Nushell shell (try saying that 10 times real fast), and when that shell exits, the environment will be returned to its entry state (even with def-env).

But if you are doing something after the cd, then it would make sense to include this in a script. For example, a silly_cd.nu (silly, because it's pretty useless other than as a demonstration of exit):

#!/usr/bin/env nu
def main [d?: string] {
    if ($d == null) {
        # Prevent sourced function from exiting Nushell
        return
    }
    try {
        cd $d
    } catch {
        print -e "Error in cd"
        exit 1
    }
    ls
}
NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
  • this version is much better, with `try/catch` and `return`, and even stderr redirection ... which alas, doesn't work with `cd` ... nushell is very nice, but it will be a tough job winning users spoiled by years (even decades!) of bash experience – zentrunix Dec 04 '22 at 17:36
  • @zentrunix Right, or in my case Fish. – NotTheDr01ds Dec 04 '22 at 20:20
1

One solution is to create a custom command something like this.

def-env mycd [path] {
  let p = (if ($path | path exists) { $path } else { $env.PWD })
  cd $p
}

This solves part of the problem, getting rid of the error message by checking if the folder exists, and if it does, it uses that path. If it doesn't exist, it just uses your current directory.

This doesn't solve the second part, returning, but one could foresee setting $env.LAST_EXIT_CODE to some value. You'd have to play around a bit to see if that works and fits your needs. Good luck.

Darren
  • 483
  • 7
  • 15
  • Thanks. I have already tried something like your solution, and it works, more or less, but I was not happy with it. I think not having redirection of stderr is a big hassle, as is not having a "return" command. – zentrunix Nov 20 '22 at 21:17
  • 1
    We're planning on adding redirection as we speak. For those who want to participate in the design can join our [Discord](https://discordapp.com/invite/NtAbbGn) where it's actively being discussed. – Darren Nov 21 '22 at 01:08
  • Shouldn't `def-env` be only `def`` in your answer ? – zentrunix Dec 04 '22 at 17:39
  • @zentrunix nope, `def` is scoped and thus would not allow the cd to change outside of the mycd custom command. `def-env` allows it to "escape". – Darren Dec 05 '22 at 18:11