আপনি কিভাবে একটি স্ট্রিং থেকে একটি স্বেচ্ছাসেবী নেটিভ কমান্ড কার্যকর?


208

আমি নিম্নলিখিত দৃশ্যের সাথে আমার প্রয়োজনটি প্রকাশ করতে পারি: একটি ফাংশন লিখুন যা নেটিজ কমান্ড হিসাবে চালানোর জন্য একটি স্ট্রিং গ্রহণ করে।

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

  1. কমান্ডটি হয়ত কোনও প্রোগ্রামে একটি ফাঁকা জায়গা সহ বাস করে:

    $command = '"C:\Program Files\TheProg\Runit.exe" Hello';
  2. কমান্ডের ফাঁকা জায়গাগুলির সাথে প্যারামিটার থাকতে পারে:

    $command = 'echo "hello world!"';
  3. কমান্ডটিতে একক এবং ডাবল দুটি টিক থাকতে পারে:

    $command = "echo `"it`'s`"";

এটি সম্পাদন করার কোনও পরিষ্কার উপায় আছে কি ? আমি কেবল উদাসীন এবং কুৎসিত কাজের কাঠামো তৈরি করতে সক্ষম হয়েছি, তবে একটি স্ক্রিপ্টিং ভাষার জন্য আমার মনে হয় এটি মরা সহজ হওয়া উচিত।

উত্তর:


318

Invoke-Expression, হিসাবে aliised iex। নিম্নলিখিত আপনার # 2 এবং # 3 উদাহরণগুলিতে কাজ করবে:

iex $command

কিছু স্ট্রিং যেমন হয় তেমন চলতে পারে না যেমন আপনার উদাহরণ # 1 কারণ এপিকেট উদ্ধৃতিতে রয়েছে। এটি যেমন রয়েছে তেমন কাজ করবে কারণ স্ট্রিংয়ের বিষয়বস্তু হ'ল আপনি পাওয়ারশেল কমান্ড প্রম্পট থেকে সরাসরি কীভাবে এটি চালাবেন:

$command = 'C:\somepath\someexe.exe somearg'
iex $command

যাইহোক, যদি এই এক্সিকেটের উদ্ধৃতিগুলিতে থাকে তবে &এটি চালানোর জন্য আপনার সাহায্যের প্রয়োজন , উদাহরণস্বরূপ, কমান্ডলাইন থেকে চালিত হিসাবে:

>> &"C:\Program Files\Some Product\SomeExe.exe" "C:\some other path\file.ext"

এবং তারপর স্ক্রিপ্টে:

$command = '"C:\Program Files\Some Product\SomeExe.exe" "C:\some other path\file.ext"'
iex "& $command"

সম্ভবত, আপনি কমান্ড স্ট্রিংয়ের প্রথম অক্ষরটি "এই নিখুঁত বাস্তবায়নের মতো কিনা তা সনাক্ত করে প্রায় সমস্ত ক্ষেত্রে পরিচালনা করতে পারবেন :

function myeval($command) {
    if ($command[0] -eq '"') { iex "& $command" }
    else { iex $command }
}

তবে আপনি অন্য কিছু ক্ষেত্রে খুঁজে পেতে পারেন যা ভিন্ন উপায়ে প্রার্থনা করতে হবে। try{}catch{}সেক্ষেত্রে আপনাকে অবশ্যই নির্দিষ্ট ব্যতিক্রম / বার্তাগুলির জন্য বা কমান্ডের স্ট্রিং পরীক্ষা করতে হবে।

আপনি যদি সর্বদা আপেক্ষিক পাথের পরিবর্তে নিখুঁত পাথগুলি পান তবে উপরের ২ টির বাইরেও আপনার বিশেষ বিশেষ কিছু হওয়া উচিত নয়।


3
এলিয়াসিং দুর্দান্ত। মনে রাখবেন, আপনি যদি অন্য কোনও মেশিনে যান বা অন্য কারও কাছে সেই স্ক্রিপ্টটি প্রেরণ করেন তবে সম্ভবত উপন্যাসটি সেটআপ হবে না। পাওয়ারশেল ফাংশনগুলির পুরো নামগুলি পছন্দ করুন।
ডগ ফিঙ্কে

1
@ ডউগ: বেশিরভাগ সময় আমি এটি করি বা অন্তর্নির্মিত এলিয়াসগুলি ব্যবহার করি (বিশেষত কমান্ডলাইনে সংকোচনের জন্য)। evalকিছু অর্ধ joking কারণ যে তা অন্যান্য অনেক স্ক্রিপ্টিং ভাষায় বলা হয়, এবং এই প্রথম প্রশ্ন আমি দেখেছি যেখানে কেউ সম্পর্কে কোন ধারণা ছিল না নয় invoke-expression। এবং ওপি-র ক্ষেত্রে কেবল অভ্যন্তরীণ স্ক্রিপ্টের মতো মনে হচ্ছে।
জোয়েল বি ফ্যান্ট

