powershell/bash硬链接Hardlink@软连接@符号链接@创建@linux符号链接检查

各种链接

  • 在Windows和Linux系统下,符号链接、软连接和硬链接的概念和用途有所不同。以下是它们在这两个操作系统中的区别:
    1. Linux系统:
      • 符号链接(软连接):在Linux系统中,符号链接和软连接是同一概念。它们是一种特殊的文件,包含了指向另一个文件或目录的路径。符号链接可以跨越不同的文件系统。在Linux中,使用ln -s 命令创建符号链接。
      • 硬链接:硬链接是一个指向文件的目录条目,它与原始文件共享相同的inode和数据。硬链接只能在同一文件系统中使用。在Linux中,使用ln 命令创建硬链接。
    2. Windows系统:
      • 符号链接:符号链接是一种特殊的文件,它指向另一个文件或目录。符号链接可以跨越不同的文件系统。在Windows中,使用mklink /d 命令创建目录符号链接.
      • 硬链接:硬链接是一个指向文件的目录条目,它与原始文件共享相同的文件数据。硬链接只能在同一文件系统中使用。在Windows中,使用mklink /h 命令创建硬链接。
      • Junction(连接点):Junction是Windows系统中的一种特殊目录链接类型,类似于Linux中的符号链接。Junction可以链接到另一个目录,使得该目录中的所有文件和子目录都可以通过Junction访问。Junction只能在同一文件系统中使用。在Windows中,使用mklink /j 命令创建Junction。
  • 总结:Linux系统中有符号链接(软连接)和硬链接两种链接类型,而Windows系统中有符号链接、硬链接和Junction三种链接类型。在使用这些链接类型时,需要注意它们在不同操作系统中的实现方式和限制。

用途

直接简化目录名

  • 在不影响对当前目录的依赖的同时,为该目录(记为D)起一个别名,可以通过创建D的符号链接来实现

  • 特别是使用学校邮箱注册的,创建的目录名老长,还带空格,不好看,但是直接修改会破坏映射关系.\

  • 例:mklink /j d:\org "d:\OneDrive - pop.zjgsu.edu.cn\"

文件搬家

  • 对于软件,搬家,可能需要在关机状态下启用修复模式/pe系统下进行
  • (不然旧文件夹删不掉,会被占用)

git管理和符号链接

  • 经过粗略的实践,有如下结论
  • 在git 仓库中通过/j 选项创建的符号链接并绑定的git目录之外的目录,可以被git所管理到
  • 对于/d选项,行为类似,但是git似乎只能够在初次对外源目录做一次管理,之后的外源目录的变更似乎无法引起git的注意.

ondrive

  • 将某些软件的下载目录通过软连接可用定向到onedrive目录实现自动同步,即便软件本身没有提供下载路径的修改功能

FAQ

权限要求🎈

  • 硬链接的创建需要管理员权限

  • 硬链接不可以盘(分区)创建

  • 只有文件才可以创建硬链接,文件夹(目录)不可以

    • PS C:\Users\cxxu\Desktop> New-Item -ItemType HardLink -Path todirr -Target $env:desktop\recycleBin\
      New-Item: A file is required for the operation. The item 'C:\Users\cxxu\desktop\recycleBin\' is not a file.
      

通过本地安全策略来为用户分配指定权限

win+r
输入secpol.msc
按如下方法将当前用户添加到Create symbolic links权限组中.
在这里插入图片描述
但是修改完成后,注销(logout登出)后再登陆才可以生效.

关于硬链接

删除文件/目录对应的操作

那么,当用户删除掉某个 文件,这意味这什么?

  • 实际上,用户删除掉的只是指向文件的一个指针,如果该指针所绑定的文件恰好就这么一个指针,那么你删除掉该指针,就再也不能找到该文件(在哪里了,效果相当于文件没有了(不可寻));
    • 而一些数据恢复技术也是基于此特点实现的(帮助用户找回文件指针,文件就可用了)
  • 而如果某个文件不知有一个指针(名字),那么当其中的一个指针被删除,我们仍然可以通过其他的名字找到该文件,也就是文件仍然可以正常别引用!

