Nushell
문서
쿡북
블로그
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
문서
쿡북
블로그
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
  • 소개
  • 설치하기
    • 기본 셸
  • 시작하기
    • 빠른 둘러보기
    • 시스템 이동
    • 누셸 방식으로 생각하기
    • 누셸 치트 시트
  • Nu 기본
    • 데이터 유형
    • 데이터 로드
    • 파이프라인
    • 문자열 작업
    • 목록 작업
    • 레코드 작업
    • 테이블 작업
    • 구조화된 데이터 탐색 및 액세스
    • 특수 변수
  • Nu에서 프로그래밍하기
    • 사용자 지정 명령
    • 별칭
    • 연산자
    • 변수
    • 제어 흐름
    • 스크립트
    • 모듈
      • 모듈 사용하기
      • 모듈 만들기
    • 오버레이
    • 정렬
    • 누셸 코드 테스트
    • 모범 사례
  • 셸로서의 Nu
    • 구성
    • 환경
    • 표준 출력, 표준 오류 및 종료 코드
    • 시스템(외부) 명령 실행
    • 타사 프롬프트 구성 방법
    • 디렉터리 스택
    • Reedline, Nu의 줄 편집기
    • 사용자 지정 완성
    • 외부 명령
    • Nu의 색상 지정 및 테마 설정
    • 후크
    • 백그라운드 작업
  • Nu로 전환하기
    • Bash에서 오신 분들을 위해
    • CMD.EXE에서 오신 분들을 위해
    • 다른 셸 및 도메인 특정 언어의 Nu 맵
    • 명령형 언어의 Nu 맵
    • 함수형 언어의 Nu 맵
    • 누셸 연산자 맵
  • 디자인 노트
    • 누셸 코드가 실행되는 방법
  • (약간)고급 사용법
    • 표준 라이브러리 (미리보기)
    • 데이터프레임
    • 메타데이터
    • 나만의 오류 만들기
    • 병렬 처리
    • 플러그인
    • explore

누셸 방식으로 생각하기

누셸은 다릅니다! 새로운 사용자가 다른 셸이나 언어에서 온 기존의 "습관"이나 정신 모델을 가지고 있는 것은 일반적이며 예상되는 일입니다!

새로운 사용자의 가장 일반적인 질문은 일반적으로 다음 주제 중 하나에 해당합니다.

  • 누셸은 Bash가 아닙니다
    • 때로는 Bash처럼 보일 수 있습니다
    • 하지만 Bash는 아닙니다
  • 암시적 반환
  • 표현식당 단일 반환 값
  • 모든 명령은 값을 반환합니다
  • 누셸을 컴파일된 언어로 생각하십시오
    • 정적 구문 분석에 기반한 기능
    • 제한 사항
    • 요약
  • 변수는 기본적으로 불변입니다
  • 누셸의 환경은 범위가 지정됩니다

누셸은 Bash가 아닙니다

때로는 Bash처럼 보일 수 있습니다

누셸은 프로그래밍 언어이자 셸입니다. 이 때문에 파일, 디렉터리, 웹사이트 등을 다루는 고유한 방식이 있습니다. 누셸의 일부 기능은 다른 셸에서 익숙한 기능과 유사하게 작동한다는 것을 알게 될 것입니다. 예를 들어, 파이프라인은 다른 셸과 마찬가지로 두 개 이상의 명령을 함께 결합하여 작동합니다.

예를 들어, 다음 명령줄은 유닉스/리눅스 플랫폼의 Bash와 누셸 모두에서 동일하게 작동합니다.

curl -s https://api.github.com/repos/nushell/nushell/contributors | jq -c '.[] | {login,contributions}'
# => 누셸에 대한 기여자를 기여 횟수 순으로 반환합니다.

누셸은 Bash(및 다른 셸)와 많은 유사점을 가지고 있으며 공통된 명령도 많습니다.

팁

Bash는 주로 외부 명령을 실행하는 명령 인터프리터입니다. 누셸은 이러한 많은 명령을 크로스 플랫폼, 내장 명령으로 제공합니다.

위 명령줄은 두 셸 모두에서 작동하지만 누셸에서는 curl 및 jq 명령을 사용할 필요가 없습니다. 대신 누셸에는 내장 http get 명령이 있으며 JSON 데이터를 기본적으로 처리합니다. 예시:

http get https://api.github.com/repos/nushell/nushell/contributors | select login contributions

