Как использование тильды работает как ярлык для моего домашнего каталога?

Я был в замешательстве, пытаясь скопировать некоторые файлы с одного компьютера на другой. Я понял это, но синтаксис все еще смущает меня. Это работает:

scp ~/Desktop/Volenteer.png jay@server.ip:~j0h/b

который ставит Volenteer.png в папке /home/j0h/b, Тем не менее, это не работает:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Это также дает сбой, давая статус выхода 1 файл не найден:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

Как это сделать:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Так ясно, что есть некоторая разница между ~ а также ~/Эта разница заключается в наличии /

$~/
bash: /home/j0h/: Is a directory
$ ~
bash: /home/j0h: Is a directory

Так почему же в scp ~ решиться на ~/? Это предположение, я не могу проверить, что происходит. Но это кажется противоречивым, а потому и запутанным. Это ошибка в scp? или что-то в тильде мне не хватает?

4 ответа

Решение

~ это ваш домашний каталог.

~foo домашний каталог пользователя foo, если такой пользователь существует, или просто каталог с именем ~foo, если этот пользователь не существует.


Следовательно, в:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

~Desktop развернется в домашний каталог пользователя Desktop, если такой пользователь существует (и обычно не существует), или просто ~Desktop (путь, который обычно не существует).


В:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

~/j0h развернется в каталог с именем j0h в jay домашний каталог, который, опять же, вряд ли существует.


Это не ~ а также ~/ где разница возникает, но в ~ а также ~foo,


Дополнительно, ~ также может использоваться для навигации по истории каталогов:

  • ~- предыдущий рабочий каталог (например, $OLDPWD)
  • ~+ текущий рабочий каталог (например, $PWD)

Это не относится к scp, так как вы не можете изменить каталоги в середине scp операция.

И если вы используете pushd а также popd поддерживать стек каталогов, ~N а также ~+N будет N th каталог в стеке каталогов, как видно из вывода dirs, ~-N будет N каталог с конца (считая с нуля, в обоих случаях). Например:

$ 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

Затем к каталогам в стеке можно получить доступ, используя:

/tmp /var /usr /etc ~/.vim
  ~0   ~1   ~2   ~3     ~4
 ~+0  ~+1  ~+2  ~+3    ~+4
 ~-4  ~-3  ~-2  ~-1    ~-0 
  ~+   ~-

Прочитайте документацию по GNU для Bash Tilde Expansion (как я должен был сделать до моей первой итерации этого ответа).

~/Desktop а также ~j0h делают принципиально разные вещи, что объясняет, почему ~Desktop не работает:

  • Равнина ~ заменяет ваш текущий $HOME переменная окружения, установленная при входе в систему. Так ~ решает в /home/oli for me, and ~/Desktop читается как /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, Так ~oli решает в /home/oli, ~j0h might resolve to /home/j0h but not neccessarily, your homedir can be anywhere.

  • ~not-a-username не разрешается Так как Desktop is not a user, ~Desktop isn't substituted. It is taken literally as a file or path named ~Desktop (which doesn't exist here).

И само собой разумеется, все это происходит удаленно (это было бы бесполезно в scp если бы он был заменен местными значениями). Это работает, потому что Bash не заменит ~... если ему предшествует что-либо, кроме пробелов.

Символ ~ используется в качестве ярлыка для /home/user в bashтак что в случае ~/Desktop/Volenteer.png это сокращение для /home/user/Desktop/Volenteer.png,

Так как вы можете видеть /как всегда, показывает новый уровень в иерархии файловой системы.

~ является сокращением для переменной среды $HOME на большинстве оболочек c производных / поддерживающих POSIX-совместимых оболочек. наиболее распространенное использование для ~ это когда вы ссылаетесь на свой домашний каталог или каталог другого пользователя:

cd ~ # ie shell, take me to my home folder

cd ~root # i.e. shell, take me to root's home folder

Чтобы найти домашний каталог для любого локального пользователя в системе POSIX (UNIX, Linux, OS X, BSD), использующей базу данных passwd(5), запустите awk на /etc/passwd вот так:

awk -F: '{ print $1,$(NF-1) }' /etc/passwd

Это перечислит каждого локального пользователя и его домашний каталог.

Другие вопросы по тегам