সেমিডলেটটির বর্তমান ডিরেক্টরি কীভাবে কার্যকর করা হবে


202

এটি একটি সাধারণ কাজ হওয়া উচিত, তবে আমি যেখানে এক্সিকিউটেড সেমিডলেট মিশ্রিত সাফল্যের সাথে অবস্থিত সেখানে ডিরেক্টরিতে যাওয়ার পথটি পেতে কীভাবে বেশ কয়েকটি প্রচেষ্টা দেখেছি। উদাহরণস্বরূপ, আমি যখন নির্বাহ করি C:\temp\myscripts\mycmdlet.ps1যার একটি সেটিংস ফাইল রয়েছে C:\temp\myscripts\settings.xmlআমি তার C:\temp\myscriptsমধ্যে একটি ভেরিয়েবলের মধ্যে সঞ্চয় করতে সক্ষম হতে চাই mycmdlet.ps1

এটি একটি সমাধান যা কাজ করে (যদিও কিছুটা জটিল)

$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + '\settings.xml'

আরেকটি এই সমাধানটির পরামর্শ দিয়েছিল যা কেবলমাত্র আমাদের পরীক্ষার পরিবেশে কাজ করে:

$settingspath = '.\settings.xml'

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


11
নোট করুন যে এই প্রশ্নের দ্ব্যর্থক শিরোনাম নীচের উত্তরগুলির ফলে দুটি স্বতন্ত্র সমস্যার একটি সমাধান করেছে, তা স্পষ্টভাবে উল্লেখ না করে যা: (ক) কীভাবে বর্তমান অবস্থান (ডিরেক্টরি) উল্লেখ করতে হবে বা (খ) কীভাবে চলমান স্ক্রিপ্টের অবস্থান উল্লেখ করতে হবে ( চলমান স্ক্রিপ্টটি যে ডিরেক্টরিটিতে রয়েছে সেগুলি বর্তমান ডিরেক্টরি হতে পারে বা নাও থাকতে পারে)।
mklement0

উত্তর:


143

এটি করার নির্ভরযোগ্য উপায়টি আপনি যেমন দেখিয়েছিলেন ঠিক তেমন $MyInvocation.MyCommand.Path

আপেক্ষিক পাথগুলি ব্যবহার করা $ পিডাব্লুডির উপর ভিত্তি করে, পাওয়ারশেলের একটি অ্যাপ্লিকেশনের জন্য বর্তমান ডিরেক্টরি, বা .NET এপিআই-র জন্য বর্তমান ওয়ার্কিং ডিরেক্টরি।

পাওয়ারশেল ভি 3 + :

স্বয়ংক্রিয় পরিবর্তনশীল ব্যবহার করুন $PSScriptRoot


6
আপনি কীভাবে আমাকে PATH সম্পত্তি খুঁজে পেয়েছেন তা আমাকে ব্যাখ্যা করতে পারেন? I MyInvocation.MyCommand | gm সদস্যদের তালিকায় এ জাতীয় সম্পত্তি দেখায় না।
ভিতালিয়া মারকিতানভ

19
কেন শুধু $ পিএসএস স্ক্রিপ্ট রুট ব্যবহার করবেন না? আরও নির্ভরযোগ্য বলে মনে হচ্ছে
এমব্রাইস 1024

@ ব্যবহারকারী 2326106 আপনি $PSScriptRootএবং এর মধ্যে পার্থক্য ব্যাখ্যা করতে পারেন $MyInvocation.MyCommand.Path?
duct_tape_coder

1
এই উত্তরটি অসম্পূর্ণ।
কে - এসও-তে বিষক্রিয়া বাড়ছে।

এই উত্তরটি অসম্পূর্ণ।
স্ট্যাকলিট

263

হ্যাঁ, এটি কাজ করা উচিত। তবে আপনি যদি পরম পথটি দেখতে চান তবে আপনার যা প্রয়োজন তা হ'ল:

(Get-Item -Path ".\").FullName

4
ধন্যবাদ, আপেক্ষিক পথগুলি থেকে সম্পূর্ণ পথ খুঁজে পেতে এটি দুর্দান্ত পদ্ধতি। উদাহরণস্বরূপ (গেট-আইটেম -পথ $ myRelativePath -Verbose) ull ফুলনাম
বায়ু

এই জন্য আপনাকে ধন্যবাদ. অন্যান্য উত্তরগুলি EXEs তে সংকলিত পাওয়ারশেল স্ক্রিপ্টগুলির জন্য কাজ করছে না।
জাচ আলেকজান্ডার

10
এটা ভুল । এটি প্রক্রিয়াটির বর্তমান ডিরেক্টরিটি পায় যা যে কোনও জায়গায় হতে পারে। উদাহরণস্বরূপ, যদি আমার কমান্ড লাইন বর্তমান ডিরেক্টরি হয় C:\mydirএবং আমি আদেশটি প্রার্থনা করি তবে এটি C:\dir1\dir2\dir3\mycmdlet.ps1সমাধান করবে C:\mydir, না C:\dir1\dir2\dir3। বর্তমান ডিরেক্টরিটি প্যারেন্ট প্রক্রিয়া থেকে উত্তরাধিকার সূত্রে একটি নতুন এক্সিকিউটেবলকে চালিত করার ক্ষেত্রে একই সমস্যা রয়েছে।
jpmc26

85

নিম্নলিখিতটি পূর্বনির্ধারিত ভেরিয়েবলটি ব্যবহার করা সবচেয়ে সহজ পদ্ধতি বলে মনে হচ্ছে:

 $PSScriptRoot

about_Automatic_Variablesএবং about_Scriptsউভয় রাষ্ট্র:

পাওয়ারশেল ২.০-তে, এই পরিবর্তনশীলটি কেবল স্ক্রিপ্ট মডিউলগুলিতে (.psm1) বৈধ। পাওয়ারশেল 3.0.০ থেকে শুরু করে, এটি সমস্ত স্ক্রিপ্টে বৈধ।

আমি এটি এর মতো ব্যবহার করি:

 $MyFileName = "data.txt"
 $filebase = Join-Path $PSScriptRoot $MyFileName

12
এটি সংস্করণ নির্দিষ্ট। এর জন্য কমপক্ষে পাওয়ারশেল 3.0 প্রয়োজন।
মারভিন ডিখাউস

1
স্ক্রিপ্টের মতো একই জায়গায় আমার কোনও ফাইলের রেফারেন্স করার দরকার ছিল - ধন্যবাদ!
অ্যাডাম প্রেসকোট

এটি সর্বোত্তম উত্তর হিসাবে এটি আপনাকে পিএস স্ক্রিপ্টটি উপস্থিত হবার জন্য নিখুঁতভাবে পথ দেয় যা মূলত আপনার স্ক্রিপ্ট কার্যকর করার জন্য মূল। আপনি যেখানে আপনার স্ক্রিপ্টগুলি শুরু করেছেন সেখান থেকে আপনার বর্তমান কার্যক্ষম ডিরেক্টরি কী তা বিবেচ্য নয়। +1 টি।
আরবিটি

@ মারভিন ডিখাউস এজন্য আপনার বেশিরভাগ স্ক্রিপ্টে "সেট-স্ট্রাইকডমড-ভার্সন 3.0" ব্যবহার করা দরকার :) লিঙ্কগুলির জন্য ধন্যবাদ আপনাকে ধন্যবাদ!
আলেকজান্ডার শাপকিন

44

আপনি এটি ব্যবহার করতে পারেন:

(Resolve-Path .\).Path

বন্ধনীগুলির অংশটি একটি PathInfoবস্তু ফেরত দেয় ।

(পাওয়ারশেল ২.০ থেকে পাওয়া যায়।)


2
এটা ভুল । এটি প্রক্রিয়াটির বর্তমান ডিরেক্টরিটি পায় যা যে কোনও জায়গায় হতে পারে। উদাহরণস্বরূপ, যদি আমার কমান্ড লাইন বর্তমান ডিরেক্টরি হয় C:\mydirএবং আমি আদেশটি প্রার্থনা করি তবে এটি C:\dir1\dir2\dir3\mycmdlet.ps1সমাধান করবে C:\mydir, না C:\dir1\dir2\dir3। বর্তমান ডিরেক্টরিটি প্যারেন্ট প্রক্রিয়া থেকে উত্তরাধিকার সূত্রে একটি নতুন এক্সিকিউটেবলকে চালিত করার ক্ষেত্রে একই সমস্যা রয়েছে।
jpmc26

3
ধন্যবাদ! আমি এই প্রশ্নের শিরোনামটিও ভুল বুঝেছিলাম এবং এই উত্তরটি আমি ঠিক যা খুঁজছিলাম। তবে ... এটি প্রশ্নের উত্তর দেয় না।
রায়ান দ্য লিচ

33