누셸 방식으로 생각하기

누셸은 많은 셸과 언어에서 개념을 차용합니다. 누셸의 많은 기능이 익숙하게 느껴질 것입니다.

하지만 Bash는 아닙니다

그러나 이 때문에 Bash(및 일반적으로 POSIX) 스타일 구문 중 일부는 누셸에서 작동하지 않는다는 것을 잊기 쉽습니다. 예를 들어, Bash에서는 다음과 같이 작성하는 것이 일반적입니다.

# >를 사용하여 리디렉션
echo "hello" > output.txt
# 그러나 test 명령을 사용하여 비교(보다 큼)
test 4 -gt 7
echo $?
# => 1

그러나 누셸에서는 >가 비교를 위한 보다 큼 연산자로 사용됩니다. 이것은 현대 프로그래밍 기대치와 더 일치합니다.

4 > 10
# => false

>가 연산자이므로 누셸에서 파일로의 리디렉션은 콘텐츠 저장 전용 파이프라인 명령인 save를 통해 처리됩니다.

"hello" | save output.txt

누셸 방식으로 생각하기

Bash에서 오신 분들을 위해 장에서 일반적인 Bash 사용법과 누셸에서 해당 작업을 수행하는 방법에 대한 목록을 정리했습니다.

암시적 반환

다른 셸에서 온 사용자는 echo 명령에 매우 익숙할 것입니다. 누셸의 echo는 처음에는 동일하게 보일 수 있지만 매우 다릅니다.

먼저, 다음 출력이 Bash와 누셸(심지어 PowerShell과 Fish에서도)에서 어떻게 동일하게 보이는지 확인하십시오.

echo "Hello, World"
# => Hello, World

그러나 다른 셸이 Hello, World를 _표준 출력_으로 직접 보내는 반면, 누셸의 echo는 단순히 _값을 반환_합니다. 그런 다음 누셸은 명령 또는 더 기술적으로는 _표현식_의 반환 값을 _렌더링_합니다.

더 중요한 것은 누셸이 표현식의 값을 _암시적으로 반환_한다는 것입니다. 이것은 여러 면에서 PowerShell이나 Rust와 유사합니다.

팁

표현식은 파이프라인 이상일 수 있습니다. 사용자 지정 명령(많은 언어의 함수와 유사하지만 나중 장에서 더 자세히 다룰 것입니다)조차도 자동으로 마지막 값을 암시적으로 _반환_합니다. 값을 반환하기 위해 echo나 심지어 return 명령도 필요하지 않습니다. 그냥 _발생_합니다.

즉, 문자열 _"Hello, World"_와 echo "Hello, World"의 출력 값은 동일합니다.

"Hello, World" == (echo "Hello, World")
# => true

다음은 사용자 지정 명령 정의가 있는 또 다른 예입니다.

def latest-file [] {
    ls | sort-by modified | last
}

해당 파이프라인의 출력("값")은 latest-file 사용자 지정 명령의 _반환 값_이 됩니다.

누셸 방식으로 생각하기

echo <something>을 작성할 수 있는 대부분의 곳에서 누셸에서는 대신 <something>만 작성하면 됩니다.

표현식당 단일 반환 값

표현식은 단일 값만 반환할 수 있다는 것을 이해하는 것이 중요합니다. 표현식 내에 여러 하위 표현식이 있는 경우 마지막 값만 반환됩니다.

일반적인 실수는 다음과 같은 사용자 지정 명령 정의를 작성하는 것입니다.

def latest-file [] {
    echo "Returning the last file"
    ls | sort-by modified | last
}

latest-file

새로운 사용자는 다음을 기대할 수 있습니다.

  • 2행에서 "Returning the last file" 출력
  • 3행에서 파일 반환/출력

그러나 echo가 **값을 반환**한다는 것을 기억하십시오. 마지막 값만 반환되므로 2행의 _값_은 버려집니다. 3행에서 파일만 반환됩니다.

첫 번째 줄이 _표시_되도록 하려면 print 명령을 사용하십시오.

def latest-file [] {
    print "Returning last file"
    ls | sort-by modified | last
}

또한 다음을 비교하십시오.

40; 50; 60

팁

세미콜론은 누셸 표현식에서 줄 바꿈과 동일합니다. 위는 파일 또는 여러 줄 명령과 동일합니다.

40
50
60

또는

echo 40
echo 50
echo 60

