আমি কীভাবে বর্তমান পাওয়ারশেল সম্পাদনকারী ফাইল পেতে পারি?


94

দ্রষ্টব্য: পাওয়ারশেল 1.0
আমি বর্তমান সম্পাদনকারী পাওয়ারশেল ফাইলটির নাম পেতে চাই। এটি হ'ল, যদি আমি এইভাবে আমার সেশনটি শুরু করি:

powershell.exe .\myfile.ps1

আমি "।" Myfile.ps1 " (বা এর মতো কিছু) স্ট্রিং পেতে চাই। সম্পাদনা : "মাইফাইল.পিএস 1" পছন্দনীয়।
কোন ধারনা?


ধন্যবাদ, বর্তমান উত্তরগুলি প্রায় একই, তবে আমার কেবলমাত্র ফাইলের নাম প্রয়োজন (এবং পুরো পথ নয়), তাই গৃহীত উত্তরগুলি হ'ল @ কিথের। যদিও উভয় জবাব উত্তর +1। এখন আমি $ মাই ইনভোকেশন জিনিস সম্পর্কে :-) সম্পর্কে জানি
রন ক্লেইন

একটি অন্তর্ভুক্ত স্ক্রিপ্ট থেকে পিতামাতার স্ক্রিপ্ট সম্পর্কে কীভাবে?
ফ্লোরিন সাবাউ

উত্তর:


73

আমি পাওয়ারশেল 5 এর জন্য আপডেট হওয়া এখানে বিভিন্ন উত্তর সংক্ষিপ্ত করার চেষ্টা করেছি:

  • আপনি যদি কেবল পাওয়ারশেল 3 বা তার বেশি ব্যবহার করেন তবে ব্যবহার করুন $PSCommandPath

  • যদি পুরানো সংস্করণগুলির সাথে সামঞ্জস্যতা চান তবে শিমটি প্রবেশ করুন:

    if ($PSCommandPath -eq $null) { function GetPSCommandPath() { return $MyInvocation.PSCommandPath; } $PSCommandPath = GetPSCommandPath; }

    এটি $PSCommandPathইতিমধ্যে বিদ্যমান না থাকলে এটি যুক্ত করে।

    শিম কোডটি যে কোনও জায়গায় কার্যকর করা যেতে পারে (শীর্ষ স্তরের বা কোনও ফাংশনের অভ্যন্তরে), যদিও $PSCommandPathভেরিয়েবলটি সাধারণ স্কোপিং বিধিগুলির অধীন (যেমন, আপনি যদি কোনও ফাংশনে শিমটি রাখেন তবে ভেরিয়েবলটি কেবল সেই ফাংশনটিতে স্কোপ করা হয়)।

বিশদ

বিভিন্ন উত্তরে 4 টি পৃথক পদ্ধতি ব্যবহৃত হয়েছে, সুতরাং আমি প্রতিটি (যোগ $PSCommandPath) প্রদর্শন করার জন্য এই স্ক্রিপ্টটি লিখেছিলাম :

function PSCommandPath() { return $PSCommandPath; }
function ScriptName() { return $MyInvocation.ScriptName; }
function MyCommandName() { return $MyInvocation.MyCommand.Name; }
function MyCommandDefinition() {
    # Begin of MyCommandDefinition()
    # Note: ouput of this script shows the contents of this function, not the execution result
    return $MyInvocation.MyCommand.Definition;
    # End of MyCommandDefinition()
}
function MyInvocationPSCommandPath() { return $MyInvocation.PSCommandPath; }