硬链接的所绑定的target是谁?

  • 实际上,通过上述的分析,我们发现,文件的名字其实是平等的,没有谁绑定谁(在文件系统中)所有的路标都是直接指向文件实体,名字和名字之间并无关联,他们唯一的关联就是都直接指向同一个文件;
  • 正因为此,我们可以借助已有的硬链接(某一个文件路径path)来创建同等地位的其他硬链接(同一个文件的新路径)(都指向同一个文件)(新的通往"罗马"的道路))
    • 此外,使用powershell查找某个所谓的硬链接(事实上文件系统呈现给用户的文件一般都是硬链接!(处理一些被创建出来的软连接和符号链接)),linktype都是hardlink!

创建带有环境变量引用的符号链接

  • 为了避免命令解析错误,您应当编写路径参数的时候用引号将参数括起来(尽管您的参数中没有空格)

使用/j选项还是/d选项

  • 一般而言,使用/j选项即可
    • /j选项不需要管理员权限即可创建
  • 如果使用/d选项创建的符号在移动的时候不会将真实文件夹移动
    • 但是被移动过的符号链接一般就不在具有可用性了
    • 因为符号链接移动后,其绑定的目标目录/文件会发生更改
    • 应该来说,符号链接会将其绑定的对象路径解释(计算)为绝对路径

