BATsh चिटसिट [NE] नेपाली
========================

----------------------------------------------------------------------
सारांश
  BATsh एउटा द्विभाषिक शेल हो जसले cmd.exe ब्याच र bash/sh वाक्यविन्यासलाई
  एउटै स्क्रिप्ट फाइलमा चलाउँछ। यसले प्रति पङ्क्ति/खण्ड स्वतः मोड फेर्छ।
  कुनै बाह्य शेल आवश्यक छैन -- शुद्ध Perl कार्यान्वयन।
  पाइपलाइन, पुनर्निर्देशन, फङ्सन र चर-विस्तार विस्तारहरूलाई समर्थन गर्छ।

मिश्रित-मोड नमुना
  :: CMD खण्ड (पहिलो टोकन ठूलो अक्षर)
  @ECHO OFF
  SET LANG=BATsh
  SET COUNT=3

  # SH खण्ड (पहिलो टोकन सानो अक्षर)
  greet() { echo "Hello from $1 (bash mode)"; }
  greet $LANG
  for i in 1 2 3; do echo "  item $i of $COUNT"; done
  result=$(echo $LANG | perl -ne "print uc")
  echo "Uppercase: $result"

  :: फेरि CMD खण्ड (ब्रिजमार्फत SH को नतिजा पढ्छ)
  ECHO Back in CMD: %result%

  # यसरी चलाउनुहोस्: perl lib/BATsh.pm script.batsh
  # वा:             use BATsh; BATsh->run('script.batsh');
----------------------------------------------------------------------


BATsh एउटा द्विभाषिक शेल हो जसले cmd.exe र bash/sh वाक्यविन्यासलाई एउटै
स्क्रिप्टमा चलाउँछ।  स्क्रिप्टलाई खण्डहरूमा विभाजन गरिन्छ; प्रत्येक खण्ड
उपयुक्त शेलद्वारा यथारूप कार्यान्वयन गरिन्छ।