Write-Host "";
Write-Host "PSVersion: $($PSVersionTable.PSVersion)";
Write-Host "";
Write-Host "`$PSCommandPath:";
Write-Host " *   Direct: $PSCommandPath";
Write-Host " * Function: $(ScriptName)";
Write-Host "";
Write-Host "`$MyInvocation.ScriptName:";
Write-Host " *   Direct: $($MyInvocation.ScriptName)";
Write-Host " * Function: $(ScriptName)";
Write-Host "";
Write-Host "`$MyInvocation.MyCommand.Name:";
Write-Host " *   Direct: $($MyInvocation.MyCommand.Name)";
Write-Host " * Function: $(MyCommandName)";
Write-Host "";
Write-Host "`$MyInvocation.MyCommand.Definition:";
Write-Host " *   Direct: $($MyInvocation.MyCommand.Definition)";
Write-Host " * Function: $(MyCommandDefinition)";
Write-Host "";
Write-Host "`$MyInvocation.PSCommandPath:";
Write-Host " *   Direct: $($MyInvocation.PSCommandPath)";
Write-Host " * Function: $(MyInvocationPSCommandPath)";
Write-Host "";

আউটপুট:

PS C:\> .\Test\test.ps1

PSVersion: 5.1.19035.1

$PSCommandPath:
 *   Direct: C:\Test\test.ps1
 * Function: C:\Test\test.ps1

$MyInvocation.ScriptName:
 *   Direct:
 * Function: C:\Test\test.ps1

$MyInvocation.MyCommand.Name:
 *   Direct: test.ps1
 * Function: MyCommandName

$MyInvocation.MyCommand.Definition:
 *   Direct: C:\Test\test.ps1
 * Function:
    # Begin of MyCommandDefinition()
    # Note this is the contents of the MyCommandDefinition() function, not the execution results
    return $MyInvocation.MyCommand.Definition;
    # End of MyCommandDefinition()


$MyInvocation.PSCommandPath:
 *   Direct:
 * Function: C:\Test\test.ps1

মন্তব্য:

  • কার্যকর করা হয়েছে C:\, তবে প্রকৃত স্ক্রিপ্টটি C:\Test\test.ps1
  • কোনও পদ্ধতি আপনাকে পাসের আহবানের পথটি বলে না ( .\Test\test.ps1)
  • $PSCommandPath একমাত্র নির্ভরযোগ্য উপায়, তবে পাওয়ারশেল 3 তে চালু হয়েছিল
  • 3 এর পূর্ববর্তী সংস্করণগুলির জন্য, কোনও ফাংশনের ভিতরে এবং বাইরে কোনও একক পদ্ধতি কাজ করে না

7
আজ (2017) পড়ছেন এমন যে কোনও ব্যক্তির জন্য তাদের এই উত্তরটি সঠিক উত্তর হিসাবে পড়া উচিত! +1
কলিন চ্যাফিন

4
@ কলিনচ্যাফিন: একমত হয়েছে এবং এখন (2017) সর্বনিম্ন সমর্থিত উইন্ডোজ is তাই $PSCommandPathলিগ্যাসি (উইন্ডোজএক্সপি) প্রয়োজন না হলে ব্যবহার না করার কারণ নেই ।
টুকান