中间环境变量对符号链接创建的影响

  • 在创建符号链接的时候,不应当使用够过多的中间变量(不超过一层(嵌套))

    • (过多的中转会导致解析错误)
    • 例如:未能完全解析成有效路径(绝对路径)
    • 这里.gradle变量还引用了androidDepends变量,mklink 只解释了一层(得到%androidDepends%\Android\.gradle,第二层变量androidDepends未能解释
  • 在这里插入图片描述

创建方法

windows: cmd下的mklink创建链接

refs

  • mklink | Microsoft Learn

  • mklink:三种模式可以创建不同的链接符号.

  • C:\Users\cxxu\AppData\Local>mklink /?
    Creates a symbolic link.
    
    MKLINK [[/D] | [/H] | [/J]] Link Target
    
            /D      Creates a directory symbolic link.  Default is a file
                    symbolic link.
            /H      Creates a hard link instead of a symbolic link.
            /J      Creates a Directory Junction.
            Link    Specifies the new symbolic link name.
            Target  Specifies the path (relative or absolute) that the new link
                    refers to.
    
  • mklink命令是Windows操作系统中的一个命令行工具,用于创建符号链接或硬链接。

  • 符号链接是一种特殊的文件,它指向另一个文件或目录,就像一个快捷方式一样。

  • 硬链接是指向同一文件的多个文件名,它们共享相同的数据块。

  • 当你需要在Windows操作系统中创建符号链接时,可以使用mklink命令。mklink命令有三个主要的参数:/j、/d和/h。这些参数用于指定符号链接的类型和行为。

/j参数:创建目录符号链接

/j参数用于创建目录符号链接。目录符号链接是一种特殊的符号链接,它可以链接到一个目录,使得该目录中的所有文件和子目录都可以通过符号链接访问。使用/j参数创建目录符号链接的语法如下:

mklink /j <link> <target>

其中,是符号链接的名称,是符号链接指向的目标目录的路径。

/d参数:创建目录符号链接(兼容旧版Windows)

/d参数也用于创建目录符号链接,但它与/j参数不同的是,它可以在旧版的Windows操作系统中使用。使用/d参数创建目录符号链接的语法如下:

mklink /d <link> <target>

/h参数:创建文件符号链接

/h参数用于创建文件符号链接。文件符号链接是一种特殊的符号链接,它可以链接到一个文件,使得该文件可以通过符号链接访问。使用/h参数创建文件符号链接的语法如下:

mklink /h <link> <target>

其中,是符号链接的名称,是符号链接指向的目标文件的路径。

需要注意的是,符号链接的名称和标路径都可以是相对路径或绝对路径。如果使用相对路径,那么符号链接和目标路径都是相对于当前工作目录的。如果使用绝对路径,那么符号链接和目标路径都是绝对路径。

Note
  • 请注意,硬链接只能在同一驱动器上创建,而符号链接可以跨驱动器创建。

权限要求🎈

  • 使用管理员权限打开终端命令行

  • 部分目录的文件(比如系统目录)不允许被创建硬链接

    • C:\Users\cxxu\Desktop# mklink /h C:\Users\cxxu\Desktop\test_pad  C:\Windows\System32\notepad.exe
      Access is denied.
      
  • 虽然可能允许创建符号链接,但是可能并无意义(例如创建的链接打不开)

    • C:\Users\cxxu\Desktop#  mklink /d C:\Users\cxxu\Desktop\test_pad.exe C:\Windows\System32\notepad.exe
      symbolic link created for C:\Users\cxxu\Desktop\test_pad.exe <<===>> C:\Windows\System32\notepad.exe
      
  • 在powershell 下使用cmd /C来执行mklink命令

    • PS C:\Users\cxxu\Desktop> cmd /C mklink /h $env:USERPROFILE\desktop\test_byHardlink.pdf  C:\users\cxxu\Desktop\test.pdf
      Hardlink created for C:\Users\cxxu\desktop\test_byHardlink.pdf <<===>> C:\users\cxxu\Desktop\test.pdf
      

powershell 创建链接

  • 帮助文档:

  • 通过new-item -itemType hardlink 进行创建

  • 注意,使用-target 相对路径无法成功创建,需要使用绝对路径

  • 幸运的是,我们可以利用pwd来优化这一点

  • 以下函数经过一定的处理,使得用户可以仅仅输入相对路径就可以创建硬连接

function newHardLink
{
    param(
        $Path = 'slides.md',
        [String]$target 
    )
    # 下面这段判断处理可有可无
    <# if ($target.ToString().StartsWith(".\")) {
        $target=$target.TrimStart(".\")
    } #>
    # $absTarget = "$pwd\" + "$target"
    $absTarget = (Get-ChildItem $target).FullName
    Write-Output "$absTarget will be target!"
    # $absTarget = Invoke-Expression $absTarget
    Write-Output "@$absTarget"
    # $absTarget = $pwdPrefix + $target
    Write-Output '@注意,Target必须使用绝对路径!'
    Write-Output "@当然,也可以是这样的表达式:`"`$pwd\\file`""
    Write-Output '@带上-target 选项'
    if (Test-Path $Path)
    {
        rmFV $Path
    }
    New-Item -ItemType HardLink -Path $Path -Target $absTarget -Force -Verbose
}
  • 经过初步测试,该函数能够兼容Target 参数为相对路径以及完整路径的情况

powershell获取文件绝对路径

  • 两种方式:
    • $absTarget = (Get-ChildItem $pattern).FullName
    • rvpa $path

linux shell 创建硬链接

  • man ln|nl|less查看命令ln命令详情

  • target是指,需要被创建链接的文件/目录名(变量)

    • 在带...的用法中,可以同时指定多个target源(譬如用法3/4)
    • 用法三可以同时在一个目录中创建多个链接
  • NAME
           ln - make links between files
    
    SYNOPSIS
           ln [OPTION]... [-T] TARGET LINK_NAME
           ln [OPTION]... TARGET
           ln [OPTION]... TARGET... DIRECTORY
           ln [OPTION]... -t DIRECTORY TARGET...
    
    DESCRIPTION
           In  the  1st  form,  create a link to TARGET with the name LINK_NAME.  In the 2nd
           form, create a link to TARGET in the current  directory.   In  the  3rd  and  4th
           forms,  create  links to each TARGET in DIRECTORY.  Create hard links by default,
           symbolic links with --symbolic.  By default, each destination (name of new  link)
           should  not  already  exist.   When  creating hard links, each TARGET must exist.
           Symbolic links can hold arbitrary text; if later resolved, a relative link is in‐
           terpreted in relation to its parent directory.
    
           Mandatory arguments to long options are mandatory for short options too.
    
           --backup[=CONTROL]
                  make a backup of each existing destination file
    
           -b     like --backup but does not accept an argument
    
           -d, -F, --directory
                  allow the superuser to attempt to hard link directories (note: will proba‐
                  bly fail due to system restrictions, even for the superuser)
    
           -f, --force
                  remove existing destination files
          ....
    
    

例1
  • 创建指向python3.10(二进制文件)的符号链接symbolic link
# cxxu_kali @ CxxuWin11 in ~/dirToSymlinks [15:50:38] C:1
$ ln -s  /usr/bin/python3.10 py3

# cxxu_kali @ CxxuWin11 in ~/dirToSymlinks [15:51:01]
$ ll
total 0
lrwxrwxrwx 1 cxxu_kali cxxu_kali 19 Apr  5 15:51 py3 -> /usr/bin/python3.10
例2
  • 利用符号链接给文件多加一个名字
# cxxu_kali @ CxxuWin11 in ~ [15:55:01] C:130
$ ln  numbers num -s

检查链接🎈

ls -l

该选项可以检查某个目录下的symbolic link
链接会以箭头指示

# cxxu @ cxxuAli in /usr/bin [15:34:47] C:130
$ ls -1l python*
lrwxrwxrwx 1 root root       9 Apr 16  2018 python -> python2.7
lrwxrwxrwx 1 root root       9 Apr 16  2018 python2 -> python2.7
-rwxr-xr-x 1 root root 3633000 Feb 27  2021 python2.7
lrwxrwxrwx 1 root root       9 Feb  8 14:51 python3 -> python3.6
-rwxr-xr-x 2 root root 4526456 Dec  9 05:08 python3.6
lrwxrwxrwx 1 root root      33 Dec  9 05:08 python3.6-config -> x86_64-linux-gnu-python3.6-config
-rwxr-xr-x 2 root root 4526456 Dec  9 05:08 python3.6m
lrwxrwxrwx 1 root root      34 Dec  9 05:08 python3.6m-config -> x86_64-linux-gnu-python3.6m-config
lrwxrwxrwx 1 root root      16 Oct 25  2018 python3-config -> python3.6-config
lrwxrwxrwx 1 root root      10 Feb  8 14:51 python3m -> python3.6m
lrwxrwxrwx 1 root root      17 Oct 25  2018 python3m-config -> python3.6m-config

file 命令

  • 该命令可能需要手动安装
  • 可以识别出symbolic link以及链接的target.
# cxxu @ cxxuAli in /usr/bin [15:37:52]
$ file python3
python3: symbolic link to python3.6

linux:硬连接和软连接的对比

ref

  • <<操作系统概念>>

  • <<计算机操作系统(汤)>>

  • 符号链接不具有被链接的文件的inode(index number)信息

  • 符号链接仅仅包含被链接文件的路径名

  • 被链接的文件名(指针)被删除后,该符号链接就无法正确引用文件(尽管,文件本体可以被文件的其他指针(硬连接)找到(换句话说,尽管文件的引用计数count值哪怕不是0,符号链接都不能够确保能够正确引用文件

下面的实验中,注意ls -li第3个字段,每当一个inode(index number)增加一个硬连接,数字就会加1;删除,则数字减一;

  • 而符号链接和文件的inode (index number)关系就比较松散,遂,发生了符号链接所指的文件名已经被删除了,但是符号链接依然还是指着那个不再存在的文件名(尽管文件名对应的文件还存在着(任然可以通过文件的另一个名字file2来访问)
#( 05/24/22@ 2:31PM )( cxxu@cxxuAli ):~/testLink
   ec 'abc'>file1
#( 05/24/22@ 2:31PM )( cxxu@cxxuAli ):~/testLink
   ls -li
total 4
1835411 -rw-rw-r-- 1 cxxu cxxu 4 May 24 14:31 file1
#( 05/24/22@ 2:31PM )( cxxu@cxxuAli ):~/testLink
   ln file1 file2_hard
#( 05/24/22@ 2:32PM )( cxxu@cxxuAli ):~/testLink
   ls -li
total 8
1835411 -rw-rw-r-- 2 cxxu cxxu 4 May 24 14:31 file1
1835411 -rw-rw-r-- 2 cxxu cxxu 4 May 24 14:31 file2_hard
#( 05/24/22@ 2:32PM )( cxxu@cxxuAli ):~/testLink
   ln -s file1 file3_symbolic
#( 05/24/22@ 2:32PM )( cxxu@cxxuAli ):~/testLink
   ls -li
total 8
1835411 -rw-rw-r-- 2 cxxu cxxu 4 May 24 14:31 file1
1835411 -rw-rw-r-- 2 cxxu cxxu 4 May 24 14:31 file2_hard
1835412 lrwxrwxrwx 1 root root 5 May 24 14:32 file3_symbolic -> file1
#( 05/24/22@ 2:32PM )( cxxu@cxxuAli ):~/testLink
   rm file1
#( 05/24/22@ 2:32PM )( cxxu@cxxuAli ):~/testLink
   ls -li
total 4
1835411 -rw-rw-r-- 1 cxxu cxxu 4 May 24 14:31 file2_hard
1835412 lrwxrwxrwx 1 root root 5 May 24 14:32 file3_symbolic -> file1
#( 05/24/22@ 2:32PM )( cxxu@cxxuAli ):~/testLink
   bat file2_hard
───────┬───────────────────────────────────────────────────────────────────────────────────
       │ File: file2_hard
       │ Size: 4 B
───────┼───────────────────────────────────────────────────────────────────────────────────
   1   │ abc
───────┴───────────────────────────────────────────────────────────────────────────────────
#( 05/24/22@ 2:32PM )( cxxu@cxxuAli ):~/testLink
   bat file3_symbolic
[bat error]: 'file3_symbolic': No such file or directory (os error 2)

ls -li

#( 05/24/22@ 2:38PM )( cxxu@cxxuAli ):~/testLink
   manly ls -l -i

ls - list directory contents
============================

      -i, --inode
              print the index number of each file

      -l     use a long listing format

ls -l

ls -l file1 
-rw-rw-r--. 1 lilo lilo 0 Feb 26 07:08 file1

From the output above we can deduct a following information:

  • -rw-rw-r- permissions
  • 1 : number of linked hard-links
  • lilo: owner of the file
  • lilo: to which group this file belongs to
  • 0: size
  • Feb 26 07:08 modification/creation date and time
  • file1: file/directory name

辨识符号链接🎈

  • 符号链接,千好万好,就是太过于逼真(尽管在图标上可以看出和普通目录的区别,但是在原管理器中(路径属性)的显示中,并不容易看出符号链接到底指向哪里

  • /d选项创建的符号可以通过右键看到target属性(即它指向的目录)

  • /j选项创建的符符号难以通过右键来识别其绑定的目录
    好在,我们可以使用cmd(而不是powershell)的dir命令来查看这些符号(指针)所指向的目录

cmd下dir命令查看

  • 两种方式执行dir

    • 在cmd下直接执行dir
      • 对于powershell用户,可以在powershell中输入cmd即可切换到cmd,然后执行dir
    • 在powershell下直接执行cmd /c dir
    PS C:\Users\cxxu\AppData\Local> cmd /c dir
     Volume in drive C is win11
     Volume Serial Number is EC48-2060
    
     Directory of C:\Users\cxxu\AppData\Local
    
    2023/05/24  15:12    <DIR>          .
    2023/03/05  13:59    <DIR>          0install.net
    ...
    2023/05/24  15:12    <JUNCTION>     Android [\??\D:\Android]
    ...
    2023/04/07  18:15    <DIR>          cache
    2023/01/20  11:35    <DIR>          calibre-cache
    ..
    2023/05/24  20:37    <SYMLINKD>     android_test [D:\android]
    ...
    
    • 可以看到,junction类型和symbol的类型链接被显示出来.

powershell来查看符号连接的类型与其target

  • ls | Format-Table name,LinkType,Target

  • 简写为ls | ft name,LinkType,Target

  • PS C:\Users\cxxu> ls |where {$_.LinkType}|ft name,LinkType,LinkTarget
    
    Name         LinkType     LinkTarget
    ----         --------     ----------
    android_test SymbolicLink D:\android
    downloads    Junction     D:\usersByCxxu\DownloadsAll\
    ser          Junction     D:\repos\ccser\emotion-recognition-using-speech\
    
  • 包装为函数:

    • function get_links_of_type{
          <# 
          .SYNOPSIS
          查看指定类型的链接,以表格的形式输出(包括:name,linktype,linktarget)
          可用的类型包括:hardlink,symboliclink,junction
          默认不区分大小写.
           #>
          param(
              $linkType=''
          )
          Get-ChildItem $dir| Where-Object { $_.LinkType -eq $linkType} | Format-Table name, LinkType, LinkTarget
      }
      
      function get_links_in_dir
      {
          <# 
          .SYNOPSIS
          如果没有指定类型,则查看所有的链接
          否则仅查看指定连接类型的来连接
          #>
          param(
              $dir='.',
              $linkType=''
          )
          if ($linkType -eq ''){
      
              Get-ChildItem $dir| Where-Object { $_.LinkType } | Format-Table name, LinkType, LinkTarget
          }
          # elif($linkType -eq 'Junction'):
          else{
              get_links_of_type -linkType $linkType
          }
          
      }
      
      
  • 如果您了解powershell的一些基本技巧,那么可以对他进行个性化的排序等高级操作

  • 譬如:我希望优先看到符号连接相关项目(符号连接绑定的地址在名字的箭头后方(当然,您可以配合前面字段投影技巧)来更加自定义显示效果

  • PS C:\Users\cxxu> ls|sort -Property Target -Descending
    
            Directory: C:\Users\cxxu
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    l----        2022/12/28     20:38                  downloads  D:\usersByCxxu\DownloadsAll\
    l----         2023/3/27     16:09                  ser  D:\repos\ccser\emotion-recognition-using-speech\
    l----         2023/5/24     20:37                  android_test  D:\android
    d----         2023/5/24     14:28                  .android
    ....
    
    
  • 过滤掉(不显示)非链接类型

    • Get-ChildItem | Sort-Object -Property target -Descending | Select-Object name, linktype, target|where {$_.Target }

    • PS C:\Users\cxxu> Get-ChildItem | Sort-Object -Property target -Descending | Select-Object name, linktype, target|where {$_.Target }
      
      Name         LinkType     Target
      ----         --------     ------
      downloads    Junction     D:\usersByCxxu\DownloadsAll\
      ser          Junction     D:\repos\ccser\emotion-recognition-using-speech\
      android_test SymbolicLink D:\android
      
  • 带统计的版本:

    • function get_links_count {
          param (
          )
          $step = Get-ChildItem | Sort-Object -Property target  | Select-Object name, linktype, target|where {$_.Target }
          Write-Output $step "-------------"
      
          Write-Output "itemsCount: $($step.count)"
      
      }
      
    • 查询当前目录中存在的符号连接以及对应的类型:

      • PS C:\Users\c	xxu> get_links_count
        
        Name         LinkType     Target
        ----         --------     ------
        android_test SymbolicLink D:\android
        ser          Junction     D:\repos\ccser\emotion-recognition-using-speech\
        downloads    Junction     D:\usersByCxxu\DownloadsAll\
        -------------
        itemsCount: 3
        

FAQ

使用限制

  • windows符号链接执行绑定目标(target)地址的时候是硬编码,而且将环境变量转换为就对路径
  • 主要是对于多用户(多系统用户)比较受影响
  • 对于非用户目录,影响就要小一些.

重设符号链接的target

我只知道一个变通的方法(不是原生方法)

  • 将原符号链接重命名
  • 现在可以以原名设定符号链接
    • 利用`rename-item` 重名名
      
  • 删除旧的被重命名的链接
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值