如何使用波浪号作为我的主目录的快捷方式?

j0h*_*j0h 31 ssh bash scp

我很困惑,试图将一些文件从一台 PC 复制到另一台。我已经弄清楚了,但语法仍然让我感到困惑。这有效:

scp ~/Desktop/Volenteer.png jay@server.ip:~j0h/b
Run Code Online (Sandbox Code Playgroud)

放在Volenteer.png文件夹中/home/j0h/b。但是,这不起作用:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b
Run Code Online (Sandbox Code Playgroud)

这也失败,给出退出状态 1 找不到文件:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b
Run Code Online (Sandbox Code Playgroud)

就像这样:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b
Run Code Online (Sandbox Code Playgroud)

很明显,~和之间有一些区别~/ 区别在于存在/

$~/
bash: /home/j0h/: Is a directory
$ ~
bash: /home/j0h: Is a directory
Run Code Online (Sandbox Code Playgroud)

那么为什么在 scp 中,~解析为~/?这是一个猜测,我无法验证这就是正在发生的事情。但它似乎不一致,因此令人困惑。这是scp中的错误吗?或者有什么关于波浪号的东西我失踪了?

mur*_*uru 71

~ 是您的主目录。

~foo是 user 的主目录foo,如果这样的用户存在,或者只是一个名为 的目录~foo,如果该用户不存在。


因此,在:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b
Run Code Online (Sandbox Code Playgroud)

~Desktop将扩展到 user 的主目录Desktop,如果这样的用户存在(通常不存在),或者只是~Desktop(通常也不存在的路径)。


在:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b
Run Code Online (Sandbox Code Playgroud)

~/j0h将扩大到一个指定的目录j0hjay的主目录,这又是不可能存在的。


它不是~~/发生差异的地方,而是在~和 中~foo


此外,~还可用于目录历史导航:

  • ~-是以前的工作目录(如$OLDPWD
  • ~+是当前工作目录(如$PWD

这不适用于scp,因为您无法在scp操作过程中更改目录。

如果您使用pushdpopd来维护目录堆栈,并且将是目录堆栈中的第 th 个目录,如. 将是最后的第 th 目录(在这两种情况下都从零开始计数)。例如:~N~+NNdirs~-NN

$ for i in etc usr var tmp; do pushd /$i; done
/etc ~/.vim
/usr /etc ~/.vim
/var /usr /etc ~/.vim
/tmp /var /usr /etc ~/.vim

$ dirs
/tmp /var /usr /etc ~/.vim
Run Code Online (Sandbox Code Playgroud)

然后,可以使用以下方法访问堆栈中的目录:

/tmp /var /usr /etc ~/.vim
  ~0   ~1   ~2   ~3     ~4
 ~+0  ~+1  ~+2  ~+3    ~+4
 ~-4  ~-3  ~-2  ~-1    ~-0 
  ~+   ~-
Run Code Online (Sandbox Code Playgroud)

  • @Wildcard 好吧,不完全是。`~+` 和`~-` 使用`$PWD` 和`$OLDPWD` 的值,它们是绝对路径。`.` 始终是相对路径。因此,如果有一个命令在执行时更改了当前工作目录,它将看到`.` 的新路径,其中由`~-` 扩展的路径将保持不变。`tar -C` 就是一个例子,不过我承认我想不出 `~+` 有什么用处。`$PWD` 也一样好,除非你不需要引用 `~+/foo/bar` 如果 `$PWD` 包含空格。 (2认同)
  • 谢谢,这就澄清了。实际上,这是一个很好的用例示例:出于安全原因,某些命令拒绝在相对路径上进行操作;对于这样的命令,你不能使用`./filename`,但可以使用`"$PWD/filename"` 或更简单的`~+/filename`。(有些命令可以*工作*相对路径名,但功能上存在差异,例如`ln`或`tar`。) (2认同)

Oli*_*Oli 22

通读Bash Tilde ExpansionGNU 文档(正如我在第一次迭代此答案之前应该阅读的那样)。

~/Desktop并且~j0h正在做根本不同的事情,这解释了为什么~Desktop不起作用:

  • 一个普通的~被替换为您当前的$HOME环境变量,在登录时设置。所以~决定/home/oli为我,并~/Desktop阅读为/home/oli/Desktop。这是您看到最多使用 tilda 的地方。

  • ~username解析为该用户的家,如/etc/passwd. 所以~oli解析为/home/oli~j0h可能解析为/home/j0h但不一定,您的 homedir 可以在任何地方。

  • ~not-a-username不解决。因为Desktop不是用户,~Desktop不被替换。它从字面上理解为命名的文件或路径~Desktop(此处不存在)。

不用说,这一切都是远程发生的(scp如果用本地值替换它就没有用了)。这是有效的,因为~...如果Bash前面没有空格,则不会替换它。

  • “bin”是大多数 Linux 机器上的系统用户,其主目录为 /bin。 (2认同)