BATsh চিটশিট [BN] বাংলা
=======================

----------------------------------------------------------------------
সারসংক্ষেপ
  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 -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 সিনট্যাক্স
চালায়।  স্ক্রিপ্টটি বিভাগে ভাগ করা হয়; প্রতিটি বিভাগ উপযুক্ত শেল দ্বারা
হুবহু নির্বাহিত হয়।

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    cmd2 চালান কেবল যদি cmd1 সফল হয়
  cmd1 || cmd2    cmd2 চালান কেবল যদি cmd1 ব্যর্থ হয়
  cmd1 ; cmd2     cmd2 শর্তহীনভাবে চালান

আরও দেখুন: https://metacpan.org/dist/BATsh
