在PowerShell的WebClient和FileStream中使用相对路径

3
我被指定编写一段 PowerShell 脚本来执行文件下载,最终将作为每周定期任务运行。我没有在 Windows 环境下编程的背景,所以今天很有趣。
我遇到了一个问题,即 shell 的 $pwd 和 $home 处理出乎意料。
我向程序传递一个下载 URL 和目标文件。我希望目标文件是一个相对路径,例如 download/temp.txt.gz。
param($srcUrl, $destFile)

$client = new-object System.Net.WebClient
$client.DownloadFile($srcUrl, $destFile)

Ungzip-File $destFile

Remove-Item $destFile

实际上,调用Remove-Item时会出现错误。如果$destFile是相对路径,则脚本会愉快地下载该文件并将其放在相对于$home的文件中。同样,我解压缩了它,并且我的函数Ungzip-File使用了System.IO.Filestream,它似乎能够找到这个文件。然后Remove-Item抱怨说,在相对于$pwd的路径中没有文件。

我有点困惑,因为这些都是 shell 的一部分,可以说是同一种函数。我不清楚为什么这些函数会以不同的方式处理路径,更重要的是,我不确定如何修复这个问题,使得相对路径和绝对路径都能正常工作。我已经尝试查看io.path方法,但由于我的$home$pwd位于不同的驱动器上,所以甚至无法使用IsPathRooted,尽管这个方法看起来很接近。

需要帮助吗?

2个回答

1
你必须知道自己在路径中的位置。$pwd 在命令行界面中可以正常使用,但是假设您从计划任务中启动了脚本。您可能会认为 $pwd 是您的脚本所在的位置,并相应地编写代码,但实际上它使用的是,比如 %windir%\system32。
通常,我会使用完整路径到目标,对于与脚本文件夹相关的路径,我会使用 $PSScriptRoot/folder_name/file_path。
也有一些注意事项。例如,我注意到 $PSScriptRoot 在脚本内部可以很好地解析,但在 Param() 块内无法解析。我强烈建议在编写和测试时使用 write-verbose,以便您知道它将路径视为何种路径。
[CMDLETBINDING()] ## you need this!
Param()
write-verbose "path is $pwd"
Write-Verbose "removing $destFile"
Remove-Item $destfile

当您调用脚本/函数时,请添加-verbose:

myscript.ps1 -verbose
mydownloadfunction -verbose

不,这不是不知道你在哪里的问题。我知道我在哪里 - 一些命令只是忽略它并选择根据脚本位置解释相对路径。 - ArtOfWarfare

1
为了使用相对路径,您需要用 ./ 指定当前目录。
例如:./download/temp.txt.gz 您还可以在脚本中间通过 Set-Location(别名:cd)更改位置。

1
这是我尝试做的第一件事情之一,认为它正在尝试从根目录解析路径。问题在于相对路径对于这些“Microsoft”调用是不同的。我希望这些方法使用$home或$pwd,但不是“有时一个,有时另一个”。 - Matt Thompson
大多数情况下,它是相对于脚本本身或脚本所在的位置“启动”的。 - Vasili Syrakis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接