পাওয়ারশেল: স্ক্রিপ্টের ডিরেক্টরি থেকে রান কমান্ড


144

আমার কাছে পাওয়ারশেল স্ক্রিপ্ট রয়েছে যা স্ক্রিপ্টের বর্তমান ডিরেক্টরি ব্যবহার করে কিছু স্টাফ করে। সুতরাং যে ডিরেক্টরি ভিতরে, চলমান .\script.ps1সঠিকভাবে কাজ করে।

এখন আমি স্ক্রিপ্টটির রেফারেন্স ডিরেক্টরিটি পরিবর্তন না করেই একটি ভিন্ন ডিরেক্টরি থেকে সেই স্ক্রিপ্টটি কল করতে চাই। সুতরাং আমি কল করতে চাই ..\..\dir\script.ps1এবং এখনও চাইছি যে স্ক্রিপ্টটি এটির ডিরেক্টরি হিসাবে এটি ডাকা হয়েছিল beha

আমি কীভাবে এটি করব বা কোনও স্ক্রিপ্টটি কোনও ডিরেক্টরি থেকে চালিত করতে পারি তাই কীভাবে তা পরিবর্তন করব?

উত্তর:


200

আপনি কী স্ক্রিপ্টের নিজস্ব পথ চান তাই আপনি স্ক্রিপ্টের পাশে একটি ফাইল রেফারেন্স করতে পারেন? এটা চেষ্টা কর:

$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Write-host "My directory is $dir"

আপনি $ MyInvocation এবং এর বৈশিষ্ট্য থেকে প্রচুর তথ্য পেতে পারেন।

আপনি যদি বর্তমান ওয়ার্কিং ডিরেক্টরিতে কোনও ফাইলের রেফারেন্স করতে চান তবে আপনি সমাধান সমাধান বা গেট-চাইল্ড আইটেম ব্যবহার করতে পারেন:

$filepath = Resolve-Path "somefile.txt"

সম্পাদনা (ওপির মন্তব্যের ভিত্তিতে):

# temporarily change to the correct folder
Push-Location $folder

# do stuff, call ant, etc

# now back to previous directory
Pop-Location

ইনভোক-কমান্ড ব্যবহার করেও অনুরূপ কিছু অর্জনের সম্ভবত অন্যান্য উপায় রয়েছে।


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

3
আহ তবে সেই ক্ষেত্রে আপনি চাইবেন Push-LocationএবংPop-Location
জনল

5
যে বিষয়ে সতর্ক, $ MyInvocation, প্রসঙ্গ সংবেদনশীল আমি সাধারণত কি $ ScriptPath = (পান-চলক MyInvocation -Scope স্ক্রিপ্ট) .Value.MyCommand.Path যা পাখির বা ফাংশনের কোন ধরণের থেকে কাজ করে
আয়ন Todirel

39

আপনি যদি নেটিভ অ্যাপ্লিকেশনগুলিতে কল করছেন তবে আপনার [Environment]::CurrentDirectoryপাওয়ারশেলের $PWDবর্তমান ডিরেক্টরি সম্পর্কে নয় তা নিয়ে চিন্তা করা দরকার । বিভিন্ন কারণে, যখন আপনি সেট-লোকেশন বা পুশ-লোকেশন সেট করুন তখন পাওয়ারশেল প্রক্রিয়াটির বর্তমান ওয়ার্কিং ডিরেক্টরিটি সেট করে না, সুতরাং আপনি যদি অ্যাপ্লিকেশনগুলি (বা সেমিডলেট) চালিয়ে যাচ্ছেন এটি সেট হওয়ার প্রত্যাশা করে তবে আপনি এটি করছেন তা নিশ্চিত করা দরকার।

স্ক্রিপ্টে, আপনি এটি করতে পারেন:

$CWD = [Environment]::CurrentDirectory

Push-Location $MyInvocation.MyCommand.Path
[Environment]::CurrentDirectory = $PWD
##  Your script code calling a native executable
Pop-Location

# Consider whether you really want to set it back:
# What if another runspace has set it in-between calls?
[Environment]::CurrentDirectory = $CWD