আমি এটি চেষ্টা করেছি, তবে এটি এর সাথে কাজ করে না: $ কমান্ড = '"সি: \ প্রোগ্রাম ফাইলগুলি \ উইন্ডোজ মিডিয়া প্লেয়ার \ mplayer2.exe" "এইচ: \ অডিও \ সঙ্গীত \ স্টিভির ওয়ান্ডার \ স্টিভির ওয়ান্ডার - সুপারস্টিশন.এমপি 3" '
জনি কাউফম্যান

3
আপনাকে একটি "&" বা "রাখতে হবে। প্রকৃত কমান্ড সামনে সাইন যদি এটা PowerShell-নেটিভ, যেমন নয়Invoke-Expression "& $command"
Torbjörn Bergstedt

Torbjörn বার্গস্টেট জিতেছে! Theন্দ্রজালিক অতিরিক্ত "&" আমার সমস্যার সমাধান করেছে! ফলস্বরূপ, আমি উভয়ই খুশি এবং তেজস্ক্রিয়।
জনি কাউফম্যান

19

দয়া করে এই মাইক্রোসফ্ট সংযোগের প্রতিবেদনটি মূলত দেখুন, শেল কমান্ড চালানোর জন্য পাওয়ারশেল ব্যবহার করা কতটা অসুবিধাজনক (ওহ, বিড়ম্বনা) bl

http://connect.microsoft.com/PowerShell/feedback/details/376207/

তারা --%পাওয়ারশেলকে ডানদিকে পাঠ্যের ব্যাখ্যা করার চেষ্টা বন্ধ করতে বাধ্য করার উপায় হিসাবে পরামর্শ দেয় suggest

উদাহরণ স্বরূপ:

MSBuild /t:Publish --% /p:TargetDatabaseName="MyDatabase";TargetConnectionString="Data Source=.\;Integrated Security=True" /p:SqlPublishProfilePath="Deploy.publish.xml" Database.sqlproj

1
আহ, এবং মাইক্রোসফ্ট ইন্টারনেট ভেঙেছে এবং লিঙ্কটি আর বৈধ নয়।
জোহান বুলি

1
উপরের লিঙ্কটি এ archive.org হয় web.archive.org/web/20131122050220/http://...
mwfearnley

4

আনইনস্টল স্ট্রিংগুলির জন্য রেজিস্ট্রিটি বিশ্লেষণ করার এবং সেগুলি সম্পাদন করার সময় গ্রহণযোগ্য উত্তর আমার পক্ষে কাজ করছে না। দেখা যাচ্ছে আমার Invoke-Expressionসর্বোপরি কল করার দরকার নেই ।

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

$path = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
$app = 'MyApp'
$apps= @{}
Get-ChildItem $path | 
    Where-Object -FilterScript {$_.getvalue('DisplayName') -like $app} | 
    ForEach-Object -process {$apps.Set_Item(
        $_.getvalue('UninstallString'),
        $_.getvalue('DisplayName'))
    }

foreach ($uninstall_string in $apps.GetEnumerator()) {
    $uninstall_app, $uninstall_arg = $uninstall_string.name.split(' ')
    & $uninstall_app $uninstall_arg
}

এটি আমার পক্ষে কাজ করে, কারণ $appএকটি গৃহ অ্যাপ্লিকেশন যা আমি জানি যে কেবল দুটি যুক্তি থাকবে। আরও জটিল আনইনস্টল স্ট্রিংয়ের জন্য আপনি জয়েন অপারেটরটি ব্যবহার করতে চাইতে পারেন । এছাড়াও, আমি সবেমাত্র একটি হ্যাশ-মানচিত্র ব্যবহার করেছি, তবে সত্যই, আপনি সম্ভবত একটি অ্যারে ব্যবহার করতে চান।

এছাড়াও, যদি আপনার কাছে একই অ্যাপ্লিকেশনটির একাধিক সংস্করণ ইনস্টল করা থাকে তবে এই আনইনস্টলারটি তাদের একবারে একবারে চক্র করবে, যা বিভ্রান্ত করে MsiExec.exe, তাই সেগুলিও রয়েছে।


1

আপনি যদি কল অপারেটরটি ব্যবহার করতে চান, আর্গুমেন্টগুলি কোনও ভেরিয়েবলের মধ্যে সঞ্চিত অ্যারে হতে পারে:

$prog = 'c:\windows\system32\cmd.exe'
$myargs = '/c','dir','/x'
& $prog $myargs

কল অপারেটরটি অ্যাপ্লিকেশনআইনফো অবজেক্টগুলির সাথেও কাজ করে।

$prog = get-command cmd
$myargs = -split '/c dir /x'
& $prog $myargs
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.