উইন্ডোজ b ব্যাচের ফাইল: কেন এই আইএফ ব্লকগুলি আমাকে একটি মানকে ভেরিয়েবল বরাদ্দ করা থেকে আটকাচ্ছে?


6

ভাঙা ব্যাচের ফাইলটি এখানে:

@echo off
if prod==prod (
    if xps==xps (
        set i1=prodxpsi1
        set i2=prodxpsi2
        set e1=prodxpse1
        set e2=prodxpse2
    ) else (
        set i1=prodzpsi1
        set i2=prodzpsi2
        set e1=prodzpse1
        set e2=prodzpse2
    )

    if 1==1 (
        echo %i1%, %i2%, %e1%, %e2%
    ) else (
        echo %i1%, %i2%, %e1%, %e2%
    )
)

pause

যাইহোক, আমি যখন if prod==prodএইরকম বাইরের ব্লকটি বের করি তখন এটি কাজ করে:

@echo off
if xps==xps (
    set i1=prodxpsi1
    set i2=prodxpsi2
    set e1=prodxpse1
    set e2=prodxpse2
) else (
    set i1=prodzpsi1
    set i2=prodzpsi2
    set e1=prodzpse1
    set e2=prodzpse2
)

if 1==1 (
    echo %i1%, %i2%, %e1%, %e2%
) else (
    echo %i1%, %i2%, %e1%, %e2%
)

pause

আমি যখন ব্যাচ ফাইলটি প্রথমবার চালিত করি তখন এটি প্রতিধ্বনিত হয় , , ,। আমি যখন দ্বিতীয়বার এটি চালাই, তখন এটি ঠিকঠাক কাজ করে:

lolwut


আমি দুর্ঘটনাক্রমে আমার পরিবেশে আই 1, আই 2, ই 1 এবং ই 2 ফেলে দিয়ে আমার প্রথম উত্তরটি আঁকিয়েছি। আমার নতুন উত্তরটি আপনি যা খুঁজছেন তা হওয়া উচিত!
স্টিফেন জেনিংস

উত্তর:


5

এটি হ'ল কমান্ড পার্সারের একটি ছদ্মবেশ। কারণ বন্ধনীর, তা থেকে সবকিছু দেখেন if ...করার )এক লাইন হিসাবে। এটি যখন এই "একটি লাইন" পড়ে, এটির কোনও প্রক্রিয়া করার আগে এটি সমস্ত ভেরিয়েবলগুলি তাদের মানগুলিতে প্রসারিত করে। setকমান্ড ভেরিয়েবল পরে occcur সম্প্রসারিত করা হয়েছে।

দুটি সমাধান রয়েছে: শাখা এবং বিলম্বিত প্রসার।

শাখা:set কমান্ড এবং echoকমান্ড শীর্ষ-বন্ধনীগুলির একই সেটে নেই তা নিশ্চিত করুন :

@echo off
if not prod==prod goto :end
if xps==xps (
    set ...
) else (
    set ...
)
if 1==1 (
    ...
)
:end
pause

বিলম্বিত সম্প্রসারণ: এর ফলে আগাম পরিবর্তে পরিবর্তনের প্রয়োজন অনুসারে প্রসারিত হতে পারে। SetLocal EnableDelayedExpansionএই মোডটি সক্রিয় করতে কমান্ডটি ব্যবহার করুন, ব্যবহার করুন! এই পদ্ধতিতে কোনও ভেরিয়েবলকে চিহ্নিত করতে চিহ্নিত করে এবং EndLocalআপনার হয়ে গেলে কমান্ডটি ব্যবহার করুন । নোটটি যে EndLocalকোনও ঘোষিত ভেরিয়েবলের পরে ভুলে যাবে SetLocal, তাই আপনি কমান্ডগুলির SetLocalপরে যেতে চাইবেন set

@echo off
setlocal enabledelayedexpansion
if prod==prod (
    if xps==xps (
        set i1=prodxpsi1
        ...
    ) else (
        set i1=prodzpsi1
        ...
    )
    if 1==1 (
        echo !i1!, !i2!, !e1!, !e2!
    ) else (
        echo !i1!, !i2!, !e1!, !e2!
    )
)
endlocal
pause

ঠিক আমার চিন্তা। বিলম্বিত প্রসারণ।
সারফাসব