참조: 여러 줄 편집

위의 모든 경우:

  • 첫 번째 값은 정수 40으로 평가되지만 반환되지 않습니다.
  • 두 번째 값은 정수 50으로 평가되지만 반환되지 않습니다.
  • 세 번째 값은 정수 60으로 평가되며, 마지막 값이므로 반환되어 표시(렌더링)됩니다.

누셸 방식으로 생각하기

예기치 않은 결과를 디버깅할 때 다음을 주의하십시오.

  • 하위 표현식(예: 명령 또는 파이프라인)...
  • ... (비-null) 값을 출력하는...
  • ... 해당 값이 부모 표현식에서 반환되지 않는 경우.

이것들은 코드에서 문제의 원인이 될 수 있습니다.

모든 명령은 값을 반환합니다

일부 언어에는 값을 반환하지 않는 "문"이라는 개념이 있습니다. 누셸에는 없습니다.

누셸에서는 **모든 명령이 값을 반환**합니다. 해당 값이 null( nothing 유형)인 경우에도 마찬가지입니다. 다음 여러 줄 표현식을 고려하십시오.

let p = 7
print $p
$p * 6
  1. 1행: 정수 7이 $p에 할당되지만 let 명령 자체의 반환 값은 null입니다. 그러나 표현식의 마지막 값이 아니므로 표시되지 않습니다.
  2. 2행: print 명령 자체의 반환 값은 null이지만 print 명령은 해당 인수($p, 즉 7)를 _표시_하도록 강제합니다. 1행과 마찬가지로 이것이 표현식의 마지막 값이 아니므로 null 반환 값은 버려집니다.
  3. 3행: 정수 값 42로 평가됩니다. 표현식의 마지막 값이므로 이것이 반환 결과이며 표시(렌더링)됩니다.

누셸 방식으로 생각하기

일반적인 명령의 출력 유형에 익숙해지면 간단한 명령을 함께 결합하여 복잡한 결과를 얻는 방법을 이해하는 데 도움이 됩니다.

help <command>는 누셸의 각 명령에 대한 서명(출력 유형 포함)을 표시합니다.

누셸을 컴파일된 언어로 생각하십시오

누셸에서는 코드를 실행할 때 정확히 두 개의 별도 상위 수준 단계가 있습니다.

  1. 1단계(파서): 전체 소스 코드 구문 분석
  2. 2단계(엔진): 전체 소스 코드 평가

누셸의 구문 분석 단계를 Rust 또는 C++와 같은 정적 언어의 _컴파일_로 생각하는 것이 유용할 수 있습니다. 즉, 2단계에서 평가될 모든 코드는 구문 분석 단계 중에 **알려지고 사용 가능**해야 합니다.

중요

그러나 이것은 또한 누셸이 현재 Bash나 Python과 같은 동적 언어와 같이 eval 구문을 지원할 수 없음을 의미합니다.

정적 구문 분석에 기반한 기능

반면에 구문 분석의 정적 결과는 다음과 같은 누셸의 REPL의 많은 기능에 대한 핵심입니다.

  • 정확하고 표현력 있는 오류 메시지
  • 오류 조건의 조기 및 강력한 감지를 위한 의미 분석
  • IDE 통합
  • 유형 시스템
  • 모듈 시스템
  • 완성
  • 사용자 지정 명령 인수 구문 분석
  • 구문 강조
  • 실시간 오류 강조
  • 프로파일링 및 디버깅 명령
  • (미래) 서식 지정
  • (미래) 더 빠른 실행을 위해 "컴파일된" IR(중간 표현) 결과 저장

제한 사항

누셸의 정적 특성은 eval을 사용할 수 있는 언어에서 온 사용자에게 종종 혼란을 야기합니다.

간단한 두 줄 파일을 고려하십시오.

<line1 code>
<line2 code>
  1. 구문 분석:
    1. 1행이 구문 분석됩니다.
    2. 2행이 구문 분석됩니다.
  2. 구문 분석이 성공하면 평가:
    1. 1행이 평가됩니다.
    2. 2행이 평가됩니다.

이것은 다음 예제가 누셸에서 단일 표현식(예: 스크립트)으로 실행될 수 없는 이유를 설명하는 데 도움이 됩니다.

노트

다음 예제에서는 source 명령을 사용하지만, use, overlay use, hide 또는 source-env와 같이 누셸 소스 코드를 구문 분석하는 다른 명령에도 유사한 결론이 적용됩니다.

