سؤال

وأنا إنشاء برنامج نصي PowerShell لنشر بعض رمز وجزء من هذه العملية هو الدعوة إلى أداة ضغط سطر الأوامر تسمى RAR.EXE إلى احتياطية بعض المجلدات.

وأنا محاولة لبناء حيوي من المعلمات ومن ثم إجراء مكالمة بوويرشيل الأمر مع المتغيرات ولكن أنا على التوالي في ورطة. انها لا تعمل ...

وتشغيل البرنامج النصي التالي، ويجب أن نرى ما أتحدث عنه. المعلمات يتم تمريرها في كما يتم المهترئ متغير. إذا مررت الأمر بالكامل + المعلمات في أحصل سيئة السمعة "لم يتم التعرف على أمر cmdlet ..." رسالة.

وشكرا على اي مساعدة!

echo "this should succeed"
& cmd /c echo foo

echo "why does this echo out an additional double quote?"
$param = "/c echo foo"
& cmd "$param"

echo "this does the same"
$param = "/c echo foo"
& cmd $param

echo "escaping the slash doesn't work either..."
$param = "`/c echo foo"
& cmd $param

echo "this fails, but why?"
$cmd = "cmd /c echo foo"
&$cmd
هل كانت مفيدة؟

المحلول

والمشغل الدعوة "و" لا لزوم لها في هذه الحالة. فهو يستخدم لاستدعاء أمر في نطاق جديد. وعادة ما تستخدم هذه استدعاء الأمر المحدد من قبل سلسلة أو scriptblock. كما أن لديها مصلحة الفريق الذي أية متغيرات خلقت في القول السيناريو بوويرشيل والتخلص منها بعد انتهاء القيادة ونطاق يذهب بعيدا.

ولكن منذ كمد هو EXE ينفذ في عملية مختلفة تماما. FWIW، تحصل إخراج مشابه مباشرة من CMD.EXE:

> cmd "/c echo foo"
foo"

وهكذا الاقتباس إضافية على النهاية هو قضية CMD.EXE. وعادة ما تحتاج إلى الحفاظ على الأمر منفصلة عن المعلمات عندما بوويرشيل تقوم به إعراب استدعاء الأمر منها مثلا.

45> & { $foo = "foo" }
46> $foo  # Note that $foo wasn't found - it went away with the scope
47> . { $foo = "foo" } # dotting executes in the current scope
48> $foo 
foo

والاستثناء الملحوظ هنا هو أن استدعاء-التعبير يتصرف وكأنه "تقييم هذه السلسلة" وظيفة. استخدام مع الرعاية، <م> خاصة إذا كان المستخدم يوفر السلسلة. يومك يمكن أن تمتص إذا قدموا "ري C: \ -r".

في هذه الحالة، كما فعل آخرون قد اقترح أود أن سحب / ج من سلسلة المعلمة سلسلة $ وتحديد ذلك منها مثلا:

cmd /c $param

وأو استخدام استدعاء-التعبير ولكن استخدام بحذر. BTW عندما تحاول تصحيح الأخطاء وحل المشكلات مع إرسال الحجج لEXE من بوويرشيل، وتحقق من فائدة echoargs في بوويرشيل ملحقات المجتمع ( HTTP: / /pscx.codeplex.com ). وهو مفيد جدا:

49> $param = "/c echo foo"
50> echoargs $param
Arg 0 is </c echo foo>

وهذا يدل على أن CMD.EXE يتلقى "/ ج صدى فو" باعتباره <م> واحدة حجة. "/ ج" يجب أن يكون حجة منفصلة عن "صدى فو" (الأمر إلى تنفيذ).

نصائح أخرى

ولقد كان لي مشاكل مع واستدعاء عامل في الماضي عند محاولة استدعاء الأوامر نوع القابلة للتنفيذ وكأنك تحاول. لست متأكدا أفهم لماذا. استدعاء-التعبير ومع ذلك، يبدو دائما للعمل في هذا السياق:

PS C:\> $cmd = "cmd /c echo foo"
PS C:\> Invoke-expression $cmd
foo

وكانت ثمة طريقة أخرى وجدت أن تفعل هذا لخلق مجموعة من الحجج لسطر الأوامر واستخدام ذلك مع apersand واستدعاء المشغل. شيء من هذا القبيل:

$exe = "cmd";
[Array]$params = "/c", "echo", "foo";

& $exe $params;

وسارت الامور بشكل جيد بالنسبة لي.

ولقد وجدت في الأصل هذه التقنية هنا: http://techstumbler.blogspot.com/2009/12 /windows-commands-with-arguments-in.html

واخر مثال لديك إذا فشلت ل"و" يعامل السلسلة ك وسيطة واحدة، لذلك تبحث عن برنامج يسمى "كمد / ج صدى foo.exe". :)

وهذا يعمل:

& $cmd $params

وأما بالنسبة لمسألة الاقتباس مزدوجة، فإنه لا يبدو أن كمد لا يحب علامات الاقتباس حول الحجج التي يضع بوويرشيل. يحصل هذا:

cmd "/c echo foo"

وهكذا أعتقد أنه يعامل كل شيء بعد / ج كأمر المحدد، وذلك كما يلي:

echo foo"

وبعض البرامج سطر الأوامر والتوزيع غير تقليدي من سطر الأوامر (وهذا هو السبب يأخذ بوويرشيل خلال هذا العمل للمهام وأوامر cmdlets). في حالة كمد، أود أن أقترح هذا:

$param = "echo foo"
& cmd /c $param

وانها قطعة أثرية من استخدام كمد / ج، على ما أعتقد. تشغيل

$param = "echo foo"
cmd /c $param

ويعمل بشكل جيد. لم يكن لديك المثال رمز حقيقي، فمن الصعب بعض الشيء لمشكلة تبادل لاطلاق النار.

يتم التعامل مع

وسائط مختلفة عندما كانت مضمنة في سلسلة:

PS D:\> echo "1 2 3"
1 2 3
PS D:\> echo 1 2 3
1
2
3

وتحدث نفس النتائج عند استخدام متغير لوسائط:

PS D:\> $param = "1 2 3"
PS D:\> echo $param
1 2 3

والحل هو استخدام صفيف:

PS D:\> $param = @(1,2,3)
PS D:\> echo $param
1
2
3
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top