BATsh Лавлах хуудас [MN] Монгол
==============================

----------------------------------------------------------------------
ТОВЧ ТАЙЛБАР
  BATsh нь cmd.exe batch болон bash/sh синтаксийг нэг скрипт файлд
  ажиллуулдаг хоёр хэлт shell юм. Энэ нь мөр/хэсэг тус бүрээр горимыг
  автоматаар сольдог.
  Гадны shell шаардлагагүй -- цэвэр 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 -e 'while(<STDIN>){chomp;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 синтаксийг нэг скриптэд ажиллуулдаг хоёр
хэлт shell юм.  Скриптийг хэсгүүдэд хуваадаг; хэсэг бүрийг тохирох shell
эх хувиар нь гүйцэтгэдэг.

1. Горим илрүүлэх
-----------------
  Хэсгийн эхний утга бүхий мөрийн «эхний токен» тухайн хэсгийг аль shell
  гүйцэтгэхийг тодорхойлдог:

  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. Shell эхлүүлэх
-----------------
  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 мөрүүд).  Хэсгийн дараа shell-ийн
  эцсийн орчныг %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 руу хийнэ

  Batch-параметрийн тильд засварлагч (ж.нь %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