প্রথম কোড উদাহরণটি ত্রুটিযুক্ত কারণ এতে একই ফাংশন ( function PSCommandPath) এর দুটি সংজ্ঞা এবং ভুল ফাংশনের একটি উল্লেখ রয়েছে ( Write-Host " * Direct: $PSCommandPath"; Write-Host " * Function: $(ScriptName)";- বা আমি কি কিছু সুস্পষ্ট উপেক্ষা করছি?
মাইক

@ মাইকেল'এঞ্জেলো ঠিক বলেছেন! 3 বছরের জন্য অলক্ষিত হয়েছে। স্থির, আপনাকে ধন্যবাদ। আউটপুট এবং উপসংহার যদিও একই।
গ্রেগম্যাক

81

যদিও বর্তমান উত্তর বেশিরভাগ ক্ষেত্রে সঠিক, তবে এমন কিছু পরিস্থিতি রয়েছে যা এটি আপনাকে সঠিক উত্তর দেয় না। আপনি যদি আপনার স্ক্রিপ্ট ফাংশনের ভিতরে ব্যবহার করেন তবে:

$MyInvocation.MyCommand.Name 

স্ক্রিপ্টের নামের পরিবর্তে ফাংশনের নামটি ফিরিয়ে দেয়।

function test {
    $MyInvocation.MyCommand.Name
}

আপনার স্ক্রিপ্টটির নাম দেওয়া হোক না কেন আপনাকে " পরীক্ষা " দেবে। স্ক্রিপ্টের নাম পাওয়ার জন্য সঠিক কমান্ড সর্বদা

$MyInvocation.ScriptName

এটি আপনি সম্পাদনা করছেন এমন স্ক্রিপ্টের পুরো পথটি ফিরিয়ে দেয়। এই কোডটির চেয়ে আপনার যদি কেবল স্ক্রিপ্ট ফাইলের প্রয়োজন হয় তবে আপনাকে সহায়তা করা উচিত:

split-path $MyInvocation.PSCommandPath -Leaf

6
নোট করুন যে শীর্ষ স্তরে, স্ক্রিপ্টনামটি পোষ ভি 4 এর সাথে অপরিজ্ঞাত। আমি শীর্ষ স্তরে ব্যবহার করতে চাই, $ MyInvocation.MyCommand.Difinition for पूर्ण পথ বা অন্য উত্তর অনুসারে নাম।
অ্যানিএগাইল

30
$MyInvocation.ScriptNameআমার জন্য খালি স্ট্রিং ফিরে, পিএস v3.0।
জনসি

4
@ জনসি $MyInvocation.ScriptNameশুধুমাত্র একটি ফাংশনের ভিতরে থেকেই কাজ করে। দেখুন নিচের আমার উত্তর
গ্রেগম্যাক

72

আপনি যদি কেবল ফাইলের নাম চান (পুরো পাথ নয়) এটি ব্যবহার করুন:

$ScriptName = $MyInvocation.MyCommand.Name

32

নিম্নলিখিত চেষ্টা করুন

$path =  $MyInvocation.MyCommand.Definition 

এটি আপনাকে টাইপ করা প্রকৃত পাথ না দেয় তবে এটি আপনাকে ফাইলের একটি বৈধ পথ দেয়।


4
@ হামিশ প্রশ্নটি বিশেষত বলেছে যদি কোনও ফাইল থেকে আবেদন করা হয়।
জেয়ার্ডপাড়

এফওয়াইআই: এটি আপনাকে পুরো পথ এবং ফাইলের নাম দেয় (
পাওয়ারশেল

আমি ঠিক এই আদেশটি অনুসন্ধান করছিলাম। ধন্যবাদ, জারেডপার! :)
স্কলফুল

ডিরেক্টরি পেতে স্প্লিট-পাথ ব্যবহার করবেন? $path = Split-Path $MyInvocation.MyCommand.Definition -Parent
25-18

7

আপনি যদি বর্তমান ডিরেক্টরিটি সন্ধান করছেন যেখানে স্ক্রিপ্টটি কার্যকর হচ্ছে, আপনি এটি চেষ্টা করতে পারেন:

$fullPathIncFileName = $MyInvocation.MyCommand.Definition
$currentScriptName = $MyInvocation.MyCommand.Name
$currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "")

Write-Host $currentExecutingPath

4
এটি সঠিকভাবে কাজ করবে না C:\ilike.ps123\ke.ps1, তাই না?
ফ্রিডোজেট

@ ফ্রিডোজেট - নিশ্চিত নয়, এটি পরীক্ষা করার জন্য কোনও পিএস টার্মিনালের কাছে নয়। কেন আপনি এটি চেষ্টা করে দেখুন না?
Ryk

না, কেবল একটি অলঙ্কৃত প্রশ্ন ;-) - এটি কেবল যুক্তিযুক্ত হবে কারণ Replace()পদ্ধতিটি সুইয়ের প্রতিটি ঘটনাকে প্রতিস্থাপন করে (কেবল শেষ ঘটনা নয়) এবং আমি এটিও পরীক্ষা করে দেখেছি। তবে স্ট্রিংগুলিতে বিয়োগের মতো কিছু করা ভাল ধারণা idea
ফ্রিডোজেট