পথ প্রায়শই শূন্য থাকে। এই ফাংশনটি নিরাপদ।

function Get-ScriptDirectory
{
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value;
    if($Invocation.PSScriptRoot)
    {
        $Invocation.PSScriptRoot;
    }
    Elseif($Invocation.MyCommand.Path)
    {
        Split-Path $Invocation.MyCommand.Path
    }
    else
    {
        $Invocation.InvocationName.Substring(0,$Invocation.InvocationName.LastIndexOf("\"));
    }
}

1
কেন -স্কোপ 1? না -স্কোপ 0
স্যুইনফেং

1
গেট-ভেরিয়েবল: স্কোপ নম্বর '1' সক্রিয় স্কোপের সংখ্যা ছাড়িয়ে গেছে।
suiwenfeng

2
আপনার কোনও পিতামাতার সুযোগ নেই বলে আপনি এই ত্রুটিটি পাচ্ছেন। -স্কোপ প্যারামিটার একটি নির্দিষ্ট স্কোপে ভেরিয়েবল পায়। এই ক্ষেত্রে 1 পিতামাতার সুযোগ। আরও তথ্যের জন্য গেট-ভেরিয়েবল ( টেকনেট.মাইক্রোসফট.ইন- ইউস / লাইবারি /hh849899.aspx ) সম্পর্কে এই টেকনেট নিবন্ধটি দেখুন
খ্রিস্টান ফ্লেম



11

আমি এক-লাইন সমাধানটি পছন্দ করি :)

$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent

এটি এখন পর্যন্ত সেরা সমাধান।
তেওমান শিপাহি

হ্যাঁ আমার জন্য কাজ করে। আমার পিডব্লিউডি আমার ব্যবহারকারী ডিরেক্টরি এবং আমি অন্য ডিরেক্টরিতে (বি) স্ক্রিপ্টটি চালাচ্ছি যা এটি দেয় (বি)
এন্ড্রু প্যাট


4

পাওয়ারশেল 3 এবং এরপরে আপনি কেবল ব্যবহার করতে পারবেন

$PSScriptRoot


1

আপনি ভাবেন যে '। \' কে পাথ হিসাবে ব্যবহার করার অর্থ এটি একটি আহবানের পথ। কিন্তু সব সময় না। উদাহরণস্বরূপ, যদি আপনি এটি কোনও কাজের স্ক্রিপ্টব্লকের ভিতরে ব্যবহার করেন। কোন ক্ষেত্রে এটি% প্রোফাইল% \ নথিগুলিতে নির্দেশ করতে পারে।


1

এই ফাংশনটি স্ক্রিপ্টের পথে প্রম্পট অবস্থান সেট করবে, vscode, psise এবং pwd এর মধ্যে স্ক্রিপ্টপথ পাওয়ার বিভিন্ন পদ্ধতির সাথে কাজ করবে:

function Set-CurrentLocation
{
    $currentPath = $PSScriptRoot                                                                                                     # AzureDevOps, Powershell
    if (!$currentPath) { $currentPath = Split-Path $pseditor.GetEditorContext().CurrentFile.Path -ErrorAction SilentlyContinue }     # VSCode
    if (!$currentPath) { $currentPath = Split-Path $psISE.CurrentFile.FullPath -ErrorAction SilentlyContinue }                       # PsISE

    if ($currentPath) { Set-Location $currentPath }
}

0

এটির মূল্য কী, তার জন্য একটি একক-লাইন সমাধান হতে, নীচেরটি আমার জন্য কার্যক্ষম সমাধান।

$currFolderName = (Get-Location).Path.Substring((Get-Location).Path.LastIndexOf("\")+1)

শেষে 1 টি অগ্রাহ্য করা /

গেট-লোকেশন সিএমডিলেট ব্যবহার করে উপরের পোস্টগুলিকে ধন্যবাদ ।


0

নিম্নলিখিত আইডিইগুলিতে ডিবাগ করার সময় বেশিরভাগ উত্তর কাজ করে না:

  • PS-ISE (পাওয়ারশেল আইএসই)
  • ভিএস কোড (ভিজ্যুয়াল স্টুডিও কোড)

কারণ এগুলির $PSScriptRootমধ্যে খালি এবং Resolve-Path .\(এবং সাদৃশ্য) এর ফলে ভুল পথ দেখা যাবে।

ফ্রেইকিডিন্ডের উত্তর কেবলমাত্র সেই পরিস্থিতিগুলি সমাধান করে, তাই আমি এটিকে ভোট দিয়েছি, তবে আমি মনে করি Set-Locationনা যে উত্তরটি উত্তরটি সত্যই পছন্দসই। সুতরাং আমি এটি সংশোধন করেছি এবং কোডটি কিছুটা পরিষ্কার করে দিয়েছি:

$directorypath = if ($PSScriptRoot) { $PSScriptRoot } `
    elseif ($psise) { $psise.CurrentFile.FullPath } `
    elseif ($psEditor) { split-path $psEditor.GetEditorContext().CurrentFile.Path }

-1

@ ক্র্যাডলের উত্তরটি প্রসারিত করার জন্য: আপনি একটি বহু-উদ্দেশ্যমূলক ফাংশনও লিখতে পারেন যা আপনাকে ওপি-র প্রশ্নের অনুরূপ ফলাফলটি পেতে পারে:

Function Get-AbsolutePath {

    [CmdletBinding()]
    Param(
        [parameter(
            Mandatory=$false,
            ValueFromPipeline=$true
        )]
        [String]$relativePath=".\"
    )

    if (Test-Path -Path $relativePath) {
        return (Get-Item -Path $relativePath).FullName -replace "\\$", ""
    } else {
        Write-Error -Message "'$relativePath' is not a valid path" -ErrorId 1 -ErrorAction Stop
    }

}

-1

আপনার যদি কেবলমাত্র বর্তমান ডিরেক্টরিটির নাম প্রয়োজন হয় তবে আপনি এরকম কিছু করতে পারেন:

((Get-Location) | Get-Item).Name

ধরে নিচ্ছি আপনি সি: \ টেম্প \ অবস্থান \ মাই ওয়ার্কিং ডিরেক্টরি> থেকে কাজ করছেন

আউটপুট

MyWorkingDirectory


-1

আমারও একই রকম সমস্যা ছিল এবং আমি পাওয়ারশেল (সম্পূর্ণ শেষ ব্যবহারকারী জিইআইআই অ্যাপ্লিকেশন) এ লিখিত প্রোগ্রামগুলি তৈরি করার পরে এটি আমাকে অনেক সমস্যায় ফেলেছে এবং আমার ডিস্ক থেকে লোড করার জন্য আমার প্রচুর ফাইল এবং সংস্থান রয়েছে। আমার অভিজ্ঞতা থেকে, ব্যবহার । তারপরে, পাওয়ারশেল ডিরেক্টরিটি ডিরেক্টরিটি পরিবর্তিত করে আপনি যে ডিরেক্টরি থেকে এটি শুরু করেছেন, বা ডিরেক্টরিতে যেখানে আপনি চালিত স্ক্রিপ্টটি পাওয়ারশেল প্রম্পট সহ আপনাকে উপস্থাপন করার আগে বা স্ক্রিপ্ট চালানোর আগে অবস্থিত। কিন্তু পাওয়ারশেল অ্যাপ্লিকেশনটি মূলত আপনার হোম ব্যবহারকারী ডিরেক্টরিতে শুরু হওয়ার পরে এটি ঘটে।. বর্তমান ডিরেক্টরি উপস্থাপন করতে করা অবিশ্বাস্য। এটি বর্তমান চলমান ডিরেক্টরি উপস্থাপন করা উচিত, তবে এটি প্রায়শই হয় না। দেখা যাচ্ছে যে পাওয়ারশেল সেই জায়গাটি সংরক্ষণ করে যেখান থেকে পাওয়ারশেলের ভিতরে প্রবেশ করা হয়েছিল .। আরও সুনির্দিষ্টভাবে বলতে গেলে, পাওয়ারশেলটি যখন প্রথম শুরু করা হয় তখন এটি আপনার হোম ব্যবহারকারী ডিরেক্টরিতে ডিফল্টরূপে শুরু হয়। এটি সাধারণত আপনার ব্যবহারকারীর অ্যাকাউন্টের ডিরেক্টরি accountC:\USERS\YOUR USER NAME

এবং .সেই প্রাথমিক ডিরেক্টরিটি উপস্থাপন করে যার মধ্যে পাওয়ারশেল শুরু হয়েছিল। সুতরাং .যদি আপনি পছন্দসই ডিরেক্টরি থেকে পাওয়ারশেলকে অনুরোধ করেন তবে কেবলমাত্র বর্তমান ডিরেক্টরিটি উপস্থাপন করে। আপনি যদি পরে পাওয়ারশেল কোডে ডিরেক্টরি পরিবর্তন করেন তবে পরিবর্তনটি .প্রতিটি ক্ষেত্রেই প্রতিফলিত হবে না বলে মনে হয় । কিছু ক্ষেত্রে .বর্তমান কার্যনির্বাহী ডিরেক্টরি উপস্থাপন করে এবং অন্যদের মধ্যে ডিরেক্টরি থেকে পাওয়ারশেল (নিজেই, স্ক্রিপ্টটি নয়) আহ্বান করা হয়েছে, এর ফলে কী বেমানান হতে পারে। এই কারণে আমি ইনভোকার স্ক্রিপ্ট ব্যবহার করি। একক কমান্ড ভিতরে PowerShell স্ক্রিপ্ট: POWERSHELL। এটি নিশ্চিত করবে যে পাওয়ারশেলটি পছন্দসই ডিরেক্টরি থেকে আহবান করা হয়েছে এবং এইভাবে তৈরি করা হবে.বর্তমান ডিরেক্টরি উপস্থাপন। তবে আপনি কেবল পাওয়ারশেল কোডে ডিরেক্টরি পরিবর্তন না করলে এটি কেবলমাত্র কাজ করে। একটি স্ক্রিপ্ট ক্ষেত্রে, আমি invoker স্ক্রিপ্ট গত এক আমি উল্লেখ অনুরূপ ছাড়া এটা একটি ফাইল বিকল্প রয়েছে ব্যবহার করুন: POWERSHELL -FILE DRIVE:\PATH\SCRIPT NAME.PS1। এটি নিশ্চিত করে যে পাওয়ারশেলটি বর্তমান কার্যনির্বাহী ডিরেক্টরিতে শুরু হয়েছে।

কেবল স্ক্রিপ্টে ক্লিক করা আপনার ঘরের ব্যবহারকারী ডিরেক্টরি থেকে পাওয়ারশেলকে আহ্বান জানায় যেখানে স্ক্রিপ্টটি অবস্থিত matter স্ক্রিপ্টটি যেখানে অবস্থিত সেখানে ডিরেক্টরি চলমান ডিরেক্টরি রয়েছে, তবে পাওয়ারশেল আহ্বান ডিরেক্টরিটি রয়েছে C:\USERS\YOUR USER NAMEএবং .পরিস্থিতি অনুসারে এই দুটি ডিরেক্টরিগুলির মধ্যে একটি ফেরত দেওয়ার সাথে এটি হাস্যকর।

তবে এই সমস্ত গোলমাল এড়াতে এবং ইনভোকার স্ক্রিপ্টটি ব্যবহার করার জন্য, আপনি বর্তমান ওয়ার্কিং ডিরেক্টরি বা ডিরেক্টরিটি থেকে যে স্ক্রিপ্টটি আহ্বান করা হয়েছে তা উপস্থাপন করতে চান এমন আবহাওয়ার উপর নির্ভর করে আপনি বর্তমান ডিরেক্টরিটি উপস্থাপন করতে $PWDবা এর $PSSCRIPTROOTপরিবর্তে ব্যবহার করতে পারেন .। এবং যদি আপনি কোনও কারণে দু'টি ডিরেক্টরি থেকে অন্য দুটি ডিরেক্টরি পুনরুদ্ধার করতে চান তবে আপনি .ব্যবহার করতে পারেন $HOME

আমার ব্যক্তিগতভাবে আমার পাওয়ার অ্যাপ্লিকেশনের সাথে বিকাশ করা আমার অ্যাপ্লিকেশনগুলির মূল ডিরেক্টরিতে কেবল চালক স্ক্রিপ্ট থাকে যা আমার মূল অ্যাপ্লিকেশন স্ক্রিপ্টকে আমন্ত্রণ জানায় এবং আমার অ্যাপ্লিকেশনটির উত্স কোডের অভ্যন্তরীণ বর্তমানের ডিরেক্টরিটি কখনও পরিবর্তন করতে পারে তা মনে রাখে না, তাই আমাকে কখনই এই নিয়ে চিন্তা করতে হবে না, এবং আমি .বর্তমান ডিরেক্টরি উপস্থাপন করতে এবং কোনও সমস্যা ছাড়াই আমার অ্যাপ্লিকেশনগুলিতে আপেক্ষিক ফাইল ঠিকানা সমর্থন করতে ব্যবহার করতে পারি use এটি পাওয়ারশেলের নতুন সংস্করণে (সংস্করণ 2 এর চেয়েও নতুন) কাজ করা উচিত।

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