এর কোনও বুদ্ধিমান বিকল্প নেই। আমাদের মধ্যে অনেকে [পরিবেশ]] কারেন্টডাইরেক্টরি ... সেট করার জন্য আমাদের প্রম্পট ফাংশনে একটি লাইন রেখে দেয় তবে আপনি যখন কোনও স্ক্রিপ্টের মধ্যে অবস্থান পরিবর্তন করেন তখন তা আপনাকে সাহায্য করবে না ।

এটি পাওয়ারশেল দ্বারা স্বয়ংক্রিয়ভাবে সেট না হওয়ার কারণ সম্পর্কে দুটি নোট:

  1. পাওয়ারশেলটি বহু-থ্রেডযুক্ত হতে পারে। আপনার একাধিক রানস্পেস থাকতে পারে (রানস্পেসপুল এবং পিএসটিগ্র্যাডজব মডিউল দেখুন) একক প্রক্রিয়ার মধ্যে একসাথে চলছে। প্রতিটি রান স্পেসের নিজস্ব নিজস্ব $PWDকার্যক্ষম ডিরেক্টরি রয়েছে তবে এখানে কেবল একটি প্রক্রিয়া এবং কেবল একটি পরিবেশ রয়েছে।
  2. এমনকি আপনি যখন একক থ্রেডেড হন, $PWDসর্বদা আইনী কারেন্টডাইরেক্টরি হয় না (উদাহরণস্বরূপ আপনি রেজিস্ট্রি সরবরাহকারীতে সিডি করতে পারেন)।

আপনি যদি এটিকে আপনার প্রম্পটে রাখতে চান (যা কেবলমাত্র প্রধান রানস্পেসে চলবে, একক থ্রেডযুক্ত), আপনার প্রয়োজন:

[Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem

4
এটি পথ সরবরাহকারীদের কারণে প্রক্রিয়াটির কার্য সম্পাদনকারী ডিরেক্টরি পরিবর্তন করে না: আপনি রেজিস্ট্রি, একটি এসকিউএল ডাটাবেস বা আইআইএস
এইচআইভি

1
হ্যাঁ. আমি জানি, এটি ছিল সেই শেষ "চূড়ান্ত নোট" এর পয়েন্ট। তারা থাকতে পারে (যেমন আমি আমার প্রম্পট ফাংশনটি করি) এটি বিশ্বের অন্যান্য শেলের মতো ফাইলসিস্টেম সরবরাহকারীর বর্তমান অবস্থানে আপডেট করেছে।
জয়কুল

2
পবিত্র স্ক্রিপ্টিং দেবতারা, আমি খুব ত্রুটিযুক্ত .\_/.- আমার এই অর্ধেক দিনের নিহত! মানুষ, সিরিয়াসলি? সিরিয়াসলি? ..
ulidtko

2
এটি এখন বেশিরভাগ ক্ষেত্রেই অস্বস্তিকর Power
জয়কুল

1
এই পদ্ধতিটি মূল [Environment]::CurrentDirectoryথেকে পুনরুদ্ধার করতে ব্যর্থ হয় যখন এর থেকে পৃথক হয় $PWD। সঠিক জিনিসটি $origEnvDir = [Environment]::CurrentDirectoryহ'ল এটি একটি ভেরিয়েবলের মধ্যে সঞ্চয় করা এবং তারপরে এটি পুনরুদ্ধার করা [Environment]::CurrentDirectory = $origEnvDir
স্ট্রুম

37

বিপুল সংখ্যক ভোটের উত্তর রয়েছে, তবে আমি যখন আপনার প্রশ্নটি পড়েছিলাম তখন আমি ভেবেছিলাম যে আপনি স্ক্রিপ্টটি কোথায় আছে সেই ডিরেক্টরিটি জানতে চান, যেখানে স্ক্রিপ্টটি চলছে তা নয়। আপনি পাওয়ারশেলের অটো ভেরিয়েবলগুলির সাথে তথ্য পেতে পারেন

$PSScriptRoot - the directory where the script exists, not the target directory the script is running in
$PSCommandPath - the full path of the script

উদাহরণস্বরূপ, আমার কাছে script প্রোফাইল স্ক্রিপ্ট রয়েছে যা ভিজ্যুয়াল স্টুডিও সমাধান ফাইলটি আবিষ্কার করে এবং এটি শুরু করে। আমি একবার সমাধান ফাইল শুরু করার পরে পুরো পথটি সঞ্চয় করতে চেয়েছিলাম। তবে আমি যেখানে ফাইলটি মূল স্ক্রিপ্টটি উপস্থিত আছে সেভ করতে চেয়েছিলাম। সুতরাং আমি $ পিএসস্ক্রিপ্ট রুট ব্যবহার করেছি।


12

আমি প্রায়শই একটি মডিউল আমদানি করতে নিম্নলিখিত কোডটি ব্যবহার করি যা চলমান স্ক্রিপ্টের মতো একই ডিরেক্টরিতে বসে under এটি প্রথমে ডিরেক্টরিটি পাওয়ার ক্ষমতা থেকে চালিত হবে get

$ কারেন্টপথ = স্প্লিট-পাথ ((গেট-ভেরিয়েবল মাই ইনভোকেশন -স্কোপ 0)। মূল্য)) মাইকম্যান্ড.পথ

