scp 的 Bash 脚本解释波形符 (~) 太快了

scp 的 Bash 脚本解释波形符 (~) 太快了

所以,我刚刚开始了一门新的 C++ 课程,它要求我在 Linux 环境中编程。我的机器上没有安装 Linux,但我有 OS X,并且我可以 ssh 到学校实验室中的 Linux 机器(这是更好的选择,因为我的代码必须在实验室机器上编译和运行,无论是否不适用于我的机器)。如果你在这个问题结束时还不能判断出来,那么我对 Linux 还不太熟悉。

我经常需要将下载到本地计算机上的文件放在远程计算机上,编辑它们以制作程序,然后将它们放回本地计算机上以将它们上传到我们的保管箱。我厌倦了打字 ,决定创建一个别名来执行此操作。就在那时我发现别名不能处理这种事情,所以我决定编写一个 shell 脚本来代替。这是我所得到的:
scp -P xx [email protected]:~/filename filename

#!/bin/bash

# Author: me
# Created 26 August 2014
# transfers a file from remote machine to current directory in local machine
# keeps same filename

location="$1"
# name gets just the part of the path after the last slash
# ie the filename
name="$(echo "$1" | sed -n -e 's/^.*\///p')"
# echo "$location"
# echo "$name"
scp -P xx [email protected]:"$location" "$name"

理论上,我只需键入get ~/path/to/filename,它就会从远程主机获取文件并将其复制(具有相同的文件名)到本地计算机上的当前目录中。

如果从命令行运行该 scp 命令,效果会很好。当我将它粘贴到 shell 脚本中时,它就崩溃了。它给了我错误:No such file or directory

经过大量测试(您可以在上面看到一些注释掉的调试输出)和研究,我发现 shell 正在扩展~ 它将它发送到脚本(好吧,这是我根据我对 glob 的了解进行的猜测)。然后我的脚本在我的路径中查找该文件当地的机器的主文件夹而不是偏僻的机器的主文件夹。我怎样才能让它停止这样做?

我意识到在输入这个问题时,我在运行命令时可能只需要一些引号......但我真的不想这样做。我可以以某种方式解决这个问题而不必输入,get "~/filename"因为必须输入这些引号真的很烦人。

抱歉,如果有很多无关的信息,但我认为太多总比太少好。谢谢!

PS:我已经找到了关于配置 ssh。虽然很有用,但我仍然需要输入两次确切的文件名,这不允许我像我想要的那样懒惰。

答案1

默认情况下,远程路径是相对于主目录解释的,因此您根本scp不需要:~

scp [email protected]:some/file/name filename

some/file/name将从主目录下载user并将其保存为filename本地。当您想在远程服务器上使用绝对文件路径时,请以/:开头scp host:/etc/passwd passwd

严格来说,您的服务器可能会以不同的方式解释事物。在这种情况下,您可以将其放入~脚本中,而不是每次都在命令行上重复它(想偷懒就偷懒!):

scp [email protected]:~/"$location" "$name"

这样你的 shell 就永远没有机会解释它。 (也可以~在命令行上引用:\~'~',但这比必要的工作更多。)不过,我想上面的第一种方法会起作用。


关于变量的另一个注释name。您说您希望它只是基本文件名。有一个命令专门用于此目的,即basename命令:

name="$(basename "$location")"

这比运行所有内容要简单sed

相关内容