2009-03-26 9 views
48

Я хотел бы включить файлы сценариев с таким псевдо синтаксисом:Включить относительные файлы в PowerShell

Include '.\scripA.ps1' 

Но единственное, что я нашел некоторые вещи, как это:

$thisScript = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 
. ($thisScript + '.\scriptA.ps1') 

, что это некрасиво ,

Есть ли nice Способ включения скриптов с относительными путями?

+2

PowerShell является уродливым – tofutim

ответ

11

К сожалению нет, нет хорошего пути. PowerShell не очень хорошо поддерживает эту идею в V1. На самом деле такой подход вы принимаете это лучший подход

+0

А что такое v2? Должен ли я использовать модули для внешних скриптов и синтаксис «Import-Module ./foo.psm1»? Или любые улучшения для включения обычных скриптов? – alex2k8

+0

@ alex2k8, я еще не сделал много работы с V2, но я не могу дать слишком много помощи.Я знаю, что модули должны быть гораздо более изолированными, чем скрипты, но кроме этого у меня мало данных. – JaredPar

+0

В v2 вы можете использовать модуль с манифестом, который определяет все модули, скрипты и даже snapins/assemblylies. Хорошим преимуществом этого является то, что вы можете иметь функции и переменные, которые являются частными для модуля. – JasonMArcher

27

Вы можете дот-источника (включить) файл:

. . \ ScriptA.ps1

Чтобы получить полный путь к сценарию:.

Resolve-Path \ scriptA.ps1

+0

Нет, это работает до тех пор, пока основное месторасположение сценария не будет равно pwd. – alex2k8

+1

Первая часть выполняет ... но Resolve-Path проверит текущий каталог и ваш путь к файлу. Если ваш каталог сценариев находится на вашем пути ($ env: path), он найдет его. –

+0

Thnaks, ребята, я должен был упомянуть о поселении. –

20

Dot-источников является самым простым вариантом хотя и не особенно красивая, как уже было сказано. Тем не менее, этот формат делает это только чуть-чуть немного чище:

$ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path 
. (Join-Path $ScriptDirectory ScriptA.ps1) 

Кроме того, заметка о относительные пути, что полезно сделать явным: исходное сообщение может показаться, что означает, желая путь относительно к тока рабочий каталог; в действительности намерение должно относиться к исходному каталогу текущего сценария (как показывает собственный пример кода alex2k8). Таким образом, это позволяет текущему скрипту получать доступ к другим скриптам из одного и того же репозитория.

4

Как У2 (родной, начиная с Win7/2008R2, см $psversiontable.psversion), вы можете легко включить файл, как так:

. "RelativeOrAbsolutePathToFile\include.ps1" 

$result = FunctionInIncludeFile() 

Ссылка:
How to reuse windows powershell functions in scripts

+6

Насколько я могу судить, проблема заключается в том, что строка с точечным источником оценивается относительно текущей рабочей директории, а не относительно сценария, содержащего строку с точечным источником. Поэтому, если вы 'cd' в каталог, который содержит скрипт, сначала он работает, но если вы вызываете его из другого каталога, это не так. –

+0

Это, наверное, дизайн, спасибо за комментарий, хотя помощник! –

71

Вы можете использовать параметр $ PSScriptRoot например:

. "$PSScriptRoot\script.ps1" 
+4

Это единственный ответ, который работает – Richard

+0

Чистое решение, которое работает для меня! – Omar

0

Это, вероятно, работало бы из любого каталога, но это будет slooo ooowwwww найти, если ваш стартовый каталог не является прямым антецедентом каталога файла, который вы пытаетесь включить. IOW, если отправной точкой для этого поиска является корень c: \ или другой буквы диска, это, вероятно, будет ужасно медленным.

. $ (Resolve-Path -literal $ (gci -Recurse include.ps1))

Это будет работать особенно хорошо, если вы разрабатываете скрипты на своем ПК, но вам необходимо развернуть их на сервере, который будет запускать скрипт как запланированное задание.