এনবি "গোটো: ইওএফ" "ফাইলের শেষে যান" এর সমতুল্য। এটি "কল: মাইসুব" হিসাবে যেমন ব্যাচ "সাবরটাইনগুলি" থেকে "ফিরতে" ব্যবহৃত হয়।
বিলপি 3 ই

1
@ বিলপ থার্ড: চমৎকার! আমি Exit /Bএকই উদ্দেশ্যে ব্যবহার করার ঝোঁক ।
হ্যান্ড-ই-ফুড

এবং আমি খুব শিখেছি ... আপনার পদ্ধতিটি ERRORLEVEL সেট করতে পারে। কুল!
বিলপি 3 ই

উজ্জ্বল! কেউ কীভাবে এমন কিছু জানতে পারে?
oscilatingcretin

3

যদি আপনি বিলম্বিত প্রসারণ সক্ষম করেন, তবে !var!ভেরিয়েবলগুলি উল্লেখ করতে সিনট্যাক্স ব্যবহার করুন , তবে এটি আপনার প্রত্যাশা অনুযায়ী আচরণ করে।

@echo off

setlocal enabledelayedexpansion

if prod==prod (
    if xps==xps (
        set i1=prodxpsi1
        set i2=prodxpsi2
        set e1=prodxpse1
        set e2=prodxpse2
    ) else (
        set i1=prodzpsi1
        set i2=prodzpsi2
        set e1=prodzpse1
        set e2=prodzpse2
    )

    if 1==1 (
        echo !i1!, !i2!, !e1!, !e2!
    ) else (
        echo !i1!, !i2!, !e1!, !e2!
    )
)

সহায়তা পাঠ্য ( cmd /?) ব্যাখ্যা করে:

/ ভি: অন - বিলম্বিত পরিবেশের পরিবর্তনশীল প্রসারণটি ব্যবহার করে সক্ষম করুন! সীমানা হিসাবে উদাহরণস্বরূপ, / ভি: অন অনুমতি দেয়! Var! এক্সিকিউশন সময়ে ভেরিয়েবল ভার প্রসারিত করতে। ভের সিনট্যাক্স ইনপুট সময়ে ভেরিয়েবলগুলি প্রসারিত করে যা কোনও ফর লুপের অভ্যন্তরে যখন একেবারে আলাদা জিনিস।

যদি বিলম্বিত পরিবেশের ভেরিয়েবল প্রসারণ সক্ষম করা হয় তবে এক্সক্লিমেশন চরিত্রটি কার্যকরকরণের সময় পরিবেশের পরিবর্তনশীলের মান পরিবর্তনে ব্যবহার করা যেতে পারে।

আপনি যখন কোনও ifবিবৃতিতে পুরো জিনিসটি মুড়ে রাখেন তখন পুরো ব্লকটি মূলত একটি কমান্ড হয়ে যায়। কমান্ডের ভিতরে সমস্ত ভেরিয়েবলগুলি ইনপুট দেওয়ার সময় প্রসারিত হয়, যা if xps==xpsঅংশটি শুরুর আগে । স্ক্রিপ্টের সেই মুহুর্তে, ভেরিয়েবলগুলি এখনও সংজ্ঞায়িত করা হয়নি।

!var!বিলম্বিত প্রসারণের সাথে বাক্য গঠন ব্যবহার করে , তবে !i1!নির্দিষ্ট রেখাটি কার্যকর না হওয়া পর্যন্ত এর মান মূল্যায়ন করা হয় না।

ধন্যবাদ! আপনার প্রশ্ন আমাকে আজ কিছু শিখিয়েছে!


0

পুরো cmdস্টাফ আরও প্রিপ্রোসেসরের মতো কাজ করে যা একবার ফাইল চালায়, প্রিপ্রোসেসড 'রিয়েল' ফাইল তৈরি করে এবং তারপরে এটি চালায়। এর অর্থ এই যে cmd(পরিবর্তনশীল) পরিবর্তনশীল (বা forএকটি 'ভেরিয়েবল') এর পরিবর্তিত সামগ্রীর উপর ভিত্তি করে লুপগুলি পুনরায় মূল্যায়ন করে না ।

যেহেতু আপনার সমস্যার বর্ণনাটি কিছুটা অস্পষ্ট: আপনি 'প্রোড' এবং 'এক্সপিএস' স্ট্রিংয়ের পরিবর্তে ভেরিয়েবল ব্যবহার করেন এবং এই 'ভেরিয়েবলগুলি'র গতিশীল ব্যাখ্যা আশা করেন?


