V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
1054850490
V2EX  ›  PowerShell

powershell 运行 ps 文件的时候,如何支持带空格的路径

  •  1
     
  •   1054850490 · 2023-02-13 21:07:45 +08:00 · 2175 次点击
    这是一个创建于 678 天前的主题,其中的信息可能已经有所发展或是发生改变。
    列如我在以下的文件夹中打开了一个 PS 文件

    C:\Users\yerin\Desktop\新建文件夹 (2)\无标题 8.ps1

    我们可以看到上面的路径中有空格,由于 ps 文件默认是以当前运行的目录作为运行路径,而上面路径也没有双引号圈起来,也没法圈路径,该如何解决当前路径带有空格的问题?虽然控制台可以双引号路径,但是 ps 文件没法事先双引号路径


    还有另一个问题,就是我右键 ps 文件的时候,有个选项是“使用 powershell 运行”,这时候当前路径带空格也没事
    但是如果我绑定了默认应用,也就是所有 ps1 文件都以“C:\Windows\System32\WindowsPowerShell\v1.0”改路径下的 powershell 运行,然后此时我双击运行的时候,就会出现我上述第一个问题,该路径找不到
    23 条回复    2023-02-15 16:15:40 +08:00
    Tumblr
        1
    Tumblr  
       2023-02-13 21:16:19 +08:00
    首先,不要设置 ps1 双击运行!不要设置 ps1 双击运行!不要设置 ps1 双击运行!
    其次,运行 PowerShell 脚本的方法有很多种:
    1. 在 PowerShell 里用 & "path to script.ps1"
    2. 在 PowerShell 里用 . "path to script.ps1"
    3. 在 PowerShell 里用 iex "path to script.ps1"
    4. 在 PowerShell 里用 Invoke-Expression "path to script.ps1"
    5. 直接运行 powershell -file "path to script.ps1"

    剩下的自己去挖掘吧。
    1054850490
        2
    1054850490  
    OP
       2023-02-13 22:36:34 +08:00
    @Tumblr 如果必须以快捷方式运行呢?每次运行复制一下很麻烦,因为这个程序我需要绑定快捷键唤醒一下,运行频率非常的高,但是是我手动在控制,如果每次都需要复制运行的话对我来说是非常的麻烦
    id7368
        3
    id7368  
       2023-02-13 22:49:57 +08:00 via iPhone
    英文双引号即可
    1054850490
        4
    1054850490  
    OP
       2023-02-13 22:55:37 +08:00
    @id7368 是 ps1 文件运行的时候,默认以 ps1 所在当前文件夹为路径打开控制台,这优先级是非常高的,哪怕你设置了绝对路径也是闪退,因为事先就设定了当前路径
    thinkershare
        5
    thinkershare  
       2023-02-13 22:55:50 +08:00
    @1054850490 这是旧版本 powershell 的一个 bug ,升级 powershell 为 powershell 7 好了,使用 pwsh.exe 打开 ps1 就不会有问题了。
    1054850490
        6
    1054850490  
    OP
       2023-02-13 23:08:50 +08:00 via Android
    @thinkershare 啊这是 bug 吗?我感觉不像,这是最容易触发的问题,只要文件夹带空格就炸了,但是找了很多外网论坛都找不到办法,我待会试试新版本看看
    Crabby
        7
    Crabby  
       2023-02-13 23:12:08 +08:00
    # from cmd.exe
    powershell [noexit] "& path\xxx.ps1"
    or
    pwsh -command "& path\xxxx.ps1"
    thinkershare
        8
    thinkershare  
       2023-02-13 23:13:09 +08:00
    @1054850490 你也可以认为它是一个 feature, 不过 PowerShell 不跨平台的版本也是时候丢弃了。用新版的,快多了,而且各方面都有增强,也方便在 Linux 是使用。
    bg7lgb
        9
    bg7lgb  
       2023-02-13 23:26:53 +08:00 via Android
    win10 默认 ps 版本太低了,升级到 7 以后打开了新的窗户
    1054850490
        10
    1054850490  
    OP
       2023-02-14 03:25:47 +08:00
    @Crabby 用两个脚本维护一个工作太麻烦了有点
    1054850490
        11
    1054850490  
    OP
       2023-02-14 04:02:25 +08:00
    @thinkershare 升级之后问题依旧,将 powershell 文件绑定默认应用为 pow7 ,双击后依旧是提示找不到路径,
    lifansama
        12
    lifansama  
       2023-02-14 07:08:58 +08:00 via Android
    既然右键选择运行那你问题,可以改一下注册表吧
    HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\ ,修改右侧的默认键值
    0 表示直接运行
    Edit 表示用 PowerShell ISE 打开
    Open 表示用记事本打开
    FYFX
        13
    FYFX  
       2023-02-14 07:40:16 +08:00
    @1054850490 #2 你可以写在快捷方式的 target 里面写 powershell.exe -File "path to script.ps1"
    thinkershare
        14
    thinkershare  
       2023-02-14 10:58:42 +08:00
    @1054850490 并不会,我刚刚才还特意去测试了一下,pwsh.exe 在文件夹有空格的情况下能正常工作,怀疑你的 ps1 脚本内部写的有问题。
    thinkershare
        15
    thinkershare  
       2023-02-14 11:18:46 +08:00
    @1054850490 我给你做了个演示, 没啥问题。
    ![演示]( https://imgur.com/a/TXhahLl )
    1054850490
        16
    1054850490  
    OP
       2023-02-14 20:33:58 +08:00
    @thinkershare 下面是我运行 powershell 运行的全部命令

    $env:HTTP_PROXY="http://127.0.0.1:1081"
    $env:HTTPS_PROXY="http://127.0.0.1:1081"
    yt-dlp --lazy-playlist --flat-playlist --print "/watch?v=%(id)s" --print "/shorts/%(id)s" "https://www.youtube.com/playlist?list=PLsPAeAwxHrfMjtOU5Y-2qT32aMIP2nCFH" *>&1 | % {$_; if($_ -notin (gc "总文件 15.txt")){$_ >>"总文件 15.txt"}}
    pause

    我也上传了一个视频用于讲解我遇到的问题
    视频里可以看到,我右键运行是没问题的,但是绑定了默认 powershell 应用双击后直接就闪退,而绑定的是 powershell 无论是 64 位还是 32 位都闪退,但是右键运行就没问题,而且在里面的 pow7 运行的时候也提示错误,看这个提示应该是指路径有问题,我换一个没空格的文件夹就不跳了
    thinkershare
        17
    thinkershare  
       2023-02-14 22:45:20 +08:00
    @thinkershare 是这个脚本写的有问题。在我这里运行你这个脚本双击运行一切正常。你是不是启用了系统管理员账号?
    thinkershare
        18
    thinkershare  
       2023-02-14 22:50:57 +08:00
    你的脚本在双击运行时候,将文件 总文件 15.txt 定位到了系统目录,而你运行的身份没用对此目录文件的写入权限,所有就挂掉了。正常情况 总文件 15.txt 会定位到你运行脚本的文件夹。然后首次文件不存在会报一次错误,然后就应该一切工作正常。你尝试将脚本分开写,然后下中间结果,或者打印下当前的工作目录看看,验证下我的猜想。
    1054850490
        19
    1054850490  
    OP
       2023-02-15 07:36:24 +08:00
    @thinkershare


    我运行这个脚本就是在管理员账户下运行的

    在一闪而过的画面,我录屏捕捉到的信息如下


    ---------------------------------


    题外话
    当我用#16 楼的代码运行的时候,就会跳出以下警告

    哪怕路径不带空格也会跳出这个警告,虽然对最终结果没有运行,但是我不知道这个未来会不会影响某些东西,能不能告诉我是哪里错误了?还有如何关掉之类的警告
    thinkershare
        20
    thinkershare  
       2023-02-15 10:44:47 +08:00
    @1054850490 不要去修复 PowerShell 上的错误, 那是一个无法修复的错误, 虽然可以使用注册表来处理这个问题。
    尝试修复 pwsh.exe 的错误,这个错误很容易修复。就是你的路径定位错误。

    当我用#16 楼的代码运行的时候,就会跳出以下警告: 这个是 yt-dlp 内部的错误,和 powershell 没啥关系,这个错误是 YouTube 返回的错误,它说这个视频是: Unavaiable videos are hidden.

    ```powershell
    $env:HTTP_PROXY="http://127.0.0.1:1081"
    $env:HTTPS_PROXY="http://127.0.0.1:1081"

    Get-Location # 看下为啥你的 powershell 会将活动目录定位到系统路径(pwsh 下)
    New-Item -ItemType File -Name '总文件 15.txt'
    pause

    yt-dlp --lazy-playlist --flat-playlist --print "/watch?v=%(id)s" --print "/shorts/%(id)s" "https://www.youtube.com/playlist?list=PLsPAeAwxHrfMjtOU5Y-2qT32aMIP2nCFH" *>&1 | % {$_; if($_ -notin (gc "总文件 15.txt")){$_ >>"总文件 15.txt"}}
    pause
    ```
    1054850490
        21
    1054850490  
    OP
       2023-02-15 15:32:09 +08:00
    @thinkershare 我最下面那个图并不是指那个:
    WARNING: [youtube:tab] YouTube said: INFO - 120 unavailable videos are hidden

    而是指那个:
    所在位置 C:\Users\yerin\Desktop\新建文件夹 (2)\无标题 8.ps1
    1054850490
        22
    1054850490  
    OP
       2023-02-15 15:53:36 +08:00
    @thinkershare pwsh 确实将 ps1 默认运行路径定为"C:\Windows\System32"导致的,而我本机 win10 的 powershell 5.0 运行的时候会把 ps1 所在目录当做运行路径,所以 pwsh 就是路径错误,可是我这个脚本就是想要以 ps1 所在目录运行的,如果是绝对路径的话又很麻烦,同样的,偶尔也会出现#19 楼最后一张图的警告,我不知道这个警告什么意思,哪怕事先文件夹已经创建了“总文件 15.txt”
    1054850490
        23
    1054850490  
    OP
       2023-02-15 16:15:40 +08:00
    @thinkershare #19 楼最后图的警告我大概知道为什么引起的了,是因为 youtube 发出的警告,然后 powershell 就会报告是谁引起的错误

    如果我想解决下图中的警告,这个警告是因为我想读取名为“总文件 15.txt”,但是由于事先没有创建而引发的警告,虽然最后会自动为我创建


    但是我并不想像这样事先创建:New-Item -ItemType File -Name '总文件 15.txt'
    因为这样的话,我每次改掉 txt 名称的时候还得去改它,有没有办法关掉警告,我也不想依赖 pow7 ,因为看起来 pow7 有更多的问题需要解决,因为它打开 ps1 文件的时候并不是把所在目录当做默认路径,我之前用 cmd 的话,我是用以下代码解决的:
    ```
    cd %~dp0
    %~d0

    ```
    这样打开 bat 文件就会自动跳转到当前目录了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2436 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:49 · PVG 23:49 · LAX 07:49 · JFK 10:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.