আমদানি-মডিউল "$ বর্তমানপথ \ sqlps.ps1"


আপনি স্ক্রিপ্ট -স্কোপ সেট করতে চান
অয়ন টোডেরেল

9

এটি ভাল কাজ করবে।

Push-Location $PSScriptRoot

Write-Host CurrentDirectory $CurDir

Pop-Locationতার আসল অবস্থায় ফিরে যাওয়ার জন্য শেষে কল করতে ভুলবেন না ।
লাম লে

2

ঠিক আছে আমি কিছুক্ষণের জন্য সমাধানটির সন্ধান করছিলাম, কেবল সি এল এল থেকে কোনও স্ক্রিপ্ট ছাড়াই। এইভাবে আমি এটি এক্সডি করি:

  • যে ফোল্ডার থেকে আপনি স্ক্রিপ্টটি চালাতে চান সেটিতে নেভিগেট করুন (গুরুত্বপূর্ণ বিষয়টি হল আপনার ট্যাব সমাপ্তি রয়েছে)

    ..\..\dir

  • এখন দ্বিগুণ উদ্ধৃতি সহ চারপাশের অবস্থান এবং এর ভিতরে জুড়ুন cd, যাতে আমরা পাওয়ারশেলের আরেকটি উদাহরণ চাই।

    "cd ..\..\dir"

  • স্ক্রিপ্ট দ্বারা পৃথক করে চালিত করতে অন্য কমান্ড যুক্ত করুন ;, যার সাথে পাওয়ারশেলে একটি কমান্ড বিভাজক রয়েছে

    "cd ..\..\dir\; script.ps1"

  • অবশেষে পাওয়ারশেলের অন্য একটি উদাহরণ দিয়ে এটি চালান

    start powershell "cd..\..\dir\; script.ps1"

এটি নতুন পাওয়ারশেল উইন্ডোটি খুলবে, যান ..\..\dir, চালানো script.ps1এবং উইন্ডোটি বন্ধ করে দেবে।


মনে রাখবেন যে ";" কমান্ডগুলি কেবল আলাদা করে দেয়, যেমন আপনি সেগুলি একে একে টাইপ করেছেন, যদি প্রথম ব্যর্থ হয় তবে দ্বিতীয়টি চালিত হবে এবং তার পরে এবং তার পরেরটি ... আপনি যদি নতুন পাওয়ারশেল উইন্ডোটি খুলতে চান তবে আপনি পাস হওয়া কমান্ডটিতে নন-এক্সিট যুক্ত করুন। মনে রাখবেন যে আমি প্রথমে পছন্দসই ফোল্ডারে নেভিগেট করি যাতে আমি ট্যাব পরিপূর্ণতা ব্যবহার করতে পারি (আপনি ডাবল উদ্ধৃতিতে পারেননি)।

start powershell "-noexit cd..\..\dir\; script.ps1"

ডাবল উদ্ধৃতি ব্যবহার করুন ""যাতে আপনি নামের সাথে স্পেস সহ ডিরেক্টরিগুলি পাস করতে পারেন যেমন,

start powershell "-noexit cd '..\..\my dir'; script.ps1"


0

আমি @ জনএল এর সমাধানের বাইরে একটি লাইন তৈরি করেছি:

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