আসলে, ব্যাচ ফাইলগুলি একবারে "প্রিপ্রোসেসড" হয় না। তারা একবারে এক লাইনে পড়ে এবং প্রক্রিয়াজাত হয়। এটি প্রদর্শন করা সহজ। যেখানে বিলম্বিত সম্প্রসারণ খেলতে আসে সেখানে একাধিক লাইন একক লাইন হিসাবে পড়া হয়, যেমন: যদি 1 == 1 (foo এবং বার ও বাজ)) () এর সামগ্রীগুলি একবারে পড়তে হবে তবে নিম্নলিখিত কিছু নয়।
বিলপি 3 ই

@ বিলপি 3 তম: তবে 'ফর'-লুপগুলির জন্য প্রভাবটি যদি এটি প্রস্রোসেসড হয়ে যায় এবং একটি বিশাল প্রিপ্রোসেসড ব্যাচ ফাইল (তারপরে একটি সময়ে একটি লাইন) কার্যকর করা হয়।
আকির

@ কীরা, আমি মনে করি আপনি যা বোঝাতে চেয়েছেন তা প্রতিটি লাইন এবং বন্ধনীবদ্ধ ব্লক প্রিক্রোসেসড। শুরুতে এবং শেষে বন্ধনীগুলির সাথে মিলে, তবে হ্যাঁ, এটি পুরো ফাইলটিকে প্রসেসোসেস করে।
হ্যান্ড-ই-ফুড

0

নিম্নলিখিত প্রোগ্রামগুলি হ'ল আইএফ স্টেটমেন্টের মধ্যে একই স্টেটমেন্টের মধ্যে একটি ভেরিয়েবল সেটের মান ব্যবহার করার সহজ চিত্রণ। তারা কোনও প্যারামিটার প্রবেশ না করা হলে 'আ', এবং কোনও পরামিতি প্রবেশ করানো হলে 'বিবি' প্রদর্শন করার উদ্দেশ্যে রয়েছে। উদাহরণ 1 কেবলমাত্র 'এ' প্রদর্শন করে যদি কোনও প্যারামিটার না থাকে। অন্যান্য উদাহরণগুলি সমস্ত সঠিকভাবে কাজ করে।

আমার মতে, উদাহরণ 2, যা 'গোটো'স ব্যবহার করে, এটি সবচেয়ে সোজা এবং বোঝা সহজ।

উদাহরণস্বরূপ 2, 5 এবং 6 আইএফ স্টেটমেন্টের বাইরে ঝামেলা কোডটি নিয়ে কাজ করে।

@echo off & setlocal enableextensions & :: 1
if "%1" equ "" (
   set x=a
   set y=%x%
   ) else (
   set x=b
   set y=b
   )
echo %x%%y%

@echo off & setlocal enableextensions & :: 2
if "%1" neq "" goto 10
   set x=a
   set y=%x%
   goto 20
   :10
   set x=b
   set y=b
:20
echo %x%%y%

@echo off & setlocal enableextensions & :: 3
setlocal enabledelayedexpansion
if "%1" equ "" (
   set x=a
   set y=!x!
   ) else (
   set x=b
   set y=b
   )
endlocal & set "x=%x%" & set "y=%y%"
echo %x%%y%

নিম্নলিখিত উদাহরণে, 'অন্য' ব্লকের 'সেটলোকাল' নোট করুন। এটি 'এন্ডলোকাল' এর সাথে মেলে যাতে ভেরিয়েবলগুলি 'এক্স' এবং 'ওয়াই' প্রোগ্রামে স্থানীয় থাকে। (অন্যথায়, 'এন্ডলোকাল' প্রথম লাইনে 'সেটলোকাল' বাতিল করে))

@echo off & setlocal enableextensions & :: 4
if "%1" equ "" (
   set x=a
   setlocal enabledelayedexpansion
   set y=!x!
   ) else (
   set x=b
   set y=b
   setlocal
   )
endlocal &  set "y=%y%"
echo %x%%y%

@echo off & setlocal enableextensions & :: 5
if "%1" equ "" (
   call :seta
   ) else (
   call :setb
   )
echo %x%%y%
exit /b
:seta
   set x=a
   set y=%x%
   exit/b
:setb
   set x=b
   set y=b
   exit/b

@echo off & setlocal enableextensions & :: 6
set x=a
if "%1" equ "" (
   set y=%x%
   ) else (
   set x=b
   set y=b
   )
echo %x%%y%
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.