1. मोड पहिचान
-------------
  कुनै खण्डको पहिलो अर्थपूर्ण पङ्क्तिको «पहिलो टोकन» ले त्यो खण्ड कुन शेलले
  कार्यान्वयन गर्छ भन्ने निर्धारण गर्छ:

  CMD मोड: पहिलो टोकन पूर्णतः [A-Z 0-9 _ - \ / : . @ %] बाट बनेको हुन्छ र
           त्यसमा कम्तीमा एउटा ठूलो अक्षर A-Z हुन्छ।

    ECHO hello          -> CMD खण्ड (cmd.exe)
    SET FOO=bar baz     -> CMD खण्ड  (मान भाग जाँचिँदैन)
    @ECHO OFF           -> CMD खण्ड
    IF "%X%"=="Y" (     -> CMD खण्ड

  SH मोड: अरू सबै (कुनै सानो अक्षर छ, वा कुनै अक्षर नै छैन)।

    echo hello          -> SH खण्ड  (bash/sh)
    export FOO=bar      -> SH खण्ड
    if [ -f "$f" ]; then  -> SH खण्ड
    #!/bin/sh           -> SH खण्ड  (shebang एउटा SH पङ्क्ति हो)

  टिप्पणी र खाली पङ्क्तिहरू हालको खण्डमा समाहित गरिन्छन्।
  टिप्पणी वाक्यविन्यास:
    ::           CMD-शैली टिप्पणी
    REM ...      CMD-शैली टिप्पणी (ठूलो-सानो अक्षर निरपेक्ष)
    @REM ...     CMD-शैली टिप्पणी
    # ...        SH-शैली टिप्पणी  (#! shebang होइन)

2. शेल सुरु गर्ने
-----------------
  perl lib/BATsh.pm               # अन्तरक्रियात्मक REPL
  perl lib/BATsh.pm script.batsh  # स्क्रिप्ट फाइल चलाउनुहोस्
  perl lib/BATsh.pm -e "echo hi"  # इनलाइन एक-पङ्क्ति आदेश

  Perl बाट:
    use BATsh;
    BATsh->run('script.batsh');
    BATsh->run_string("echo hello");
    BATsh->repl();

3. वातावरण चर ब्रिज
-------------------
  प्रत्येक खण्ड चल्नुअघि, BATsh ले हालको %ENV लाई प्रस्तावनाको रूपमा
  सम्मिलित गर्छ (CMD का लागि SET पङ्क्ति, SH का लागि export पङ्क्ति)।  खण्ड
  पछि, शेलको अन्तिम वातावरण पुनः %ENV मा पढिन्छ।

  export FOO=hello   # SH ले FOO सेट गर्छ
  ECHO %FOO%         # CMD ले ब्रिजमार्फत FOO पढ्छ (Windows)

  SET BAR=world      # CMD ले BAR सेट गर्छ
  echo $BAR          # SH ले ब्रिजमार्फत BAR पढ्छ

4. SETLOCAL / ENDLOCAL
----------------------
  SETLOCAL           # %ENV को स्न्यापसट (cmd.exe होइन, BATsh ले व्यवस्थापन गर्छ)
  SET TMP=local_val
  ECHO %TMP%
  ENDLOCAL           # %ENV पुनर्स्थापना (TMP हराउँछ)

  स्कोपहरू नेस्ट हुन सक्छन्।

5. खण्ड सीमा पहिचान
-------------------
  कुनै खण्ड त्यसको ब्लकको गहिराइ शून्यमा फर्किंदा र अर्को अर्थपूर्ण पङ्क्ति
  फरक मोडको हुँदा अन्त्य हुन्छ।

  CMD खण्डहरूले उद्धरणबाहिरका ( र ) को गहिराइ पछ्याउँछन्:

    IF "%X%"=="Y" (     <- ब्लक खोल्छ (गहिराइ 1)
        ECHO yes
    ) ELSE (            <- बन्द गरी फेरि खोल्छ (गहिराइ >=1 रहन्छ)
        ECHO no
    )                   <- ब्लक बन्द (गहिराइ 0) -> खण्ड अन्त्य हुन सक्छ

  SH खण्डहरूले किवर्डको गहिराइ पछ्याउँछन्:

    for x in 1 2; do   <- ब्लक खोल्छ (गहिराइ 1)
        echo $x
    done                <- ब्लक बन्द (गहिराइ 0) -> खण्ड अन्त्य हुन सक्छ

  खुला ब्लकभित्रका पङ्क्तिहरू हालको खण्डमा समाहित हुन्छन्, चाहे तिनको पहिलो
  टोकन अर्को मोडजस्तो देखिए पनि। यसले निम्न सम्भव बनाउँछ:

    for x in A B; do
        ECHO $x          <- SH ब्लकभित्र ठूलो अक्षर: तैपनि SH खण्ड
    done

  SH किवर्ड जोडी:
    खोल्ने (+1)  : if  for  while  until  case  function  select  {
    बन्द गर्ने (-1) : fi  done  esac  }
    तटस्थ   ( 0) : then  do  else  elif

6. सबरुटिन परिभाषा
------------------
  :GREET
  echo "Hello $BATSH_ARG1"
  RET

  लेबल : बाट सुरु भई RET वा RETURN मा अन्त्य हुन्छन्।
  मुख्य भाग कार्यान्वयनअघि झिकिन्छ (इनलाइन चल्दैन)।
  मुख्य भागमा CMD पङ्क्ति, SH पङ्क्ति, वा मिश्रण हुन सक्छ।

7. CALL र source
----------------
  CALL :GREET world      # आर्गुमेन्टसहित सबरुटिन कल गर्नुहोस्
  CALL other.batsh       # अर्को .batsh फाइल समावेश/चलाउनुहोस् (CMD)
  source other.batsh     # अर्को .batsh फाइल समावेश/चलाउनुहोस् (SH)
  . other.batsh          # POSIX डट सङ्केत

  आर्गुमेन्ट: $BATSH_ARG1 .. $BATSH_ARGn  (CMD मा %BATSH_ARG1%)
  सङ्ख्या:    $BATSH_ARGC

8. Perl API
-----------
  BATsh->run($file)            # .batsh फाइल चलाउनुहोस्
  BATsh->run_string($source)   # स्रोत स्ट्रिङ चलाउनुहोस्
  BATsh->run_lines(@lines)     # पङ्क्तिहरूको एरे चलाउनुहोस्
  BATsh->repl()                # अन्तरक्रियात्मक REPL
  BATsh->classify_token($tok)  # 'CMD' वा 'SH'
  BATsh->setlocal()            # %ENV को स्न्यापसट
  BATsh->endlocal()            # %ENV पुनर्स्थापना
  BATsh->call_sub($lbl, @args) # सबरुटिन कल गर्नुहोस्
  BATsh->source_file($file)    # .batsh फाइल समावेश गर्नुहोस्
  BATsh->version()             # संस्करण स्ट्रिङ

9. प्लेटफर्म टिप्पणी
-------------------
  Windows: CMD र SH दुवै खण्ड शुद्ध Perl मा चल्छन् -- कुनै बाह्य cmd.exe, bash, वा sh आवश्यक छैन।
  UNIX:    CMD र SH दुवै खण्ड शुद्ध Perl मा चल्छन् -- कुनै बाह्य cmd.exe, bash, वा sh आवश्यक छैन।

10. आवश्यकता
------------
  Perl 5.005_03 वा नयाँ।  कोर मोड्युल मात्र (File::Spec, Carp)।
  कुनै CPAN निर्भरता छैन।

11. CMD पाइपलाइन र प्यारामिटर परिमार्जक
---------------------------------------
  cmd1 | cmd2              # अस्थायी फाइलमार्फत पाइपलाइन (शुद्ध Perl)
  ECHO hello | perl -e "while(<STDIN>){print uc}"

  SET /P VAR=Prompt:       # STDIN बाट एक पङ्क्ति पढेर VAR मा राख्छ

  ब्याच-प्यारामिटर टिल्ड परिमार्जक (उदा. %0=C:\scripts\deploy.bat हुँदा):
    %~0   -> C:\scripts\deploy.bat  (उद्धरण हटाउने मात्र)
    %~f0  -> C:/scripts/deploy.bat  (पूर्ण निरपेक्ष पथ)
    %~d0  -> C:                     (ड्राइभ अक्षर)
    %~p0  -> /scripts/              (डाइरेक्टरी पथ)
    %~n0  -> deploy                 (विस्तार नभएको फाइल नाम)
    %~x0  -> .bat                   (विस्तार)
    %~dp0 -> C:/scripts/            (ड्राइभ + डाइरेक्टरी, सबैभन्दा सामान्य)
    %~nx1 -> deploy.bat             (नाम + विस्तार)

12. SH फङ्सन र विस्तार
----------------------
  greet() {              # फङ्सन परिभाषा
      echo "Hi $1"
  }
  function add {         # वैकल्पिक वाक्यविन्यास
      echo $(( $1 + $2 ))
  }
  greet world            # फङ्सन कल गर्नुहोस्
  add 3 4                # -> 7

  ${var%.*}    .* सँग मिल्ने सबैभन्दा छोटो प्रत्यय हटाउँछ
  ${var%%.*}   .* सँग मिल्ने सबैभन्दा लामो  प्रत्यय हटाउँछ
  ${var#*.}    *. सँग मिल्ने सबैभन्दा छोटो उपसर्ग हटाउँछ
  ${var##*.}   *. सँग मिल्ने सबैभन्दा लामो  उपसर्ग हटाउँछ
  ${var/a/b}   a को पहिलो घटना b ले प्रतिस्थापन गर्छ
  ${var//a/b}  a का सबै घटना b ले प्रतिस्थापन गर्छ
  ${var^^}     सबै ठूलो अक्षर
  ${var,,}     सबै सानो अक्षर
  ${var:2:4}   अफसेट 2 बाट लम्बाइ 4 को सबस्ट्रिङ
  ${#var}      स्ट्रिङको लम्बाइ
  ${var:-def}  सेट भए त्यसको मान, नभए def

13. SH I/O पुनर्निर्देशन
------------------------
  cmd > file      stdout अधिलेखन
  cmd >> file     stdout मा थप्ने
  cmd < file      फाइलबाट stdin
  cmd 2> file     stderr फाइलमा
  cmd 2>&1        stderr लाई stdout मा मर्ज
  cmd > f 2>&1    stdout र stderr दुवै फाइलमा

  Here-document (stdin मा इनपुट):
    cmd <<EOF       EOF सम्मका मुख्य पङ्क्ति; $VAR विस्तार हुन्छ
    cmd <<'EOF'     EOF सम्मका मुख्य पङ्क्ति; विस्तार छैन (शाब्दिक)
    cmd <<-EOF      <<EOF जस्तै, तर पङ्क्ति-सुरुका TAB अक्षर हटाइन्छ

14. SH संयुक्त आदेश
-------------------
  cmd1 && cmd2    cmd1 सफल भएमा मात्र cmd2 चलाउँछ
  cmd1 || cmd2    cmd1 असफल भएमा मात्र cmd2 चलाउँछ
  cmd1 ; cmd2     बिनाशर्त cmd2 चलाउँछ

यो पनि हेर्नुहोस्: https://metacpan.org/dist/BATsh