예제: 동적으로 소스 생성

이 시나리오를 고려하십시오.

"print Hello" | save output.nu
source output.nu
# => Error: nu::parser::sourced_file_not_found
# =>
# =>   × File not found
# =>    ╭─[entry #5:2:8]
# =>  1 │ "print Hello" | save output.nu
# =>  2 │ source output.nu
# =>    ·        ────┬────
# =>    ·            ╰── File not found: output.nu
# =>    ╰────
# =>   help: sourced files need to be available before your script is run

이것은 문제가 있습니다. 왜냐하면:

  1. 1행은 구문 분석되지만 평가되지 않습니다. 즉, output.nu는 구문 분석 단계에서는 생성되지 않고 평가 중에만 생성됩니다.
  2. 2행이 구문 분석됩니다. source는 파서 키워드이므로 소스 파일의 확인은 구문 분석(1단계) 중에 시도됩니다. 그러나 output.nu는 아직 존재하지도 않습니다! 존재하는 경우에도 올바른 파일이 아닐 수 있습니다! 이로 인해 오류가 발생합니다.

노트

**REPL**에서 두 개의 별도 줄로 입력하면 첫 번째 줄이 구문 분석 및 평가된 다음 두 번째 줄이 구문 분석 및 평가되므로 작동합니다.

제한은 스크립트, 블록, 클로저 또는 다른 표현식의 일부일 수 있는 단일 표현식으로 함께 구문 분석될 때만 발생합니다.

자세한 내용은 _"누셸 코드가 실행되는 방법"_의 REPL 섹션을 참조하십시오.

예제: 동적으로 소싱할 파일 이름 만들기

다른 셸에서 올 때 흔히 볼 수 있는 또 다른 시나리오는 소싱될 파일 이름을 동적으로 만들려고 시도하는 것입니다.

let my_path = "~/nushell-files"
source $"($my_path)/common.nu"
# => Error:
# =>   × Error: nu::shell::not_a_constant
# =>   │
# =>   │   × Not a constant.
# =>   │    ╭─[entry #6:2:11]
# =>   │  1 │ let my_path = "~/nushell-files"
# =>   │  2 │ source $"($my_path)/common.nu"
# =>   │    ·           ────┬───
# =>   │    ·               ╰── Value is not a parse-time constant
# =>   │    ╰────
# =>   │   help: Only a subset of expressions are allowed constants during parsing. Try using the 'const' command or typing the value literally.
# =>   │
# =>    ╭─[entry #6:2:8]
# =>  1 │ let my_path = "~/nushell-files"
# =>  2 │ source $"($my_path)/common.nu"
# =>    ·        ───────────┬───────────
# =>    ·                   ╰── Encountered error during parse-time evaluation
# =>    ╰────

let 할당은 평가될 때까지 확인되지 않으므로 파서 키워드 source는 변수가 전달되면 구문 분석 중에 실패합니다.

Rust 및 C++ 비교

위 코드가 C++와 같은 일반적인 컴파일 언어로 작성되었다고 상상해 보십시오.

#include <string>

std::string my_path("foo");
#include <my_path + "/common.h">

또는 Rust

let my_path = "foo";
use format!("{}::common", my_path);

이러한 언어 중 하나에서 간단한 프로그램을 작성해 본 적이 있다면 이러한 예제가 해당 언어에서 유효하지 않다는 것을 알 수 있습니다. 누셸과 마찬가지로 컴파일된 언어는 모든 소스 코드 파일이 컴파일러에 미리 준비되고 사용 가능해야 합니다.

참조

오류 메시지에서 언급했듯이 my_path가 상수로 정의될 수 있는 경우 상수는 구문 분석 중에 확인될 수 있으므로(그리고 확인되므로) 작동할 수 있습니다.

const my_path = "~/nushell-files"
source $"($my_path)/common.nu"

자세한 내용은 구문 분석 시간 상수 평가를 참조하십시오.

예제: 다른 디렉터리로 변경(cd)하고 파일 source하기

하나 더 있습니다. 다른 디렉터리로 변경한 다음 해당 디렉터리에서 파일을 source하려고 시도합니다.

if ('spam/foo.nu' | path exists) {
    cd spam
    source-env foo.nu
}

누셸의 구문 분석/평가 단계에 대해 다룬 내용을 바탕으로 해당 예제의 문제를 찾아보십시오.

