在符号链接目标中使用 ~ 或使用变量创建符号链接

在符号链接目标中使用 ~ 或使用变量创建符号链接

我想创建一个符号链接,~/foo/但当我编写时,~它总是解析为绝对主路径。我../过去用过s ,它们工作得很好,是~不允许的吗?

我想这样做的原因是因为~根据机器和 Linux/OSX 有不同的绝对路径,但总是指向我的主目录。

我想在多台机器上同步的 git 存储库中包含这样的链接。

答案1

波浪号字符由 shell 扩展命令被执行。它将被 的值替换$HOME。因此,ln创建符号链接的实用程序永远不会看到波浪号,只能看到完整路径。该路径将存储在符号链接中。


Linux,没有办法创建符号链接变量。它们由内核处理。内核不支持环境变量。


BSD允许此类链接。他们叫变体符号链接。你可以这样做:

$ ln -s ’${variable}’ linkname
$ ls -l linkname
lrwxrwxrwx 1 root root 6 Sep 29 12:33 linkname -> ’${variable}’

varsym然后可以设置这些变量:

varsym variable=value cat linkname
[...] contents of file with name value [...]

答案2

为了解决有关符号链接的问题,“不允许吗?”。

答:~是不允许的。它将允许您创建这样的符号链接,但在执行时它不会解析到主目录。

ln -s \~ d
ls -ld d
lrwxrwxrwx 1 steve steve 1 Sep 29 11:28 d -> ~
ls d
d
cd d
cd: d: No such file or directory

答案3

根据您对环境的控制程度,可以配置一个行为方式与您想要的类似的命名空间。这是执行此操作的脚本:

#!/bin/bash

if [ "$(id -u)" -ne "0" ]; then
    FAKEROOT=$(mktemp -d --tmpdir "fakeroot.XXXXXXXXXX")
    unshare -Urm "$0" "${FAKEROOT}"
    rm -rf "${FAKEROOT}"
    exit 0
fi

FAKEROOT="$1"
mkdir -p "${FAKEROOT}/old_root"
for FILE in $(ls /); do ln -s "/${FILE}" "${FAKEROOT}/old_root/${FILE}"; done
for FILE in $(ls /); do ln -s "old_root/${FILE}" "${FAKEROOT}/${FILE}"; done
mount --bind "${FAKEROOT}" "${FAKEROOT}"
pivot_root "${FAKEROOT}" "${FAKEROOT}/old_root"
/bin/bash --init-file <(echo '. ~/.bashrc; symvar() { VAR=$(echo "$1" | sed "s/=.*//"); TGT=$(echo "$1" | sed "s/[^=]*=//"); ln -sf "${TGT}" "/\${${VAR}}"; }')

此时,您可以使用 BSD 语法定义符号链接变量:

symvar HOME=/home/your-username

您可以创建如下所示的符号链接:

ln -s '/${HOME}/Desktop' 'Desktop Folder'

如果将此解决方案与“恢复" 解决方案代码* 那么您可以在默认脚本中包含类似的内容:

symvar HOME="${HOME}"

示例(替换脚本中的最后一行):

revertuid /bin/bash --init-file <(echo '. ~/.bashrc; symvar() { VAR=$(echo "$1" | sed "s/=.*//"); TGT=$(echo "$1" | sed "s/[^=]*=//"); ln -sf "${TGT}" "/\${${VAR}}"; }; symvar HOME="${HOME}";')
  • 注意:如果您的任何用户 ID 不是 1000,那么您将需要调整 revertuid 示例代码。您需要做的就是将 UID 传递给下标并将其作为第一个参数传递给 revertuid。

答案4

我通过在项目中放置引用项目根目录中符号链接的相对符号链接解决了这个问题。在项目根目录中,我创建了一个symlinkToHomeDir.README文件,表示运行以下命令:

ln -s ~ ./symlinkToHomeDir

您可以创建该符号链接作为项目初始化脚本的一部分。

根级别符号链接位于我的.gitignore文件中,因此不会将其复制到其他用户的目录。

相关内容