... String.TrimEnd()( কি $currentExecutingPath = $fullPathIncFileName.TrimEnd($currentScriptName))? - এটি সঠিকভাবে কাজ করছে: "Ich bin Hamster".TrimEnd("ster")রিটার্ন Ich bin Hamএবং "Ich bin Hamsterchen".TrimEnd("ster")রিটার্ন Ich bin Hamsterchen(পরিবর্তে Ich bin Hamchen) - দুর্দান্ত!
ফ্রিডোজেট

$currentScriptPath = $MyInvocation.MyCommand.Definition; $currentScriptName = $MyInvocation.MyCommand.Name; $currentScriptDir = $currentScriptPath.Substring(0,$currentScriptPath.IndexOf($currentScriptName));
YP

7

সাবধানতা: $PSScriptRoot$PSCommandPathঅটোমেটিক ভেরিয়েবলের বিপরীতে, স্বয়ংক্রিয় ভেরিয়েবলের PSScriptRootএবং PSCommandPathবৈশিষ্ট্যগুলিতে $MyInvocationবর্তমান স্ক্রিপ্ট নয়, চালক বা কলিং স্ক্রিপ্ট সম্পর্কিত তথ্য রয়েছে।

যেমন

PS C:\Users\S_ms\OneDrive\Documents> C:\Users\SP_ms\OneDrive\Documents\DPM ...
=!C:\Users\S_ms\OneDrive\Documents\DPM.ps1

... যেখানে DPM.ps1রয়েছে

Write-Host ("="+($MyInvocation.PSCommandPath)+"!"+$PSCommandPath)

4

আমি যুক্তি দিয়ে বলব যে ভেরিয়েবলের $ MyInvocation.MyCommand.Path এর সুযোগটি সেট করে একটি আরও ভাল পদ্ধতি আছে:

প্রাক্তন> $ লিপি : MyInvocation.MyCommand.Name

এই পদ্ধতিটি অনুরোধের সমস্ত পরিস্থিতিতে কাজ করে:

EX: সামসস্ক্রিপ্ট.পিএস 1

function printme () {
    "In function:"
    ( "MyInvocation.ScriptName: " + [string]($MyInvocation.ScriptName) )
    ( "script:MyInvocation.MyCommand.Name: " + [string]($script:MyInvocation.MyCommand.Name) )
    ( "MyInvocation.MyCommand.Name: " + [string]($MyInvocation.MyCommand.Name) )
}
"Main:"
( "MyInvocation.ScriptName: " + [string]($MyInvocation.ScriptName) )
( "script:MyInvocation.MyCommand.Name: " + [string]($script:MyInvocation.MyCommand.Name) )
( "MyInvocation.MyCommand.Name: " + [string]($MyInvocation.MyCommand.Name) )
" "
printme
exit

আউটপুট:

PS> powershell C:\temp\test.ps1
Main:
MyInvocation.ScriptName:
script:MyInvocation.MyCommand.Name: test.ps1
MyInvocation.MyCommand.Name: test.ps1

In function:
MyInvocation.ScriptName: C:\temp\test.ps1
script:MyInvocation.MyCommand.Name: test.ps1
MyInvocation.MyCommand.Name: printme

লক্ষ্য করুন উপরোক্ত গৃহীত উত্তর কীভাবে মেইন থেকে ডাকলে মান দেয় না return এছাড়াও, মনে রাখবেন যে যখন প্রশ্নটি কেবল স্ক্রিপ্টের নামটির জন্য অনুরোধ করেছিল তখন উপরের স্বীকৃত উত্তরটি পুরো পথটি দেয়। স্কোপড ভেরিয়েবল সব জায়গায় কাজ করে।

এছাড়াও, আপনি যদি পুরো পথটি না চান, তবে আপনি কেবল কল করবেন:

