I was confused, trying to copy some files from one PC to another. I have it figured out, but the syntax is still confusing to me. This works:
scp ~/Desktop/Volenteer.png [email protected]:~j0h/b
which puts Volenteer.png
in the folder /home/j0h/b
. However, this doesn't work:
scp ~Desktop/Volenteer.png [email protected]:~j0h/b
This also fails, giving an exit status 1 file not found:
scp ~/Desktop/Volenteer.png [email protected]:~/j0h/b
As does this:
scp ~Desktop/Volenteer.png [email protected]:~j0h/b
So clearly, there is some difference between ~
and ~/
That difference is the presence of /
$~/
bash: /home/j0h/: Is a directory
$ ~
bash: /home/j0h: Is a directory
So why in scp, does the ~
resolve to ~/
?
That is a guess, I cant verify that's what is happening.
But it seems inconsistent, and therefore confusing.
Is this a bug in scp? or is there something about tilde I am missing?
~
is your home directory.~foo
is the home directory of userfoo
, if such a user exists, or just a directory named~foo
, if that user doesn't exist.Hence, in:
~Desktop
will expand to home directory of userDesktop
, if such a user exists (and it usually does not), or be just~Desktop
(a path which usually does not exist either).In:
~/j0h
will expand to a directory namedj0h
injay
's home directory, which, again, is unlikely to exist.It's not
~
and~/
where the difference occurs, but in~
and~foo
.Additionally,
~
can also be used for directory history navigation:~-
is the previous working directory (like$OLDPWD
)~+
is the current working directory (like$PWD
)This is not applicable to
scp
, since you don't get to change directories in the middle of anscp
operation.And if you use
pushd
andpopd
to maintain a directory stack,~N
and~+N
would be theN
th directory in the directory stack, as seen in the output ofdirs
.~-N
would be theN
th directory from the end (counting from zero, in both cases). For example:Then, the directories in the stack can be accessed using:
Have a read through of the GNU documentation for Bash Tilde Expansion (as I should have before my first iteration of this answer).
~/Desktop
and~j0h
are doing fundamentally different things, which explains why~Desktop
doesn't work:A plain
~
is substituted for your current$HOME
environment variable, set on login. So~
resolves to/home/oli
for me, and~/Desktop
reads as/home/oli/Desktop
. This is where you see the tilda being used most.~username
resolves to the home of that user, as set in/etc/passwd
. So~oli
resolves to/home/oli
,~j0h
might resolve to/home/j0h
but not neccessarily, your homedir can be anywhere.~not-a-username
doesn't resolve. BecauseDesktop
is not a user,~Desktop
isn't substituted. It is taken literally as a file or path named~Desktop
(which doesn't exist here).And needless to say, this is all happening remotely (it'd be useless in
scp
if it were replaced with local values). This works because Bash won't substitute~...
if it's preceded by anything but whitespace.The symbol
~
is used as a shortcut for/home/user
inbash
, so in the case of~/Desktop/Volenteer.png
it is shorthand for/home/user/Desktop/Volenteer.png
.So as you can see the
/
, as always, shows an new level in the file system hierarchy.~
is shorthand for the environment variable$HOME
on most c shell derivative/supporting POSIX compliant shells. the most common use for~
is when referencing your own home directory or that of another user's home:To find the home directory for any local user on a POSIX system (UNIX, Linux, OS X, BSD) that is using the passwd(5) database run awk on
/etc/passwd
like so:This will list each local user and their home directory.