如何使用命令行别名在Cmder中使用带空格的路径创建联结

时间:2017-09-20 17:25:13

标签: windows command-line alias junction cmder

我在Windows 10上使用Cmder(ConEmu 161206 [64]稳定)。我想创建一个名为 cloud 的别名来创建一个联结。这是我在Cmder中输入的内容:

alias cloud=mklink /J "C:\Users\chjensen\OneDrive - chjensen\$1" "$2"

我想说我想创建一个名为Sublime的链接文件夹,目标是我在 C:\ Program Files \ Sublime Text 3 \ Data \ Packages 的Sublime包。我试试这个:

cloud sublime C:\Program Files\Sublime Text 3\Data\Packages

但该命令会产生以下输出:

为C:\ Users \ chjensen \ OneDrive创建的交汇点 - chjensen \ sublime<< ===>> C:\程序

第一条路径是正确的,但第二条路径 - C:\ Program - 正在第一个路径被切断。当我尝试访问链接目录时,我显然不能,因为它试图链接到C:\ Program,它不存在。

如果我手动编写整个命令,它可以工作:

mklink /J "C:\Users\chjensen\OneDrive - chjensen\sublime" "C:\Program Files\Sublime Text 3\Data\Packages"

为C:\ Users \ chjensen \ OneDrive创建的交汇点 - chjensen \ sublime<< ===>> C:\ Program Files \ Sublime Text 3 \ Data \ Packages

我也尝试在实际命令中使用引号:

alias cloud=mklink /J "C:\Users\chjensen\OneDrive - chjensen\$1" $2
cloud sublime "C:\Program Files\Sublime Text 3\Data\Packages"

但我得到的结果相同。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

要解决此问题,您可以使用以下代码(这不是一个非常优雅的解决方案,但它可以很好地工作)。请注意,我使用c:\temp来测试而不是您的主目录,但它的概念相同:

alias cloud=mklink /J "C:\temp\OneDrive - chjensen\$1" $2 $3 $4 $5 $6 $7 $8 $9

这将是MS cmd命令:

cloud sublime "C:\Program Files\Sublime Text 3\Data\Packages"

这是调试别名的简单方法,但使用echo命令将其放到终端:

alias cloudp=echo mklink /J "C:\temp\OneDrive - chjensen\$1" $2 $3 $4 $5 $6 $7 $8 $9

正如您已经提到的那样,您遇到的问题是$2正在转化为"C:\Program$3 = Files\Sublime,使用这种不优雅的解决方案,它会简单地将它们全部重新组合在一起,带有空格,也许还有一些我们在最后一次双引号后不关心的尾随空格。

你可以尝试通过胡萝卜符号逃避每个空间,例如C:\Program^ Files\Sublime^ Text^ 3\Data\Packages,但我不认为它会起作用,你不想记得放胡萝卜符号每一次。

如果您可以从OneDrive路径中删除空格(空格是邪恶的,特别是在Microsoft cmd提示符中),您可以通过以下方式更优雅地解决这个问题:

alias cloud2=mklink /J C:\temp\OneDrive_chjensen\$*

$*表示cloud命令之后的所有内容。

鉴于我上面所说的,我实际建议的是什么...... 如果可能的话,转换到在Cmder中使用PowerShell控制台。它将比使用基于doskey的别名简单得多。我写了一个方法,用于将.ps1文件提取到此stackoverflow answer中的PowerShell控制台。

我已经创建了一些PowerShell的示例,您可以使用它(取决于您的PowerShell版本)来执行相同的操作,但具有更多错误检查和灵活性。有关PowerShell符号链接的更多信息,请参阅此link

此外,请考虑使用$env:USERPROFILE代替C:\Users\chjensen,以使脚本在其他计算机上更具可重用性(同样,$env:ProgramFiles而不是c:\Program Files)。

function Get-DestPath
{
    [CmdletBinding()]
    param ( [AllowNull()][String] $DestPath )

    if (!$DestPath)
    {
        # set to default
        $DestPath = 'C:\temp\OneDrive - chjensen\'
    }

    return $DestPath
}

function New-SymbolicLinkItem
{
    [CmdletBinding(SupportsShouldProcess=$true)]
    param
    (
         [Parameter(Mandatory=$true)][String] $NewLinkName 
        ,[Parameter(Mandatory=$true)][String] $ItemToLink
        ,[AllowNull()][String] $DestPath
    )

    $DestPath = Get-DestPath -DestPath $DestPath

    Write-Verbose -Message ('New Link: NewLinkName={0}, ItemToLink={1}, DestPath={2}' -f $NewLinkName, $ItemToLink, $DestPath)

    if ($PSCmdlet.ShouldProcess($ItemToLink, 'New-SymbolicLinkItem'))
    {
        try
        {
            New-Item -ItemType SymbolicLink -Path $DestPath -Name $NewLinkName -Value $ItemToLink -ErrorAction Stop
        }
        catch
        {
            ('Error creating link: {0}, line number: {1}' -f $_, $_.InvocationInfo.ScriptLineNumber)
        }
    }
}
Set-Alias -Name cloud -Value New-SymbolicLinkItem

您可以在PowerShell控制台中以与别名相同的方式使用此命令:

cloud sublime "C:\Program Files\Sublime Text 3\Data\Packages"

我希望这会有所帮助。如果您有任何问题,请告诉我。