$script:MyInvocation.MyCommand.Path

3

পূর্ববর্তী প্রতিক্রিয়াগুলিতে উল্লিখিত হিসাবে, "$ MyInvocation" ব্যবহার করা স্কোপিংয়ের বিষয় সাপেক্ষে এবং প্রয়োজনীয়ভাবে সামঞ্জস্যপূর্ণ ডেটা সরবরাহ করে না (রিটার্ন মান বনাম সরাসরি অ্যাক্সেস মান)। স্ক্রিপ্টের পথ, নাম, পারমস, কমান্ড লাইন ইত্যাদির মতো স্ক্রিপ্ট তথ্য পাওয়ার জন্য "ক্লিনস্ট" (সর্বাধিক ধারাবাহিক) পদ্ধতিটি স্কোপ নির্বিশেষে (মূল বা পরবর্তী / নেস্টেড ফাংশন কলগুলিতে) "গেট- "MyInvocation" এ পরিবর্তনীয় "...

# Get the MyInvocation variable at script level
# Can be done anywhere within a script
$ScriptInvocation = (Get-Variable MyInvocation -Scope Script).Value

# Get the full path to the script
$ScriptPath = $ScriptInvocation.MyCommand.Path

# Get the directory of the script
$ScriptDirectory = Split-Path $ScriptPath

# Get the script name
# Yes, could get via Split-Path, but this is "simpler" since this is the default return value
$ScriptName = $ScriptInvocation.MyCommand.Name

# Get the invocation path (relative to $PWD)
# @GregMac, this addresses your second point
$InvocationPath = ScriptInvocation.InvocationName

সুতরাং, আপনি $ পিএসকম্যান্ডপথের মতো একই তথ্য পেতে পারেন তবে চুক্তিতে আরও অনেক কিছু। নিশ্চিত নয়, তবে দেখে মনে হচ্ছে "গেট-ভেরিয়েবল" পিএস 3 অবধি উপলব্ধ ছিল না তাই সত্যিকারের পুরানো (আপডেট করা হয়নি) সিস্টেমগুলির জন্য প্রচুর সহায়তা নেই।

"-Scope" ব্যবহার করার সময় কিছু আকর্ষণীয় দিক রয়েছে যেমন আপনি কলিং ফাংশন (গুলি) এর নাম ইত্যাদি পেতে ব্যাকট্র্যাক করতে পারেন। 0 = বর্তমান, 1 = পিতামাতার, ইত্যাদি

আশা করি এটি কিছুটা সহায়ক হবে।

সূত্র, https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-variable


1

নীচের স্ক্রিপ্টের সাথে PS 2 এবং PS 4 উভয়টিতে কিছু পরীক্ষা করেছিলেন এবং একই ফলাফল পেয়েছিলেন। আমি আশা করি এটি মানুষের সহায়তা করবে।

$PSVersionTable.PSVersion
function PSscript {
  $PSscript = Get-Item $MyInvocation.ScriptName
  Return $PSscript
}
""
$PSscript = PSscript
$PSscript.FullName
$PSscript.Name
$PSscript.BaseName
$PSscript.Extension
$PSscript.DirectoryName

""
$PSscript = Get-Item $MyInvocation.InvocationName
$PSscript.FullName
$PSscript.Name
$PSscript.BaseName
$PSscript.Extension
$PSscript.DirectoryName

ফলাফল -

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      -1     -1      

C:\PSscripts\Untitled1.ps1
Untitled1.ps1
Untitled1
.ps1
C:\PSscripts

C:\PSscripts\Untitled1.ps1
Untitled1.ps1
Untitled1
.ps1
C:\PSscripts

1

এটি বেশিরভাগ পাওয়ার শেল সংস্করণে কাজ করতে পারে:

(& { $MyInvocation.ScriptName; })

এটি তফসিলি কাজের জন্য কাজ করতে পারে

Get-ScheduledJob |? Name -Match 'JOBNAMETAG' |% Command
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.