해결책

3행에서 구문 분석 중에 source-env가 foo.nu를 구문 분석하려고 시도합니다. 그러나 cd는 평가될 때까지 발생하지 않습니다. 이로 인해 파일이 현재 디렉터리에서 발견되지 않으므로 구문 분석 시간 오류가 발생합니다.

이 문제를 해결하려면 소싱할 파일의 전체 경로를 사용하기만 하면 됩니다.

    source-env spam/foo.nu

요약

중요

이 섹션에 대한 자세한 내용은 누셸 코드가 실행되는 방법을 참조하십시오.

누셸 방식으로 생각하기

누셸은 각 표현식 또는 파일에 대해 단일 구문 분석 단계를 사용하도록 설계되었습니다. 이 구문 분석 단계는 평가 전에 발생하며 평가와는 별개입니다. 이것이 누셸의 많은 기능을 가능하게 하지만, 사용자가 그것이 만드는 제한 사항을 이해해야 한다는 것을 의미하기도 합니다.

변수는 기본적으로 불변입니다

다른 언어에서 올 때 흔히 놀라는 또 다른 점은 누셸 변수가 기본적으로 불변이라는 것입니다. 누셸에는 선택적 가변 변수가 있지만 누셸의 많은 명령은 불변성을 요구하는 함수형 프로그래밍 스타일을 기반으로 합니다.

불변 변수는 또한 여러 값을 스레드를 사용하여 병렬로 작업할 수 있는 누셸의 par-each 명령의 핵심입니다.

자세한 내용은 불변 변수 및 가변 변수와 불변 변수 중에서 선택을 참조하십시오.

누셸 방식으로 생각하기

가변 변수에 의존하는 데 익숙하다면 더 기능적인 스타일로 코딩하는 방법을 다시 배우는 데 시간이 걸릴 수 있습니다. 누셸에는 불변 변수와 함께 작동하고 불변 변수에서 작동하는 많은 기능적 기능과 명령이 있습니다. 그것들을 배우면 더 누셸 관용적인 스타일로 코드를 작성하는 데 도움이 될 것입니다.

좋은 보너스는 par-each를 사용하여 코드의 일부를 병렬로 실행하여 얻을 수 있는 성능 향상입니다.

누셸의 환경은 범위가 지정됩니다

누셸은 컴파일된 언어에서 여러 디자인 단서를 가져옵니다. 그러한 단서 중 하나는 언어가 전역 가변 상태를 피해야 한다는 것입니다. 셸은 일반적으로 환경을 업데이트하기 위해 전역 변형을 사용했지만 누셸은 이 접근 방식을 피하려고 합니다.

누셸에서 블록은 자체 환경을 제어합니다. 환경에 대한 변경 사항은 발생하는 블록으로 범위가 지정됩니다.

실제로 이것은 (한 가지 예일 뿐이지만) 하위 디렉터리로 작업하기 위한 더 간결한 코드를 작성할 수 있게 해줍니다. 다음은 현재 디렉터리의 각 하위 프로젝트를 빌드하는 예입니다.

ls | each { |row|
  cd $row.name
  make
}

cd 명령은 PWD 환경 변수를 변경하지만 이 변수 변경은 블록이 끝난 후에도 유지되지 않습니다. 이를 통해 각 반복은 현재 디렉터리에서 시작하여 다음 하위 디렉터리로 들어갈 수 있습니다.

범위가 지정된 환경을 사용하면 명령을 더 예측 가능하고 읽기 쉽게 만들고, 때가 되면 디버깅하기 더 쉬워집니다. 이것은 또한 위에서 논의한 par-each 명령의 핵심 기능이기도 합니다.

누셸은 또한 한 번에 환경에 대한 여러 업데이트를 로드하는 편리한 방법으로 load-env와 같은 도우미 명령을 제공합니다.

참조

환경 - 범위

노트

def --env는 이 규칙의 예외입니다. 부모의 환경을 변경하는 명령을 만들 수 있습니다.

누셸 방식으로 생각하기

범위가 지정된 환경을 사용하여 더 간결한 스크립트를 작성하고 불필요하거나 원치 않는 전역 환경 변형을 방지하십시오.

GitHub에서 수정하기
Contributors: Taeyoon Kim, ImgBotApp, google-labs-jules[bot], deepthought
Prev
시스템 이동
Next
누셸 치트 시트